Data backup UI rework

- Fix balance hiding not working properly after restarting the app
- An error is displayed when no proper password is entered for backup encryption
- Add Watchlist, Manual entries and API keys backup and restore options
- Add wipe old data for Watchlist, Manual entries and API keys option
- Add encode checker to know whether or not the backup is encrypted
- Fix unproper import/export labels
- Add round corners to the top of each main layout (Holdings/Watchlist/MarketCap/List)
This commit is contained in:
Tanguy Herbron 2018-07-21 14:56:26 +02:00
parent b53d52daeb
commit 7f1a318a70
15 changed files with 408 additions and 205 deletions

Binary file not shown.

2
.idea/gradle.xml generated
View File

@ -5,7 +5,7 @@
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-4.8.1" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-4.4" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View File

@ -129,6 +129,10 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
{
Switch balanceSwitch = findViewById(R.id.switchHideBalance);
PreferencesManager preferencesManager = new PreferencesManager(getBaseContext());
balanceSwitch.setChecked(preferencesManager.isBalanceHidden());
balanceSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

View File

@ -57,6 +57,8 @@ public class Overview extends Fragment {
currencyTickerList = CurrencyTickerList.getInstance(getContext());
currencyDetailsList = CurrencyDetailsList.getInstance(getContext());
fragmentView.findViewById(R.id.toolbar).bringToFront();
preferenceManager = new PreferencesManager(getContext());
listLayout = fragmentView.findViewById(R.id.linearLayoutOverview);

View File

@ -6,7 +6,6 @@ import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@ -34,7 +33,9 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
import com.applandeo.FilePicker;
import com.applandeo.listeners.OnSelectFileListener;
@ -66,10 +67,11 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
@ -421,15 +423,17 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_export_data, null, true);
dialogBuilder.setView(dialogView);
final CheckBox backupManualEntriesCheckbox = dialogView.findViewById(R.id.checkboxBackupManualEntries);
final CheckBox backupWatchlistCheckbox = dialogView.findViewById(R.id.checkboxBackupWatchlist);
final CheckBox backupKeysCheckbox = dialogView.findViewById(R.id.checkboxBackupKeys);
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
File backupDirectory = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
if (!backupDirectory.exists()) {
if (!backupDirectory.mkdirs()) {
Log.d("moodl", "Error while creating directory");
}
}
createDefaultBackupDirectory(backupDirectory);
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
textViewFilePath.setText(backupDirectory.getAbsolutePath());
textViewFilePath.setOnClickListener(new View.OnClickListener() {
@Override
@ -447,9 +451,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
}
});
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
@ -477,7 +478,14 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
if(enterPasswordCheckbox.isChecked())
{
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
if(textInputLayoutPassword.getEditText().getText().equals(""))
{
textInputLayoutPassword.setError(getString(R.string.must_be_filled));
}
else
{
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
}
}
File backupFile = new File(textViewFilePath.getText() + "/" + fileName);
@ -487,15 +495,31 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
try {
JSONObject backupJson = new JSONObject();
if(enterPasswordCheckbox.isChecked())
initiateJsonBackup(backupJson, enterPasswordCheckbox.isChecked());
if(backupManualEntriesCheckbox.isChecked())
{
backupJson.put("encodeChecker", DataCrypter.encrypt(getContext(), "NaukVerification"));
backupJson.put("transactions",
databaseManager.getDatabaseBackup(getContext(),
DatabaseManager.TABLE_MANUAL_CURRENCIES,
enterPasswordCheckbox.isChecked()));
}
else
if(backupWatchlistCheckbox.isChecked())
{
backupJson.put("encodeChecker", "NaukVerification");
backupJson.put("watchlist",
databaseManager.getDatabaseBackup(getContext(),
DatabaseManager.TABLE_WATCHLIST,
enterPasswordCheckbox.isChecked()));
}
if(backupKeysCheckbox.isChecked())
{
backupJson.put("apiKeys",
databaseManager.getDatabaseBackup(getContext(),
DatabaseManager.TABLE_EXCHANGE_KEYS,
enterPasswordCheckbox.isChecked()));
}
backupJson.put("transactions", databaseManager.getBackupData(getContext(),enterPasswordCheckbox.isChecked()));
printWriter.write(backupJson.toString());
} catch (JSONException e) {
@ -510,6 +534,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
dialog.dismiss();
}
});
dialogBuilder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
@ -532,17 +557,78 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_import_data, null, true);
dialogBuilder.setView(dialogView);
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final CheckBox restoreManualEntriesCheckbox = dialogView.findViewById(R.id.checkboxRestoreEntries);
final CheckBox restoreWatchlistCheckbox = dialogView.findViewById(R.id.checkboxRestoreWatchlist);
final CheckBox restoreApiKeysCheckbox = dialogView.findViewById(R.id.checkboxRestoreKeys);
final CheckBox wipeManualEntriesCheckbox = dialogView.findViewById(R.id.checkboxWipeManualEntries);
final CheckBox wipeWatchlistCheckbox = dialogView.findViewById(R.id.checkboxWipeWatchlist);
final CheckBox wipeApiKeyxCheckbox = dialogView.findViewById(R.id.checkboxWipeAPIKeys);
restoreManualEntriesCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(restoreManualEntriesCheckbox.isChecked())
{
MoodlBox.expandH(wipeManualEntriesCheckbox);
}
else
{
MoodlBox.collapseH(wipeManualEntriesCheckbox);
}
}
});
restoreWatchlistCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(restoreWatchlistCheckbox.isChecked())
{
MoodlBox.expandH(wipeWatchlistCheckbox);
}
else
{
MoodlBox.collapseH(wipeWatchlistCheckbox);
}
}
});
restoreApiKeysCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(restoreApiKeysCheckbox.isChecked())
{
MoodlBox.expandH(wipeApiKeyxCheckbox);
}
else
{
MoodlBox.collapseH(wipeApiKeyxCheckbox);
}
}
});
enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b && textInputLayoutPassword.getVisibility() == View.GONE)
{
MoodlBox.expandH(textInputLayoutPassword);
}
if(!b && textInputLayoutPassword.getVisibility() == View.VISIBLE)
{
MoodlBox.collapseH(textInputLayoutPassword);
}
}
});
File backupDirectory = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
if(!backupDirectory.exists())
{
if(!backupDirectory.mkdirs())
{
Log.d("moodl", "Error while creating directory");
}
}
createDefaultBackupDirectory(backupDirectory);
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
textViewFilePath.setText(backupDirectory.getAbsolutePath());
textViewFilePath.setOnClickListener(new View.OnClickListener() {
@Override
@ -559,10 +645,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
}
});
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final CheckBox wipeCheckbox = dialogView.findViewById(R.id.checkboxWipeData);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
dialogBuilder.setTitle(getString(R.string.restoreBackup));
dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
@Override
@ -577,11 +659,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
}
if(wipeCheckbox.isChecked())
{
databaseManager.wipeTransactions();
}
File backupFile = new File(textViewFilePath.getText().toString());
try {
@ -610,13 +687,44 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
if(checker.equals("NaukVerification"))
{
JSONArray transactionsArray = backupJson.getJSONArray("transactions");
for(int i = 0; i < transactionsArray.length(); i++)
if(restoreManualEntriesCheckbox.isChecked())
{
JSONObject transactionObject = transactionsArray.getJSONObject(i);
if(wipeManualEntriesCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_MANUAL_CURRENCIES);
}
databaseManager.addRowTransaction(transactionObject, getContext(), enterPasswordCheckbox.isChecked());
if(backupJson.has("transactions"))
{
JSONArray transactionsArray = backupJson.getJSONArray("transactions");
for(int i = 0; i < transactionsArray.length(); i++)
{
JSONObject transactionObject = transactionsArray.getJSONObject(i);
databaseManager.addRowTransaction(transactionObject, getContext(), enterPasswordCheckbox.isChecked());
}
}
}
if(restoreWatchlistCheckbox.isChecked())
{
if(wipeWatchlistCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_WATCHLIST);
}
if(backupJson.has("watchlist"))
{
JSONArray watchlistArray = backupJson.getJSONArray("watchlist");
for(int i = 0; i < watchlistArray.length(); i++)
{
JSONObject transactionObject = watchlistArray.getJSONObject(i);
databaseManager.addRowWatchlist(transactionObject, getContext(), enterPasswordCheckbox.isChecked());
}
}
}
}
else
@ -653,6 +761,27 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
editTextPreference.setNegativeButtonText(getString(R.string.cancel));
}
private void initiateJsonBackup(JSONObject backupJson, boolean mustEncrypt) throws JSONException
{
if(mustEncrypt)
{
backupJson.put("encodeChecker", DataCrypter.encrypt(getContext(), "NaukVerification"));
}
else
{
backupJson.put("encodeChecker", "NaukVerification");
}
}
private void createDefaultBackupDirectory(File backupDirectory)
{
if (!backupDirectory.exists()) {
if (!backupDirectory.mkdirs()) {
Log.d("moodl", "Error while creating directory");
}
}
}
private boolean checkPermissions() {
String[] permissions = new String[]{

View File

@ -24,13 +24,13 @@ import java.util.List;
public class DatabaseManager extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 6;
private static final int DATABASE_VERSION = 7;
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";
public static final String TABLE_MANUAL_CURRENCIES = "ManualCurrencies";
public static final String TABLE_EXCHANGE_KEYS = "ExchangeKeys";
public static final String TABLE_WATCHLIST = "Watchlist";
private static final String KEY_CURRENCY_ID = "idCurrency";
private static final String KEY_CURRENCY_SYMBOL = "symbol";
@ -43,6 +43,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
private static final String KEY_EXCHANGE_ID = "idExchange";
private static final String KEY_EXCHANGE_NAME = "name";
private static final String KEY_EXCHANGE_DESCRIPTION = "description";
private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey";
private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey";
@ -73,6 +74,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_EXCHANGE_KEYS + "("
+ KEY_EXCHANGE_ID + " INTEGER PRIMARY KEY,"
+ KEY_EXCHANGE_NAME + " TEXT,"
+ KEY_EXCHANGE_DESCRIPTION + " TEXT,"
+ KEY_EXCHANGE_PUBLIC_KEY + " TEXT,"
+ KEY_EXCHANGE_SECRET_KEY + " TEXT"
+ ");");
@ -90,11 +92,12 @@ public class DatabaseManager extends SQLiteOpenHelper{
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
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);
switch (oldVersion)
{
case 6:
db.execSQL("ALTER TABLE " + TABLE_EXCHANGE_KEYS
+ " ADD " + KEY_EXCHANGE_DESCRIPTION+ " VARCHAR");
}
}
private boolean isCurrencyInWatchlist(String symbol)
@ -157,17 +160,17 @@ public class DatabaseManager extends SQLiteOpenHelper{
db.close();
}
public JSONArray getBackupData(Context context, boolean encryptData)
public JSONArray getDatabaseBackup(Context context, String table, boolean encryptData)
{
String selectQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES;
String selectQuerry = "SELECT * FROM " + table;
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery(selectQuerry, null);
JSONArray transactionsArray = new JSONArray();
JSONArray backupArray = new JSONArray();
while(result.moveToNext())
{
JSONObject transactionJson = new JSONObject();
JSONObject backupObject = new JSONObject();
for(int i = 0; i < result.getColumnCount(); i++)
{
@ -176,32 +179,58 @@ public class DatabaseManager extends SQLiteOpenHelper{
{
if(encryptData)
{
transactionJson.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i)));
backupObject.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i)));
}
else
{
transactionJson.put(result.getColumnName(i), result.getString(i));
backupObject.put(result.getColumnName(i), result.getString(i));
}
}
else
{
transactionJson.put(result.getColumnName(i), "");
backupObject.put(result.getColumnName(i), "");
}
} catch (JSONException e) {
Log.d("moodl", "Error while creating a json transaction");
Log.d("moodl", "Error while creating a json backup");
}
}
transactionsArray.put(transactionJson);
backupArray.put(backupObject);
}
return transactionsArray;
return backupArray;
}
public void wipeTransactions()
public void wipeData(String table)
{
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM "+ TABLE_MANUAL_CURRENCIES);
db.execSQL("DELETE FROM "+ table);
}
public void addRowWatchlist(JSONObject rawValues, Context context, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
try {
if(decrypt)
{
values.put(KEY_WATCHLIST_SYMBOL, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_SYMBOL)));
values.put(KEY_WATCHLIST_NAME, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_NAME)));
values.put(KEY_WATCHLIST_POSITION, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_POSITION)));
}
else
{
values.put(KEY_WATCHLIST_SYMBOL, rawValues.getString(KEY_WATCHLIST_SYMBOL));
values.put(KEY_WATCHLIST_NAME, rawValues.getString(KEY_WATCHLIST_NAME));
values.put(KEY_WATCHLIST_POSITION, rawValues.getString(KEY_WATCHLIST_POSITION));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting transaction");
}
db.insert(TABLE_MANUAL_CURRENCIES, null, values);
db.close();
}
public void addRowTransaction(JSONObject rawValues, Context context, boolean decrypt)

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/summary_background"/>
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
</shape>
</item>
</selector>

View File

@ -13,35 +13,31 @@
android:id="@+id/textViewFilePath"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Click to select"
android:background="@drawable/background_filepath"/>
<CheckBox
android:id="@+id/checkboxWipeData"
android:id="@+id/checkboxBackupManualEntries"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_data"
android:enabled="false" />
android:text="@string/backup_manual_entries" />
<CheckBox
android:id="@+id/checkboxRestoreEntries"
android:id="@+id/checkboxBackupWatchlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_manual_entries"
android:enabled="false" />
android:text="@string/backup_watchlist" />
<CheckBox
android:id="@+id/checkboxRestoreKeys"
android:id="@+id/checkboxBackupKeys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_keys"
android:enabled="false" />
android:text="@string/backup_keys" />
<CheckBox
android:id="@+id/checkboxEnterPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/enter_password"/>
android:text="@string/enter_password" />
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputLayoutPassword"

View File

@ -13,28 +13,49 @@
android:id="@+id/textViewFilePath"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Click to select"
android:background="@drawable/background_filepath"/>
<CheckBox
android:id="@+id/checkboxWipeData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_data"/>
<CheckBox
android:id="@+id/checkboxRestoreEntries"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_manual_entries"
android:enabled="false" />
android:text="@string/restore_manual_entries"/>
<CheckBox
android:id="@+id/checkboxWipeManualEntries"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_manual_entries"
android:layout_marginStart="10dp"
android:visibility="gone"/>
<CheckBox
android:id="@+id/checkboxRestoreWatchlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_watchlist"/>
<CheckBox
android:id="@+id/checkboxWipeWatchlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_watchlist"
android:layout_marginStart="10dp"
android:visibility="gone"/>
<CheckBox
android:id="@+id/checkboxRestoreKeys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_keys"
android:enabled="false" />
android:text="@string/restore_keys"/>
<CheckBox
android:id="@+id/checkboxWipeAPIKeys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_api_keys"
android:layout_marginStart="10dp"
android:visibility="gone"/>
<CheckBox
android:id="@+id/checkboxEnterPassword"

View File

@ -4,48 +4,43 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background">
android:layout_height="?attr/actionBarSize"
android:background="@drawable/gradient_background"
app:layout_collapseMode="pin"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
android:layout_margin="10dp">
<FrameLayout
android:layout_width="match_parent"
<ImageButton
android:id="@+id/drawer_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
android:layout_margin="10dp">
android:text="@string/action_settings"
android:background="@drawable/ic_drawer_white_24dp"
android:visibility="visible"
android:layout_gravity="start|center_vertical"
android:contentDescription="@string/drawer"/>
<ImageButton
android:id="@+id/drawer_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_settings"
android:background="@drawable/ic_drawer_white_24dp"
android:visibility="visible"
android:layout_gravity="start|center_vertical"
android:contentDescription="@string/drawer"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/title_market_cap"
android:textSize="18sp"
android:textColor="@color/white"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/title_market_cap"
android:textSize="18sp"
android:textColor="@color/white"
android:textStyle="bold"/>
</FrameLayout>
</FrameLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshmarketcap"
@ -53,13 +48,14 @@
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/summary_background">
android:background="@drawable/gradient_background">
<LinearLayout android:id="@+id/layoutMarketCap"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="20dp">
android:paddingTop="20dp"
android:background="@drawable/list_background">
<ProgressBar
android:id="@+id/progressBarMarketCap"

View File

@ -4,54 +4,48 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background">
android:layout_height="?attr/actionBarSize"
android:background="@drawable/gradient_background"
app:layout_collapseMode="pin">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
android:layout_margin="10dp">
<FrameLayout
android:layout_width="match_parent"
<ImageButton
android:id="@+id/drawer_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
android:layout_margin="10dp">
android:text="@string/action_settings"
android:background="@drawable/ic_drawer_white_24dp"
android:visibility="visible"
android:layout_gravity="start|center_vertical"
android:contentDescription="@string/drawer"/>
<ImageButton
android:id="@+id/drawer_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_settings"
android:background="@drawable/ic_drawer_white_24dp"
android:visibility="visible"
android:layout_gravity="start|center_vertical"
android:contentDescription="@string/drawer"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/title_coin_list"
android:textSize="18sp"
android:textColor="@color/white"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/title_coin_list"
android:textSize="18sp"
android:textColor="@color/white"
android:textStyle="bold"/>
</FrameLayout>
</FrameLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</android.support.v7.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:background="@color/summary_background">
android:background="@drawable/gradient_background">
<ListView android:id="@+id/linearLayoutOverview"
android:layout_width="match_parent"
@ -61,7 +55,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:divider="@null"
android:dividerHeight="0dp"
android:clipChildren="false"/>
android:clipChildren="false"
android:background="@drawable/list_background"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -5,14 +5,16 @@
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.herbron.moodl.Activities.HomeActivity">
tools:context="com.herbron.moodl.Activities.HomeActivity"
android:background="@drawable/gradient_background">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:theme="@style/AppTheme.AppBarOverlay"
android:background="@drawable/gradient_background">
android:background="@drawable/gradient_background"
app:elevation="0dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
@ -70,13 +72,13 @@
android:id="@+id/swiperefreshsummary"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/summary_background">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.widget.NestedScrollView
android:id="@+id/nestedScrollViewLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@drawable/list_background">
<LinearLayout
android:layout_width="match_parent"

View File

@ -4,58 +4,53 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background">
android:layout_height="?attr/actionBarSize"
android:background="@drawable/gradient_background"
app:layout_collapseMode="pin"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
android:layout_margin="10dp">
<FrameLayout
android:layout_width="match_parent"
<ImageButton
android:id="@+id/drawer_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
android:layout_margin="10dp">
android:text="@string/action_settings"
android:background="@drawable/ic_drawer_white_24dp"
android:visibility="visible"
android:layout_gravity="start|center_vertical"
android:contentDescription="@string/drawer"/>
<ImageButton
android:id="@+id/drawer_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_settings"
android:background="@drawable/ic_drawer_white_24dp"
android:visibility="visible"
android:layout_gravity="start|center_vertical"
android:contentDescription="@string/drawer"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/title_watchlist"
android:textSize="18sp"
android:textColor="@color/white"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/title_watchlist"
android:textSize="18sp"
android:textColor="@color/white"
android:textStyle="bold"/>
<ImageButton
android:id="@+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_edit_mode"
android:background="@drawable/ic_mode_edit_white_24dp"
android:visibility="visible"
android:layout_gravity="end|center_vertical"
android:contentDescription="@string/edit_mode"/>
<ImageButton
android:id="@+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_edit_mode"
android:background="@drawable/ic_mode_edit_white_24dp"
android:visibility="visible"
android:layout_gravity="end|center_vertical"
android:contentDescription="@string/edit_mode"/>
</FrameLayout>
</FrameLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshwatchlist"
@ -63,12 +58,13 @@
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/summary_background">
android:background="@drawable/gradient_background">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
android:overScrollMode="never"
android:background="@drawable/list_background">
<LinearLayout
android:layout_width="match_parent"

View File

@ -131,4 +131,12 @@
<string name="wrong_password">Mauvais mot de passe</string>
<string name="error">Erreur</string>
<string name="wrong_fingerprint">Mauvaise empreinte digitale</string>
<string name="backup_manual_entries">Sauvegarder les entrées manuelles</string>
<string name="backup_watchlist">Sauvegarder la liste suivie</string>
<string name="backup_keys">Sauvegarder les clefs API</string>
<string name="must_be_filled">Ne peut pas être vide</string>
<string name="restore_watchlist">Restaurer la liste suivie</string>
<string name="wipe_manual_entries">Supprimer les entrées manuelles actuelles</string>
<string name="wipe_watchlist">Supprimer la liste suivie actuelle</string>
<string name="wipe_api_keys">Supprimer les clefs API actuelles</string>
</resources>

View File

@ -151,6 +151,12 @@
<item>1 year</item>
</string-array>
<string-array name="wipe_options_string_array">
<item>Manual entries</item>
<item>Watchlist</item>
<item>API keys</item>
</string-array>
<!--Cardview placeholders-->
<string name="currencySymbolPlaceholder" translatable="false">(%1$s)</string>
<string name="currencyBalancePlaceholder" translatable="false">%1$s%2$s</string>
@ -235,5 +241,13 @@
<string name="wrong_password">Wrong password</string>
<string name="error">Error</string>
<string name="wrong_fingerprint">Wrong fingerprint</string>
<string name="backup_manual_entries">Backup manual entries</string>
<string name="backup_watchlist">Backup watchlist</string>
<string name="backup_keys">Backup API keys</string>
<string name="must_be_filled">Cannot be blank</string>
<string name="restore_watchlist">Restore watchlist</string>
<string name="wipe_manual_entries">Wipe current entries</string>
<string name="wipe_watchlist">Wipe current watchlist</string>
<string name="wipe_api_keys">Wipe current API keys</string>
</resources>