From 4393a7d592beb1a7dfdb659b649d7a69115fa356 Mon Sep 17 00:00:00 2001 From: Tanguy Herbron Date: Sat, 14 Apr 2018 01:18:49 +0200 Subject: [PATCH] Update HomeActivity with fragments - Fragments for WatchList, Currency list and Market cap - WatchList implementation --- .../Activities/CurrencySelectionActivity.java | 29 +- .../coinfolio/Activities/HomeActivity.java | 813 +----------------- .../MarketCapitalization.java | 232 +++++ .../HomeActivityFragments/Summary.java | 660 ++++++++++++++ .../HomeActivityFragments/Watchlist.java | 230 +++++ .../Activities/RecordTransactionActivity.java | 1 + .../DataManagers/BalanceManager.java | 2 +- .../DataManagers/CurrencyData/Currency.java | 24 + .../DataManagers/DatabaseManager.java | 46 +- .../ExchangeManager/BinanceManager.java | 2 + .../DataManagers/WatchlistManager.java | 37 + .../java/com/nauk/coinfolio/PagerAdapter.java | 47 + .../res/layout/activity_currency_summary.xml | 15 +- .../fragment_marketcap_homeactivity.xml | 61 ++ .../layout/fragment_summary_homeactivity.xml | 49 ++ .../fragment_watchlist_homeactivity.xml | 56 ++ 16 files changed, 1519 insertions(+), 785 deletions(-) create mode 100644 app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/MarketCapitalization.java create mode 100644 app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Summary.java create mode 100644 app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Watchlist.java create mode 100644 app/src/main/java/com/nauk/coinfolio/DataManagers/WatchlistManager.java create mode 100644 app/src/main/java/com/nauk/coinfolio/PagerAdapter.java create mode 100644 app/src/main/res/layout/fragment_marketcap_homeactivity.xml create mode 100644 app/src/main/res/layout/fragment_summary_homeactivity.xml create mode 100644 app/src/main/res/layout/fragment_watchlist_homeactivity.xml diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/CurrencySelectionActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/CurrencySelectionActivity.java index 45d64be..ddacfd5 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/CurrencySelectionActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/CurrencySelectionActivity.java @@ -21,6 +21,8 @@ import android.widget.SearchView; import com.nauk.coinfolio.DataManagers.BalanceManager; import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; import com.nauk.coinfolio.DataManagers.CurrencyData.CurrencyDetailsList; +import com.nauk.coinfolio.DataManagers.DatabaseManager; +import com.nauk.coinfolio.DataManagers.PreferencesManager; import com.nauk.coinfolio.LayoutManagers.CurrencyListAdapter; import com.nauk.coinfolio.R; @@ -33,6 +35,7 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear private ListView listView; private android.widget.Filter filter; private CurrencyDetailsList currencyDetailsList; + private boolean isWatchList; @Override protected void onCreate(Bundle savedInstanceState) { @@ -47,10 +50,11 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear setTitle("Select a coin"); + Intent intent = getIntent(); + isWatchList = intent.getBooleanExtra("isWatchList", false); + ListLoader listLoader = new ListLoader(); listLoader.execute(); - - Log.d("coinfolio", "Started"); } private void setupSearchView() @@ -89,10 +93,23 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { Currency selectedCurrency = (Currency) adapterView.getItemAtPosition(i); - Intent intent = new Intent(CurrencySelectionActivity.this, RecordTransactionActivity.class); - intent.putExtra("coin", selectedCurrency.getName()); - intent.putExtra("symbol", selectedCurrency.getSymbol()); - startActivity(intent); + + if(isWatchList) + { + PreferencesManager preferencesManager = new PreferencesManager(getApplicationContext()); + DatabaseManager databaseManager = new DatabaseManager(getApplicationContext()); + + databaseManager.addCurrencyToWatchlist(selectedCurrency); + preferencesManager.setMustUpdate(true); + } + else + { + Intent intent = new Intent(CurrencySelectionActivity.this, RecordTransactionActivity.class); + intent.putExtra("coin", selectedCurrency.getName()); + intent.putExtra("symbol", selectedCurrency.getSymbol()); + startActivity(intent); + } + finish(); } }); diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java index a85a5fd..ae26f82 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java @@ -15,6 +15,7 @@ import android.support.design.widget.AppBarLayout; import android.support.design.widget.BottomNavigationView; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.Snackbar; +import android.support.v4.view.ViewPager; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.graphics.Palette; @@ -28,6 +29,7 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.Button; import android.widget.ImageButton; import android.widget.LinearLayout; @@ -45,6 +47,7 @@ import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; import com.nauk.coinfolio.DataManagers.MarketCapManager; import com.nauk.coinfolio.DataManagers.PreferencesManager; import com.nauk.coinfolio.LayoutManagers.HomeLayoutGenerator; +import com.nauk.coinfolio.PagerAdapter; import com.nauk.coinfolio.R; import java.io.IOException; @@ -72,30 +75,14 @@ import java.util.Locale; public class HomeActivity extends AppCompatActivity { private PreferencesManager preferencesManager; - private BalanceManager balanceManager; - private MarketCapManager marketCapManager; - - private int coinCounter; - private int iconCounter; - private int marketCapCounter; - private long lastTimestamp; - private boolean detailsChecker; - private boolean isDetailed; - protected float totalValue; - protected float totalFluctuation; private CollapsingToolbarLayout toolbarLayout; - private SwipeRefreshLayout refreshLayout; - private LinearLayout currencyLayout; - private TextView toolbarSubtitle; - private Dialog loadingDialog; - private Handler handler; - private Runnable updateRunnable; private ViewFlipper viewFlipper; private HomeLayoutGenerator layoutGenerator; private BottomNavigationView bottomNavigationView; - private HashMap dominantCurrenciesColors; + private ViewPager viewPager; + private BottomNavigationView.OnNavigationItemSelectedListener onNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @@ -106,13 +93,13 @@ public class HomeActivity extends AppCompatActivity { switch (item.getItemId()) { case R.id.navigation_watchlist: - switchSecondaryViews(0); + viewPager.setCurrentItem(0); break; case R.id.navigation_currencies_list: - switchMainView(); + viewPager.setCurrentItem(1); break; case R.id.navigation_market_cap: - switchSecondaryViews(2); + viewPager.setCurrentItem(2); break; } return false; @@ -134,65 +121,40 @@ public class HomeActivity extends AppCompatActivity { setContentView(R.layout.activity_currency_summary); setSupportActionBar((Toolbar) findViewById(R.id.toolbar)); - generateSplashScreen(); + viewPager = findViewById(R.id.viewPager); + final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), 3); + + viewPager.setAdapter(adapter); + viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + bottomNavigationView.getMenu().getItem(position).setChecked(true); + } + + @Override + public void onPageSelected(int position) { + + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); //Objects initialization preferencesManager = new PreferencesManager(this); - balanceManager = new BalanceManager(this); - marketCapManager = new MarketCapManager(this); - handler = new Handler(); - updateRunnable = new Runnable() { - @Override - public void run() { - if (refreshLayout.isRefreshing()) - { - refreshLayout.setRefreshing(false); - - showErrorSnackbar(); - } - - if (loadingDialog.isShowing()) - { - loadingDialog.dismiss(); - - showErrorSnackbar(); - } - } - }; - - isDetailed = preferencesManager.getDetailOption(); //Layouts setup - refreshLayout = findViewById(R.id.swiperefresh); toolbarLayout = findViewById(R.id.toolbar_layout); - toolbarSubtitle = findViewById(R.id.toolbarSubtitle); - currencyLayout = findViewById(R.id.currencyListLayout); viewFlipper = findViewById(R.id.viewFlipperSummary); bottomNavigationView = findViewById(R.id.navigationSummary); bottomNavigationView.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener); bottomNavigationView.setSelectedItemId(R.id.navigation_currencies_list); - - layoutGenerator = new HomeLayoutGenerator(this); - - Button addCurrencyButton = findViewById(R.id.buttonAddTransaction); - ImageButton detailsButton = findViewById(R.id.switch_button); - ImageButton settingsButton = findViewById(R.id.settings_button); - toolbarLayout.setForegroundGravity(Gravity.CENTER); - totalValue = 0; - totalFluctuation = 0; - - updateTitle(); - - //Events setup - detailsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - switchView(); - } - }); + ImageButton settingsButton = findViewById(R.id.settings_button); settingsButton.setBackground(this.getResources().getDrawable(R.drawable.ic_settings_black_24dp)); settingsButton.setOnClickListener(new View.OnClickListener() { @@ -204,115 +166,29 @@ public class HomeActivity extends AppCompatActivity { } }); - refreshLayout.setOnRefreshListener( - new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - switch (viewFlipper.getDisplayedChild()) - { - case 0: - Log.d(getResources().getString(R.string.debug), "Watchlist"); - refreshLayout.setRefreshing(false); - break; - case 1: - updateAll(false); - break; - case 2: - Log.d(getResources().getString(R.string.debug), "Market cap"); - refreshLayout.setRefreshing(false); - break; - } - - } - } - ); - - addCurrencyButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent addIntent = new Intent(HomeActivity.this, CurrencySelectionActivity.class); - - startActivity(addIntent); - } - }); - updateViewButtonIcon(); - lastTimestamp = 0; - - setupDominantCurrenciesColors(); } - protected void updateTitle() + private void updateViewButtonIcon() { - float totalFluctuationPercentage = totalFluctuation / (totalValue - totalFluctuation) * 100; + ImageButton imgButton = findViewById(R.id.switch_button); - if(preferencesManager.isBalanceHidden()) + imgButton.setBackgroundColor(this.getResources().getColor(R.color.buttonColor)); + + if(preferencesManager.getDetailOption()) { - toolbarLayout.setTitle(getResources().getString(R.string.currencyPercentagePlaceholder, String.format("%.2f", totalFluctuationPercentage))); - toolbarSubtitle.setVisibility(View.GONE); - - if(totalFluctuation > 0) - { - toolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.increase)); - toolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.increase)); - } - else - { - toolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.decrease)); - toolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.decrease)); - } + imgButton.setBackground(this.getResources().getDrawable(R.drawable.ic_unfold_less_black_24dp)); + preferencesManager.setDetailOption(true); } else { - toolbarLayout.setTitle(getResources().getString(R.string.currencyDollarPlaceholder, String.format("%.2f", totalValue))); - toolbarLayout.setCollapsedTitleTextColor(Color.WHITE); - toolbarLayout.setExpandedTitleColor(Color.WHITE); - - toolbarSubtitle.setVisibility(View.VISIBLE); - - if(totalFluctuation > 0) - { - toolbarSubtitle.setTextColor(getResources().getColor(R.color.increase)); - } - else - { - toolbarSubtitle.setTextColor(getResources().getColor(R.color.decrease)); - } - - if(totalFluctuation == 0) - { - toolbarSubtitle.setText(getResources().getString(R.string.currencyDollarPlaceholder, "0.00")); - toolbarSubtitle.setTextColor(-1275068417); - - } - else - { - toolbarSubtitle.setText("US$" + String.format("%.2f", totalFluctuation) + " (" + String.format("%.2f", totalFluctuationPercentage) + "%)"); - } + imgButton.setBackground(this.getResources().getDrawable(R.drawable.ic_details_black_24dp)); + preferencesManager.setDetailOption(false); } } - private void setupDominantCurrenciesColors() - { - dominantCurrenciesColors = new HashMap<>(); - dominantCurrenciesColors.put("BTC", -489456); - dominantCurrenciesColors.put("ETH", -13619152); - dominantCurrenciesColors.put("XRP", -16744256); - dominantCurrenciesColors.put("BCH", -1011696); - dominantCurrenciesColors.put("LTC", -4671304); - dominantCurrenciesColors.put("ADA", -16773080); - dominantCurrenciesColors.put("NEO", -9390048); - dominantCurrenciesColors.put("XLM", -11509656); - dominantCurrenciesColors.put("XMR", -499712); - dominantCurrenciesColors.put("EOS", -1513240); - dominantCurrenciesColors.put("IOT", -1513240); - dominantCurrenciesColors.put("DASH", -15175496); - dominantCurrenciesColors.put("XEM", -7829368); - dominantCurrenciesColors.put("TRX", -7829360); - dominantCurrenciesColors.put("ETC", -10448784); - } private void switchMainView() { @@ -356,50 +232,10 @@ public class HomeActivity extends AppCompatActivity { viewFlipper.setDisplayedChild(itemIndex); } - private void showErrorSnackbar() - { - Snackbar.make(findViewById(R.id.viewFlipperSummary), "Error while updating data", Snackbar.LENGTH_LONG) - .setAction("Update", new View.OnClickListener() { - @Override - public void onClick(View view) { - updateAll(true); - } - }) - .show(); - } - @Override protected void onResume() { super.onResume(); - //addTestWatchlistCardview(); - displayBalance(preferencesManager.isBalanceHidden()); - - updateAll(preferencesManager.mustUpdate()); - } - - private void displayBalance(boolean hideBalance) - { - updateTitle(); - - if(hideBalance) - { - for(int i = 0; i < currencyLayout.getChildCount(); i++) - { - currencyLayout.getChildAt(i).findViewById(R.id.currencyPortfolioDominance).setVisibility(View.VISIBLE); - currencyLayout.getChildAt(i).findViewById(R.id.percentageOwnedTextView).setVisibility(View.VISIBLE); - currencyLayout.getChildAt(i).findViewById(R.id.currencyOwnedInfoLayout).setVisibility(View.GONE); - } - } - else - { - for(int i = 0; i < currencyLayout.getChildCount(); i++) - { - currencyLayout.getChildAt(i).findViewById(R.id.currencyPortfolioDominance).setVisibility(View.INVISIBLE); - currencyLayout.getChildAt(i).findViewById(R.id.percentageOwnedTextView).setVisibility(View.GONE); - currencyLayout.getChildAt(i).findViewById(R.id.currencyOwnedInfoLayout).setVisibility(View.VISIBLE); - } - } } private void addTestWatchlistCardview() @@ -447,579 +283,6 @@ public class HomeActivity extends AppCompatActivity { return super.onOptionsItemSelected(item); } - private void switchView() - { - if(isDetailed) - { - isDetailed = false; - - adaptView(); - } - else - { - isDetailed = true; - - adaptView(); - } - } - - private void adaptView() - { - currencyLayout.removeAllViews(); - - for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) - { - final Currency currency = balanceManager.getTotalBalance().get(i); - - if(!currency.getSymbol().equals("USD") && ((currency.getBalance() * currency.getValue()) > 0.001 || currency.getHistoryMinutes() == null)) - { - currencyLayout.addView(layoutGenerator.getInfoLayout(currency, isDetailed, totalValue, preferencesManager.isBalanceHidden())); - } - } - - updateViewButtonIcon(); - } - - private void updateAll(boolean mustUpdate) - { - if(System.currentTimeMillis()/1000 - lastTimestamp > 60 || mustUpdate) - { - lastTimestamp = System.currentTimeMillis() / 1000; - balanceManager.updateExchangeKeys(); - refreshLayout.setRefreshing(true); - - resetCounters(); - DataUpdater updater = new DataUpdater(); - updater.execute(); - - handler.postDelayed(updateRunnable, 10000); - } - else - { - if(refreshLayout.isRefreshing()) - { - refreshLayout.setRefreshing(false); - } - } - } - - private void resetCounters() - { - coinCounter = 0; - iconCounter = 0; - detailsChecker = false; - - totalValue = 0; - totalFluctuation = 0; - } - - private void getBitmapFromURL(String src, IconCallBack callBack) { - Bitmap result; - - try { - java.net.URL url = new java.net.URL(src); - HttpURLConnection connection = (HttpURLConnection) url - .openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - result = BitmapFactory.decodeStream(input); - } catch (IOException e) { - e.printStackTrace(); - result = BitmapFactory.decodeResource(this.getResources(), - R.mipmap.icon_coinfolio); - result = Bitmap.createScaledBitmap(result, 50, 50, false); - } - - callBack.onSuccess(result); - } - - private void countIcons() - { - int offset = 0; - - for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) - { - if(balanceManager.getTotalBalance().get(i).getSymbol().equals("USD")) - { - offset++; - } - } - - iconCounter++; - - if(balanceManager.getTotalBalance() != null) - { - if(balanceManager.getTotalBalance().size() == 0) - { - updateNoBalance(); - } - else - { - if(iconCounter == balanceManager.getTotalBalance().size() - offset) - { - Log.d(getResources().getString(R.string.debug), "Loading heavy"); - - UiHeavyLoadCalculator uiHeavyLoadCalculator = new UiHeavyLoadCalculator(); - uiHeavyLoadCalculator.execute(); - } - } - } - } - - private void updateNoBalance() - { - refreshLayout.setRefreshing(false); - - currencyLayout.removeAllViews(); - - if(loadingDialog.isShowing()) - { - loadingDialog.dismiss(); - } - - runOnUiThread(new Runnable() { - @Override - public void run() { - - updateTitle(); - } - }); - } - - private void updateMarketCap() - { - marketCapCounter = 0; - - marketCapManager.updateTopCurrencies(new MarketCapManager.VolleyCallBack() { - @Override - public void onSuccess() - { - countCompletedMarketCapRequest(); - } - }); - - marketCapManager.updateMarketCap(new MarketCapManager.VolleyCallBack() { - @Override - public void onSuccess() { - countCompletedMarketCapRequest(); - } - }); - } - - @SuppressLint("ClickableViewAccessibility") - private void countCompletedMarketCapRequest() - { - marketCapCounter++; - - if(marketCapCounter == 2) - { - setupTextViewMarketCap(); - - findViewById(R.id.progressBarMarketCap).setVisibility(View.GONE); - findViewById(R.id.layoutProgressMarketCap).setVisibility(View.VISIBLE); - - List entries = new ArrayList<>(); - - ArrayList colors = new ArrayList<>(); - - float otherCurrenciesDominance = 0; - - for(Iterator i = marketCapManager.getDominance().keySet().iterator(); i.hasNext(); ) - { - String key = (String) i.next(); - entries.add(new PieEntry(marketCapManager.getDominance().get(key), key)); - otherCurrenciesDominance += marketCapManager.getDominance().get(key); - colors.add(dominantCurrenciesColors.get(key)); - } - entries.add(new PieEntry(100-otherCurrenciesDominance, "Others")); - colors.add(-12369084); - - PieDataSet set = new PieDataSet(entries, "Market Cap Dominance"); - set.setColors(colors); - set.setSliceSpace(1); - set.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE); - set.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE); - PieData data = new PieData(set); - data.setValueTextSize(10); - data.setValueFormatter(new PercentFormatter()); - - setupPieChart(data); - } - } - - private void setupPieChart(PieData data) - { - PieChart pieChart = findViewById(R.id.marketCapPieChart); - - pieChart.setData(data); - pieChart.setDrawSlicesUnderHole(false); - pieChart.setUsePercentValues(true); - pieChart.setTouchEnabled(true); - - pieChart.setEntryLabelColor(Color.parseColor("#FF000000")); - - pieChart.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - switch (motionEvent.getAction()) - { - case MotionEvent.ACTION_DOWN: - refreshLayout.setEnabled(false); - break; - case MotionEvent.ACTION_MOVE: - break; - default: - refreshLayout.setEnabled(true); - break; - } - return false; - } - }); - - pieChart.getDescription().setEnabled(false); - pieChart.getLegend().setEnabled(false); - pieChart.setCenterText(generateCenterSpannableText()); - pieChart.invalidate(); // refresh - - } - - private void setupTextViewMarketCap() - { - DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.UK); - DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols(); - - symbols.setGroupingSeparator(' '); - formatter.setDecimalFormatSymbols(symbols); - - ((TextView) findViewById(R.id.marketCapTextView)).setText(getResources().getString(R.string.market_cap_textview, formatter.format(marketCapManager.getMarketCap()))); - - ((TextView) findViewById(R.id.dayVolumeTotalMarketCap)).setText(getResources().getString(R.string.volume_market_cap_textview, formatter.format(marketCapManager.getDayVolume()))); - } - - private SpannableString generateCenterSpannableText() { - - SpannableString spannableString = new SpannableString("Market Capitalization Dominance"); - return spannableString; - } - - private void countCoins(boolean isCoin, boolean isDetails) - { - if(isCoin) - { - coinCounter++; - } - - if(isDetails) - { - detailsChecker = true; - } - - if(balanceManager.getTotalBalance() != null) - { - if(coinCounter == balanceManager.getTotalBalance().size() && detailsChecker) - { - IconDownloader iconDownloader = new IconDownloader(); - iconDownloader.execute(); - } - else - { - if(balanceManager.getTotalBalance().size() == 0) - { - countIcons(); - } - } - } - } - - private void updateViewButtonIcon() - { - ImageButton imgButton = findViewById(R.id.switch_button); - - imgButton.setBackgroundColor(this.getResources().getColor(R.color.buttonColor)); - - if(isDetailed) - { - imgButton.setBackground(this.getResources().getDrawable(R.drawable.ic_unfold_less_black_24dp)); - preferencesManager.setDetailOption(true); - } - else - { - imgButton.setBackground(this.getResources().getDrawable(R.drawable.ic_details_black_24dp)); - preferencesManager.setDetailOption(false); - } - } - - private void generateSplashScreen() - { - LinearLayout loadingLayout = new LinearLayout(this); - - loadingLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - loadingLayout.setGravity(Gravity.CENTER); - loadingLayout.setOrientation(LinearLayout.VERTICAL); - - loadingDialog = new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen); - - TextView txtView = new TextView(this); - txtView.setText("Loading data..."); - txtView.setTextSize(20); - txtView.setGravity(Gravity.CENTER); - txtView.setTextColor(this.getResources().getColor(R.color.cardview_light_background)); - - ProgressBar progressBar = new ProgressBar(this); - progressBar.setIndeterminate(true); - - loadingLayout.setBackgroundColor(this.getResources().getColor(R.color.colorPrimaryDark)); - loadingLayout.addView(txtView); - loadingLayout.addView(progressBar); - - loadingDialog.setContentView(loadingLayout); - loadingDialog.show(); - } - - private class IconDownloader extends AsyncTask - { - @Override - protected void onPreExecute() - { - super.onPreExecute(); - } - - @Override - protected void onProgressUpdate(Integer... values) - { - super.onProgressUpdate(values); - } - - @Override - protected Void doInBackground(Void... params) - { - for (int i = 0; i < balanceManager.getTotalBalance().size(); i++) - { - final Currency localCurrency = balanceManager.getTotalBalance().get(i); - - if(balanceManager.getIconUrl(localCurrency.getSymbol()) != null) - { - getBitmapFromURL(balanceManager.getIconUrl(localCurrency.getSymbol()), new IconCallBack() { - @Override - public void onSuccess(Bitmap bitmapIcon) { - localCurrency.setIcon(bitmapIcon); - countIcons(); - } - }); - } - } - - return null; - } - - @Override - protected void onPostExecute(Void result) - { - - } - } - - private class UiHeavyLoadCalculator extends AsyncTask - { - - @Override - protected void onPreExecute() - { - super.onPreExecute(); - - totalValue = 0; - totalFluctuation = 0; - } - - @Override - protected void onProgressUpdate(Integer... values) - { - super.onProgressUpdate(values); - } - - private void updateChartColor(Currency currency) - { - if(currency.getIcon() != null) - { - Palette.Builder builder = Palette.from(currency.getIcon()); - - currency.setChartColor(builder.generate().getDominantColor(0)); - } - else - { - currency.setChartColor(12369084); - } - } - - private void loadCurrency(Currency currency) - { - if(!currency.getSymbol().equals("USD") && (currency.getBalance() * currency.getValue()) > 0.001) - { - currency.setName(balanceManager.getCurrencyName(currency.getSymbol())); - currency.setId(balanceManager.getCurrencyId(currency.getSymbol())); - totalValue += currency.getValue() * currency.getBalance(); - totalFluctuation += (currency.getValue() * currency.getBalance()) * (currency.getDayFluctuationPercentage() / 100); - } - } - - private void refreshCurrencyList() - { - runOnUiThread(new Runnable() { - @Override - public void run() { - currencyLayout.removeAllViews(); - - for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) - { - Currency currency = balanceManager.getTotalBalance().get(i); - - if(!currency.getSymbol().equals("USD") && (currency.getBalance() * currency.getValue()) > 0.001) { - currencyLayout.addView(layoutGenerator.getInfoLayout(currency, isDetailed, totalValue, preferencesManager.isBalanceHidden())); - } - } - } - }); - } - - @Override - protected Void doInBackground(Void... params) - { - if(Looper.myLooper() == null) - { - Looper.prepare(); - } - - balanceManager.sortCoins(); - - for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) - { - final Currency localCurrency = balanceManager.getTotalBalance().get(i); - - updateChartColor(localCurrency); - - loadCurrency(localCurrency); - - balanceManager.getTotalBalance().set(i, localCurrency); - } - - runOnUiThread(new Runnable() { - @Override - public void run() { - updateTitle(); - } - }); - - if(loadingDialog.isShowing()) - { - loadingDialog.dismiss(); - } - - return null; - } - - @Override - protected void onPostExecute(Void result) - { - refreshLayout.setRefreshing(false); - refreshCurrencyList(); - HomeActivity.this.totalValue = totalValue; - handler.removeCallbacks(updateRunnable); - } - } - - private class DataUpdater extends AsyncTask - { - @Override - protected void onPreExecute() - { - super.onPreExecute(); - } - - @Override - protected void onProgressUpdate(Integer... values) - { - super.onProgressUpdate(values); - } - - @Override - protected Void doInBackground(Void... params) - { - balanceManager.updateDetails(new BalanceManager.IconCallBack() { - @Override - public void onSuccess() - { - countCoins(false, true); - } - }); - - balanceManager.updateTotalBalance(new BalanceManager.VolleyCallBack() { - @Override - public void onSuccess() { - - final List balance = balanceManager.getTotalBalance(); - - if(balanceManager.getTotalBalance().size() > 0) - { - for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) - { - balance.get(i).updateHistoryMinutes(getApplicationContext(), new Currency.CurrencyCallBack() { - @Override - public void onSuccess(Currency currency) { - countCoins(true, false); - } - }); - } - } - else - { - runOnUiThread(new Runnable() { - @Override - public void run() { - countCoins(false, false); - } - }); - } - } - - public void onError(String error) - { - switch (error) - { - case "com.android.volley.AuthFailureError": - preferencesManager.disableHitBTC(); - Snackbar.make(findViewById(R.id.viewFlipperSummary), "HitBTC synchronization error : Invalid keys", Snackbar.LENGTH_LONG) - .show(); - refreshLayout.setRefreshing(false); - updateAll(true); - break; - case "API-key format invalid.": - preferencesManager.disableBinance(); - Snackbar.make(findViewById(R.id.viewFlipperSummary), "Binance synchronization error : Invalid keys", Snackbar.LENGTH_LONG) - .show(); - updateAll(true); - break; - default: - Snackbar.make(findViewById(R.id.viewFlipperSummary), "Unexpected error", Snackbar.LENGTH_LONG) - .show(); - Log.d("coinfolio", error); - updateAll(true); - } - } - }); - - updateMarketCap(); - - return null; - } - - @Override - protected void onPostExecute(Void result) - { - - } - } - public interface IconCallBack { void onSuccess(Bitmap bitmap); diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/MarketCapitalization.java b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/MarketCapitalization.java new file mode 100644 index 0000000..4c19822 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/MarketCapitalization.java @@ -0,0 +1,232 @@ +package com.nauk.coinfolio.Activities.HomeActivityFragments; + +import android.annotation.SuppressLint; +import android.graphics.Color; +import android.support.v4.app.Fragment; +import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; +import android.text.SpannableString; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.github.mikephil.charting.charts.PieChart; +import com.github.mikephil.charting.data.PieData; +import com.github.mikephil.charting.data.PieDataSet; +import com.github.mikephil.charting.data.PieEntry; +import com.github.mikephil.charting.formatter.PercentFormatter; +import com.nauk.coinfolio.DataManagers.MarketCapManager; +import com.nauk.coinfolio.R; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +/** + * Created by Tiji on 13/04/2018. + */ + +public class MarketCapitalization extends Fragment { + + private int marketCapCounter; + + private MarketCapManager marketCapManager; + private HashMap dominantCurrenciesColors; + private SwipeRefreshLayout refreshLayout; + private long lastTimestamp; + + private View view; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + view = inflater.inflate(R.layout.fragment_marketcap_homeactivity, container, false); + + marketCapManager = new MarketCapManager(getContext()); + refreshLayout = view.findViewById(R.id.swiperefresh); + + refreshLayout.setOnRefreshListener( + new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + updateMarketCap(); + } + + } + ); + + lastTimestamp = 0; + + setupDominantCurrenciesColors(); + + updateMarketCap(); + + return view; + } + + private void setupDominantCurrenciesColors() + { + dominantCurrenciesColors = new HashMap<>(); + + dominantCurrenciesColors.put("BTC", -489456); + dominantCurrenciesColors.put("ETH", -13619152); + dominantCurrenciesColors.put("XRP", -16744256); + dominantCurrenciesColors.put("BCH", -1011696); + dominantCurrenciesColors.put("LTC", -4671304); + dominantCurrenciesColors.put("ADA", -16773080); + dominantCurrenciesColors.put("NEO", -9390048); + dominantCurrenciesColors.put("XLM", -11509656); + dominantCurrenciesColors.put("XMR", -499712); + dominantCurrenciesColors.put("EOS", -1513240); + dominantCurrenciesColors.put("IOT", -1513240); + dominantCurrenciesColors.put("DASH", -15175496); + dominantCurrenciesColors.put("XEM", -7829368); + dominantCurrenciesColors.put("TRX", -7829360); + dominantCurrenciesColors.put("ETC", -10448784); + } + + private void updateMarketCap() + { + if(System.currentTimeMillis() / 1000 - lastTimestamp > 60) + { + if(!refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(true); + } + + marketCapCounter = 0; + + lastTimestamp = System.currentTimeMillis() / 1000; + + marketCapManager.updateTopCurrencies(new MarketCapManager.VolleyCallBack() { + @Override + public void onSuccess() + { + countCompletedMarketCapRequest(); + } + }); + + marketCapManager.updateMarketCap(new MarketCapManager.VolleyCallBack() { + @Override + public void onSuccess() { + countCompletedMarketCapRequest(); + } + }); + } + else + { + if(refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(false); + } + } + } + + @SuppressLint("ClickableViewAccessibility") + private void countCompletedMarketCapRequest() + { + marketCapCounter++; + + if(marketCapCounter == 2) + { + setupTextViewMarketCap(); + + view.findViewById(R.id.progressBarMarketCap).setVisibility(View.GONE); + view.findViewById(R.id.layoutProgressMarketCap).setVisibility(View.VISIBLE); + + List entries = new ArrayList<>(); + + ArrayList colors = new ArrayList<>(); + + float otherCurrenciesDominance = 0; + + for(Iterator i = marketCapManager.getDominance().keySet().iterator(); i.hasNext(); ) + { + String key = (String) i.next(); + entries.add(new PieEntry(marketCapManager.getDominance().get(key), key)); + otherCurrenciesDominance += marketCapManager.getDominance().get(key); + colors.add(dominantCurrenciesColors.get(key)); + } + entries.add(new PieEntry(100-otherCurrenciesDominance, "Others")); + colors.add(-12369084); + + PieDataSet set = new PieDataSet(entries, "Market Cap Dominance"); + set.setColors(colors); + set.setSliceSpace(1); + set.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE); + set.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE); + PieData data = new PieData(set); + data.setValueTextSize(10); + data.setValueFormatter(new PercentFormatter()); + + setupPieChart(data); + + if(refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(false); + } + } + } + + private void setupPieChart(PieData data) + { + PieChart pieChart = view.findViewById(R.id.marketCapPieChart); + + pieChart.setData(data); + pieChart.setDrawSlicesUnderHole(false); + pieChart.setUsePercentValues(true); + pieChart.setTouchEnabled(true); + + pieChart.setEntryLabelColor(Color.parseColor("#FF000000")); + + pieChart.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + switch (motionEvent.getAction()) + { + case MotionEvent.ACTION_DOWN: + refreshLayout.setEnabled(false); + break; + case MotionEvent.ACTION_MOVE: + break; + default: + refreshLayout.setEnabled(true); + break; + } + return false; + } + }); + + pieChart.getDescription().setEnabled(false); + pieChart.getLegend().setEnabled(false); + pieChart.setCenterText(generateCenterSpannableText()); + pieChart.invalidate(); // refresh + + } + + private SpannableString generateCenterSpannableText() { + + SpannableString spannableString = new SpannableString("Market Capitalization Dominance"); + return spannableString; + } + + private void setupTextViewMarketCap() + { + DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.UK); + DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols(); + + symbols.setGroupingSeparator(' '); + formatter.setDecimalFormatSymbols(symbols); + + ((TextView) view.findViewById(R.id.marketCapTextView)).setText(getResources().getString(R.string.market_cap_textview, formatter.format(marketCapManager.getMarketCap()))); + + ((TextView) view.findViewById(R.id.dayVolumeTotalMarketCap)).setText(getResources().getString(R.string.volume_market_cap_textview, formatter.format(marketCapManager.getDayVolume()))); + } +} diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Summary.java b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Summary.java new file mode 100644 index 0000000..0086b15 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Summary.java @@ -0,0 +1,660 @@ +package com.nauk.coinfolio.Activities.HomeActivityFragments; + +import android.app.Dialog; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.os.AsyncTask; +import android.os.Handler; +import android.os.Looper; +import android.support.design.widget.CollapsingToolbarLayout; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.graphics.Palette; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.nauk.coinfolio.Activities.CurrencySelectionActivity; +import com.nauk.coinfolio.Activities.HomeActivity; +import com.nauk.coinfolio.Activities.SettingsActivity; +import com.nauk.coinfolio.DataManagers.BalanceManager; +import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; +import com.nauk.coinfolio.DataManagers.PreferencesManager; +import com.nauk.coinfolio.LayoutManagers.HomeLayoutGenerator; +import com.nauk.coinfolio.R; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.List; + +/** + * Created by Tiji on 13/04/2018. + */ + +public class Summary extends Fragment { + + private boolean isDetailed; + private LinearLayout currencyLayout; + private PreferencesManager preferencesManager; + private BalanceManager balanceManager; + private HomeLayoutGenerator layoutGenerator; + private View view; + private SwipeRefreshLayout refreshLayout; + private Dialog loadingDialog; + + private TextView toolbarSubtitle; + private CollapsingToolbarLayout toolbarLayout; + private Handler handler; + + private Runnable updateRunnable; + + private int coinCounter; + private int iconCounter; + private float totalValue; + private boolean detailsChecker; + protected float totalFluctuation; + private long lastTimestamp; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + view = inflater.inflate(R.layout.fragment_summary_homeactivity, container, false); + + currencyLayout = view.findViewById(R.id.currencyListLayout); + preferencesManager = new PreferencesManager(getActivity()); + balanceManager = new BalanceManager(getActivity()); + layoutGenerator = new HomeLayoutGenerator(getActivity()); + refreshLayout = view.findViewById(R.id.swiperefresh); + toolbarSubtitle = getActivity().findViewById(R.id.toolbarSubtitle); + toolbarLayout = getActivity().findViewById(R.id.toolbar_layout); + + isDetailed = preferencesManager.getDetailOption(); + + totalValue = 0; + totalFluctuation = 0; + lastTimestamp = 0; + + handler = new Handler(); + updateRunnable = new Runnable() { + @Override + public void run() { + if (refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(false); + + showErrorSnackbar(); + } + + if (loadingDialog.isShowing()) + { + loadingDialog.dismiss(); + + showErrorSnackbar(); + } + } + }; + + refreshLayout.setOnRefreshListener( + new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + updateAll(false); + } + + } + ); + + handler.postDelayed(updateRunnable, 10000); + + Button addCurrencyButton = view.findViewById(R.id.buttonAddTransaction); + + addCurrencyButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent addIntent = new Intent(getActivity(), CurrencySelectionActivity.class); + + startActivity(addIntent); + } + }); + + ImageButton detailsButton = getActivity().findViewById(R.id.switch_button); + detailsButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + switchView(); + } + }); + + displayBalance(preferencesManager.isBalanceHidden()); + + updateTitle(); + + generateSplashScreen(); + + updateAll(true); + + return view; + } + + private void updateAll(boolean mustUpdate) + { + if(System.currentTimeMillis()/1000 - lastTimestamp > 60 || mustUpdate) + { + if(!refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(true); + } + + lastTimestamp = System.currentTimeMillis() / 1000; + balanceManager.updateExchangeKeys(); + refreshLayout.setRefreshing(true); + + resetCounters(); + DataUpdater updater = new DataUpdater(); + updater.execute(); + + } + else + { + if(refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(false); + } + } + } + + private void showErrorSnackbar() + { + /*Snackbar.make(getActivity().findViewById(R.id.viewFlipperSummary), "Error while updating data", Snackbar.LENGTH_LONG) + .setAction("Update", new View.OnClickListener() { + @Override + public void onClick(View view) { + + } + }) + .show();*/ + } + + private void resetCounters() + { + coinCounter = 0; + iconCounter = 0; + detailsChecker = false; + + totalValue = 0; + totalFluctuation = 0; + } + + private void generateSplashScreen() + { + LinearLayout loadingLayout = new LinearLayout(getActivity()); + + loadingLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + loadingLayout.setGravity(Gravity.CENTER); + loadingLayout.setOrientation(LinearLayout.VERTICAL); + + loadingDialog = new Dialog(getActivity(), android.R.style.Theme_Black_NoTitleBar_Fullscreen); + + TextView txtView = new TextView(getActivity()); + txtView.setText("Loading data..."); + txtView.setTextSize(20); + txtView.setGravity(Gravity.CENTER); + txtView.setTextColor(this.getResources().getColor(R.color.cardview_light_background)); + + ProgressBar progressBar = new ProgressBar(getActivity()); + progressBar.setIndeterminate(true); + + loadingLayout.setBackgroundColor(this.getResources().getColor(R.color.colorPrimaryDark)); + loadingLayout.addView(txtView); + loadingLayout.addView(progressBar); + + loadingDialog.setContentView(loadingLayout); + loadingDialog.show(); + } + + private void switchView() + { + if(isDetailed) + { + isDetailed = false; + + adaptView(); + } + else + { + isDetailed = true; + + adaptView(); + } + } + + private void adaptView() + { + currencyLayout.removeAllViews(); + + for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) + { + final Currency currency = balanceManager.getTotalBalance().get(i); + + if(!currency.getSymbol().equals("USD") && ((currency.getBalance() * currency.getValue()) > 0.001 || currency.getHistoryMinutes() == null)) + { + currencyLayout.addView(layoutGenerator.getInfoLayout(currency, isDetailed, totalValue, preferencesManager.isBalanceHidden())); + } + } + } + + private void countCoins(boolean isCoin, boolean isDetails) + { + if(isCoin) + { + coinCounter++; + } + + if(isDetails) + { + detailsChecker = true; + } + + if(balanceManager.getTotalBalance() != null) + { + if(coinCounter == balanceManager.getTotalBalance().size() && detailsChecker) + { + IconDownloader iconDownloader = new IconDownloader(); + iconDownloader.execute(); + } + else + { + if(balanceManager.getTotalBalance().size() == 0) + { + countIcons(); + } + } + } + } + + + private void countIcons() + { + int offset = 0; + + for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) + { + if(balanceManager.getTotalBalance().get(i).getSymbol().equals("USD")) + { + offset++; + } + } + + iconCounter++; + + if(balanceManager.getTotalBalance() != null) + { + if(balanceManager.getTotalBalance().size() == 0) + { + updateNoBalance(); + } + else + { + if(iconCounter == balanceManager.getTotalBalance().size() - offset) + { + Log.d(getResources().getString(R.string.debug), "Loading heavy"); + + UiHeavyLoadCalculator uiHeavyLoadCalculator = new UiHeavyLoadCalculator(); + uiHeavyLoadCalculator.execute(); + } + } + } + } + + private void updateNoBalance() + { + refreshLayout.setRefreshing(false); + + currencyLayout.removeAllViews(); + + if(loadingDialog.isShowing()) + { + loadingDialog.dismiss(); + } + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + + updateTitle(); + } + }); + } + + protected void updateTitle() + { + float totalFluctuationPercentage = totalFluctuation / (totalValue - totalFluctuation) * 100; + + if(preferencesManager.isBalanceHidden()) + { + toolbarLayout.setTitle(getResources().getString(R.string.currencyPercentagePlaceholder, String.format("%.2f", totalFluctuationPercentage))); + toolbarSubtitle.setVisibility(View.GONE); + + if(totalFluctuation > 0) + { + toolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.increase)); + toolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.increase)); + } + else + { + toolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.decrease)); + toolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.decrease)); + } + } + else + { + toolbarLayout.setTitle(getResources().getString(R.string.currencyDollarPlaceholder, String.format("%.2f", totalValue))); + toolbarLayout.setCollapsedTitleTextColor(Color.WHITE); + toolbarLayout.setExpandedTitleColor(Color.WHITE); + + toolbarSubtitle.setVisibility(View.VISIBLE); + + if(totalFluctuation > 0) + { + toolbarSubtitle.setTextColor(getResources().getColor(R.color.increase)); + } + else + { + toolbarSubtitle.setTextColor(getResources().getColor(R.color.decrease)); + } + + if(totalFluctuation == 0) + { + toolbarSubtitle.setText(getResources().getString(R.string.currencyDollarPlaceholder, "0.00")); + toolbarSubtitle.setTextColor(-1275068417); + + } + else + { + toolbarSubtitle.setText("US$" + String.format("%.2f", totalFluctuation) + " (" + String.format("%.2f", totalFluctuationPercentage) + "%)"); + } + } + } + + private class UiHeavyLoadCalculator extends AsyncTask + { + + @Override + protected void onPreExecute() + { + super.onPreExecute(); + + totalValue = 0; + totalFluctuation = 0; + } + + @Override + protected void onProgressUpdate(Integer... values) + { + super.onProgressUpdate(values); + } + + private void updateChartColor(Currency currency) + { + if(currency.getIcon() != null) + { + Palette.Builder builder = Palette.from(currency.getIcon()); + + currency.setChartColor(builder.generate().getDominantColor(0)); + } + else + { + currency.setChartColor(12369084); + } + } + + private void loadCurrency(Currency currency) + { + if(!currency.getSymbol().equals("USD") && (currency.getBalance() * currency.getValue()) > 0.001) + { + currency.setName(balanceManager.getCurrencyName(currency.getSymbol())); + currency.setId(balanceManager.getCurrencyId(currency.getSymbol())); + totalValue += currency.getValue() * currency.getBalance(); + totalFluctuation += (currency.getValue() * currency.getBalance()) * (currency.getDayFluctuationPercentage() / 100); + } + } + + private void refreshCurrencyList() + { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + currencyLayout.removeAllViews(); + + for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) + { + Currency currency = balanceManager.getTotalBalance().get(i); + + if(!currency.getSymbol().equals("USD") && (currency.getBalance() * currency.getValue()) > 0.001) { + currencyLayout.addView(layoutGenerator.getInfoLayout(currency, isDetailed, totalValue, preferencesManager.isBalanceHidden())); + } + } + } + }); + } + + @Override + protected Void doInBackground(Void... params) + { + if(Looper.myLooper() == null) + { + Looper.prepare(); + } + + balanceManager.sortCoins(); + + for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) + { + final Currency localCurrency = balanceManager.getTotalBalance().get(i); + + updateChartColor(localCurrency); + + loadCurrency(localCurrency); + + balanceManager.getTotalBalance().set(i, localCurrency); + } + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + updateTitle(); + } + }); + + if(loadingDialog.isShowing()) + { + loadingDialog.dismiss(); + } + + return null; + } + + @Override + protected void onPostExecute(Void result) + { + refreshLayout.setRefreshing(false); + refreshCurrencyList(); + totalValue = totalValue; + handler.removeCallbacks(updateRunnable); + } + } + + private void getBitmapFromURL(String src, HomeActivity.IconCallBack callBack) { + Bitmap result; + + try { + java.net.URL url = new java.net.URL(src); + HttpURLConnection connection = (HttpURLConnection) url + .openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + result = BitmapFactory.decodeStream(input); + } catch (IOException e) { + e.printStackTrace(); + result = BitmapFactory.decodeResource(this.getResources(), + R.mipmap.icon_coinfolio); + result = Bitmap.createScaledBitmap(result, 50, 50, false); + } + + callBack.onSuccess(result); + } + + private void displayBalance(boolean hideBalance) + { + updateTitle(); + + if(hideBalance) + { + for(int i = 0; i < currencyLayout.getChildCount(); i++) + { + currencyLayout.getChildAt(i).findViewById(R.id.currencyPortfolioDominance).setVisibility(View.VISIBLE); + currencyLayout.getChildAt(i).findViewById(R.id.percentageOwnedTextView).setVisibility(View.VISIBLE); + currencyLayout.getChildAt(i).findViewById(R.id.currencyOwnedInfoLayout).setVisibility(View.GONE); + } + } + else + { + for(int i = 0; i < currencyLayout.getChildCount(); i++) + { + currencyLayout.getChildAt(i).findViewById(R.id.currencyPortfolioDominance).setVisibility(View.INVISIBLE); + currencyLayout.getChildAt(i).findViewById(R.id.percentageOwnedTextView).setVisibility(View.GONE); + currencyLayout.getChildAt(i).findViewById(R.id.currencyOwnedInfoLayout).setVisibility(View.VISIBLE); + } + } + } + + private class IconDownloader extends AsyncTask + { + @Override + protected void onPreExecute() + { + super.onPreExecute(); + } + + @Override + protected void onProgressUpdate(Integer... values) + { + super.onProgressUpdate(values); + } + + @Override + protected Void doInBackground(Void... params) + { + for (int i = 0; i < balanceManager.getTotalBalance().size(); i++) + { + final Currency localCurrency = balanceManager.getTotalBalance().get(i); + + if(balanceManager.getIconUrl(localCurrency.getSymbol()) != null) + { + getBitmapFromURL(balanceManager.getIconUrl(localCurrency.getSymbol()), new HomeActivity.IconCallBack() { + @Override + public void onSuccess(Bitmap bitmapIcon) { + localCurrency.setIcon(bitmapIcon); + countIcons(); + } + }); + } + } + + return null; + } + + @Override + protected void onPostExecute(Void result) + { + + } + } + + + private class DataUpdater extends AsyncTask + { + @Override + protected Void doInBackground(Void... params) + { + balanceManager.updateDetails(new BalanceManager.IconCallBack() { + @Override + public void onSuccess() + { + countCoins(false, true); + } + }); + + balanceManager.updateTotalBalance(new BalanceManager.VolleyCallBack() { + @Override + public void onSuccess() { + + final List balance = balanceManager.getTotalBalance(); + + if(balanceManager.getTotalBalance().size() > 0) + { + for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) + { + balance.get(i).updateHistoryMinutes(getActivity(), new Currency.CurrencyCallBack() { + @Override + public void onSuccess(Currency currency) { + countCoins(true, false); + } + }); + } + } + else + { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + countCoins(false, false); + } + }); + } + } + + public void onError(String error) + { + /*switch (error) + { + case "com.android.volley.AuthFailureError": + preferencesManager.disableHitBTC(); + Snackbar.make(findViewById(R.id.viewFlipperSummary), "HitBTC synchronization error : Invalid keys", Snackbar.LENGTH_LONG) + .show(); + refreshLayout.setRefreshing(false); + updateAll(true); + break; + case "API-key format invalid.": + preferencesManager.disableBinance(); + Snackbar.make(findViewById(R.id.viewFlipperSummary), "Binance synchronization error : Invalid keys", Snackbar.LENGTH_LONG) + .show(); + updateAll(true); + break; + default: + Snackbar.make(findViewById(R.id.viewFlipperSummary), "Unexpected error", Snackbar.LENGTH_LONG) + .show(); + Log.d("coinfolio", error); + updateAll(true); + }*/ + } + }); + + return null; + } + } + +} diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Watchlist.java b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Watchlist.java new file mode 100644 index 0000000..7174024 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivityFragments/Watchlist.java @@ -0,0 +1,230 @@ +package com.nauk.coinfolio.Activities.HomeActivityFragments; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.support.v4.app.Fragment; +import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.nauk.coinfolio.Activities.CurrencySelectionActivity; +import com.nauk.coinfolio.Activities.HomeActivity; +import com.nauk.coinfolio.DataManagers.BalanceManager; +import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; +import com.nauk.coinfolio.DataManagers.CurrencyData.CurrencyDetailsList; +import com.nauk.coinfolio.DataManagers.PreferencesManager; +import com.nauk.coinfolio.DataManagers.WatchlistManager; +import com.nauk.coinfolio.R; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +/** + * Created by Tiji on 13/04/2018. + */ + +public class Watchlist extends Fragment { + + private WatchlistManager watchlistManager; + private View view; + private int watchlistCounter; + private CurrencyDetailsList currencyDetailsList; + private SwipeRefreshLayout refreshLayout; + private long lastTimestamp; + private PreferencesManager preferencesManager; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + view = inflater.inflate(R.layout.fragment_watchlist_homeactivity, container, false); + + refreshLayout = view.findViewById(R.id.swiperefresh); + currencyDetailsList = new CurrencyDetailsList(getContext()); + preferencesManager = new PreferencesManager(getContext()); + + lastTimestamp = 0; + + watchlistManager = new WatchlistManager(getContext()); + + updateWatchlist(true); + + refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + updateWatchlist(false); + } + }); + + Button addWatchlistButton = view.findViewById(R.id.buttonAddWatchlist); + addWatchlistButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent selectionIntent = new Intent(getActivity(), CurrencySelectionActivity.class); + selectionIntent.putExtra("isWatchList", true); + startActivity(selectionIntent); + } + }); + + return view; + } + + @Override + public void onResume() + { + super.onResume(); + + updateWatchlist(preferencesManager.mustUpdate()); + } + + private void updateWatchlist(boolean mustUpdate) + { + if(System.currentTimeMillis()/1000 - lastTimestamp > 60 || mustUpdate) + { + if(!refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(true); + } + + lastTimestamp = System.currentTimeMillis()/1000; + + watchlistManager.updateWatchlist(); + + currencyDetailsList.update(new BalanceManager.IconCallBack() { + @Override + public void onSuccess() { + WatchlistUpdater watchlistUpdater = new WatchlistUpdater(); + watchlistUpdater.execute(); + } + }); + } + else + { + if(refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(false); + } + } + } + + private void countWatchlist() + { + watchlistCounter++; + + if(watchlistCounter >= watchlistManager.getWatchlist().size()) + { + ((LinearLayout) view.findViewById(R.id.linearLayoutWatchlist)).removeAllViews(); + + for(Currency currency : watchlistManager.getWatchlist()) + { + View card = LayoutInflater.from(getContext()).inflate(R.layout.cardview_watchlist, null); + + ((TextView) card.findViewById(R.id.currencyFluctuationPercentageTextView)).setText("3%"); + ((TextView) card.findViewById(R.id.currencyFluctuationTextView)).setText("$3"); + ((TextView) card.findViewById(R.id.currencyNameTextView)).setText(currency.getName()); + ((TextView) card.findViewById(R.id.currencySymbolTextView)).setText(currency.getSymbol()); + ((ImageView) card.findViewById(R.id.currencyIcon)).setImageBitmap(currency.getIcon()); + ((TextView) card.findViewById(R.id.currencyValueTextView)).setText("" + currency.getValue()); + + card.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + card.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Log.d("coinfolio", "Clicked !"); + } + }); + + ((LinearLayout) view.findViewById(R.id.linearLayoutWatchlist)).addView(card, 0); + } + + if(refreshLayout.isRefreshing()) + { + refreshLayout.setRefreshing(false); + } + } + } + + private String getIconUrl(String symbol) + { + String url; + + try { + JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol)); + url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50"; + } catch (NullPointerException e) { + Log.d(getContext().getResources().getString(R.string.debug), symbol + " has no icon URL"); + url = null; + } catch (JSONException e) { + Log.d(getContext().getResources().getString(R.string.debug), "Url parsing error for " + symbol); + url = null; + } + + return url; + } + + private void getBitmapFromURL(String src, HomeActivity.IconCallBack callBack) { + Bitmap result; + + try { + java.net.URL url = new java.net.URL(src); + HttpURLConnection connection = (HttpURLConnection) url + .openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + result = BitmapFactory.decodeStream(input); + } catch (IOException e) { + e.printStackTrace(); + result = BitmapFactory.decodeResource(this.getResources(), + R.mipmap.icon_coinfolio); + result = Bitmap.createScaledBitmap(result, 50, 50, false); + } + + callBack.onSuccess(result); + } + + private class WatchlistUpdater extends AsyncTask + { + @Override + protected void onPreExecute() + { + watchlistCounter = 0; + } + + @Override + protected Void doInBackground(Void... voids) { + for(Currency currency : watchlistManager.getWatchlist()) + { + currency.updateHistoryMinutes(getActivity(), new Currency.CurrencyCallBack() { + @Override + public void onSuccess(final Currency sucessCurrency) { + if(getIconUrl(sucessCurrency.getSymbol()) != null) + { + getBitmapFromURL(getIconUrl(sucessCurrency.getSymbol()), new HomeActivity.IconCallBack() { + @Override + public void onSuccess(Bitmap bitmapIcon) { + sucessCurrency.setIcon(bitmapIcon); + countWatchlist(); + } + }); + } + } + }); + } + return null; + } + } +} diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java index 29a690d..6c4db11 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/RecordTransactionActivity.java @@ -4,6 +4,7 @@ import android.app.DatePickerDialog; import android.content.Intent; import android.os.Bundle; import android.preference.PreferenceManager; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java index bbd6a58..5dc3515 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java @@ -121,7 +121,7 @@ public class BalanceManager { { boolean isUpdated = false; - manualBalances = databaseManager.getAllCurrencyFromManualCurrency(); + manualBalances = databaseManager.getAllCurrenciesFromManualCurrency(); if(binanceManagers.size() > 0) { diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java index 9ca08a1..2f6ea8e 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/Currency.java @@ -3,6 +3,12 @@ package com.nauk.coinfolio.DataManagers.CurrencyData; import android.graphics.Bitmap; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; + +import com.nauk.coinfolio.R; + +import org.json.JSONException; +import org.json.JSONObject; import java.util.ArrayList; import java.util.List; @@ -71,6 +77,24 @@ public class Currency implements Parcelable { }, timestamp); } + public static String getIconUrl(String currencyDetails) + { + String url; + + try { + JSONObject jsonObject = new JSONObject(currencyDetails); + url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50"; + } catch (NullPointerException e) { + //Log.d(context.getResources().getString(R.string.debug), symbol + " has no icon URL"); + url = null; + } catch (JSONException e) { + //Log.d(context.getResources().getString(R.string.debug), "Url parsing error for " + symbol); + url = null; + } + + return url; + } + public void updateHistoryMinutes(android.content.Context context, final CurrencyCallBack callBack) { dataRetriver = new CurrencyDataRetriever(context); diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java index a804607..a94b503 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/DatabaseManager.java @@ -19,12 +19,13 @@ import java.util.List; public class DatabaseManager extends SQLiteOpenHelper{ - private static final int DATABASE_VERSION = 5; + private static final int DATABASE_VERSION = 6; private static final String DATABASE_NAME = "Currencies.db"; private static final String TABLE_MANUAL_CURRENCIES = "ManualCurrencies"; private static final String TABLE_EXCHANGE_KEYS = "ExchangeKeys"; + private static final String TABLE_WATCHLIST = "Watchlist"; private static final String KEY_CURRENCY_ID = "idCurrency"; private static final String KEY_CURRENCY_SYMBOL = "symbol"; @@ -39,6 +40,11 @@ public class DatabaseManager extends SQLiteOpenHelper{ private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey"; private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey"; + private static final String KEY_WATCHLIST_ID = "idWatchlist"; + private static final String KEY_WATCHLIST_SYMBOL = "symbol"; + private static final String KEY_WATCHLIST_NAME = "name"; + private static final String KEY_WATCHLIST_POSITION = "position"; + public DatabaseManager(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -64,6 +70,13 @@ public class DatabaseManager extends SQLiteOpenHelper{ + KEY_EXCHANGE_SECRET_KEY + " TEXT" + ");"); + db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_WATCHLIST + "(" + + KEY_WATCHLIST_ID + " INTEGER PRIMARY KEY," + + KEY_WATCHLIST_SYMBOL + " VARCHAR(4)," + + KEY_WATCHLIST_NAME + " TEXT," + + KEY_WATCHLIST_POSITION + " INTEGER" + + ");"); + //loadSample(db); } @@ -72,10 +85,39 @@ public class DatabaseManager extends SQLiteOpenHelper{ { db.execSQL("DROP TABLE IF EXISTS " + TABLE_MANUAL_CURRENCIES); db.execSQL("DROP TABLE IF EXISTS " + TABLE_EXCHANGE_KEYS); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_WATCHLIST); onCreate(db); } + public void addCurrencyToWatchlist(Currency currency) + { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + + values.put(KEY_WATCHLIST_SYMBOL, currency.getSymbol()); + values.put(KEY_WATCHLIST_NAME, currency.getName()); + + db.insert(TABLE_WATCHLIST, null, values); + db.close(); + } + + public List getAllCurrenciesFromWatchlist() + { + String searchQuerry = "SELECT * FROM " + TABLE_WATCHLIST; + SQLiteDatabase db = this.getWritableDatabase(); + Cursor resultatList = db.rawQuery(searchQuerry, null); + + List currencyList = new ArrayList<>(); + + while(resultatList.moveToNext()) + { + currencyList.add(new Currency(resultatList.getString(2), resultatList.getString(1))); + } + + return currencyList; + } + public void addCurrencyToManualCurrency(String symbol, double balance, Date date, String purchasedPrice) { SQLiteDatabase db = this.getWritableDatabase(); @@ -91,7 +133,7 @@ public class DatabaseManager extends SQLiteOpenHelper{ db.close(); } - public List getAllCurrencyFromManualCurrency() + public List getAllCurrenciesFromManualCurrency() { String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES; SQLiteDatabase db = this.getWritableDatabase(); diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java index d52b5b2..402394c 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java @@ -6,7 +6,9 @@ import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.domain.account.Account; import com.binance.api.client.domain.account.AssetBalance; +import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.Trade; +import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.exception.BinanceApiException; import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/WatchlistManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/WatchlistManager.java new file mode 100644 index 0000000..59453f0 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/WatchlistManager.java @@ -0,0 +1,37 @@ +package com.nauk.coinfolio.DataManagers; + +import com.android.volley.RequestQueue; +import com.android.volley.toolbox.Volley; +import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; + +import java.util.List; + +/** + * Created by Tiji on 13/04/2018. + */ + +public class WatchlistManager { + + private android.content.Context context; + private RequestQueue requestQueue; + private DatabaseManager databaseManager; + private List watchlistCurrencies; + + public WatchlistManager(android.content.Context context) + { + this.context = context; + + requestQueue = Volley.newRequestQueue(context); + databaseManager = new DatabaseManager(context); + } + + public void updateWatchlist() + { + watchlistCurrencies = databaseManager.getAllCurrenciesFromWatchlist(); + } + + public List getWatchlist() + { + return watchlistCurrencies; + } +} diff --git a/app/src/main/java/com/nauk/coinfolio/PagerAdapter.java b/app/src/main/java/com/nauk/coinfolio/PagerAdapter.java new file mode 100644 index 0000000..febfe10 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/PagerAdapter.java @@ -0,0 +1,47 @@ +package com.nauk.coinfolio; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; + +import com.nauk.coinfolio.Activities.HomeActivityFragments.MarketCapitalization; +import com.nauk.coinfolio.Activities.HomeActivityFragments.Summary; +import com.nauk.coinfolio.Activities.HomeActivityFragments.Watchlist; + +/** + * Created by Tiji on 13/04/2018. + */ + +public class PagerAdapter extends FragmentStatePagerAdapter { + + private int numOfTabs; + + public PagerAdapter(FragmentManager fm, int numOfTabs) + { + super(fm); + this.numOfTabs = numOfTabs; + } + + @Override + public Fragment getItem(int position) { + switch (position) + { + case 0: + Watchlist watchlist = new Watchlist(); + return watchlist; + case 1: + Summary summary = new Summary(); + return summary; + case 2: + MarketCapitalization marketCapitalization = new MarketCapitalization(); + return marketCapitalization; + default: + return null; + } + } + + @Override + public int getCount() { + return numOfTabs; + } +} diff --git a/app/src/main/res/layout/activity_currency_summary.xml b/app/src/main/res/layout/activity_currency_summary.xml index a18e407..e049ade 100644 --- a/app/src/main/res/layout/activity_currency_summary.xml +++ b/app/src/main/res/layout/activity_currency_summary.xml @@ -78,7 +78,20 @@ - + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_summary_homeactivity.xml b/app/src/main/res/layout/fragment_summary_homeactivity.xml new file mode 100644 index 0000000..325226b --- /dev/null +++ b/app/src/main/res/layout/fragment_summary_homeactivity.xml @@ -0,0 +1,49 @@ + + + + + + + + +