- Prepare RecordTransactionActivity rework
- Lock Touch ID if not supported/not configured
- Prepare API storage rework
- Fix CurrencyTickerList and CurrencyDetailsList crash
-
This commit is contained in:
Tanguy Herbron 2018-07-31 01:48:03 +02:00
parent 1c670d6e5d
commit 93f0a700fb
10 changed files with 228 additions and 103 deletions

View File

@ -40,6 +40,7 @@ import com.daasuu.ei.Ease;
import com.daasuu.ei.EasingInterpolator; import com.daasuu.ei.EasingInterpolator;
import com.herbron.moodl.Activities.CurrencySelectionActivity; import com.herbron.moodl.Activities.CurrencySelectionActivity;
import com.herbron.moodl.Activities.HomeActivity; import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.Activities.RecordTransactionActivity;
import com.herbron.moodl.BalanceUpdateInterface; import com.herbron.moodl.BalanceUpdateInterface;
import com.herbron.moodl.DataManagers.BalanceManager; import com.herbron.moodl.DataManagers.BalanceManager;
import com.herbron.moodl.DataManagers.CurrencyData.Currency; import com.herbron.moodl.DataManagers.CurrencyData.Currency;
@ -180,6 +181,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface,
refreshLayout.setRefreshing(false); refreshLayout.setRefreshing(false);
showErrorSnackbar(); showErrorSnackbar();
Log.d("moodl", "Error > Refresh out of time");
} }
if (loadingDialog.isShowing()) if (loadingDialog.isShowing())
@ -187,6 +189,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface,
loadingDialog.dismiss(); loadingDialog.dismiss();
showErrorSnackbar(); showErrorSnackbar();
Log.d("moodl", "Error > Refresh out of time");
} }
} }
}; };
@ -242,7 +245,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface,
addCurrencyButton.setOnClickListener(new View.OnClickListener() { addCurrencyButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Intent addIntent = new Intent(getActivity(), CurrencySelectionActivity.class); Intent addIntent = new Intent(getActivity(), RecordTransactionActivity.class);
startActivity(addIntent); startActivity(addIntent);
} }

View File

@ -4,6 +4,8 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -47,6 +49,8 @@ public class RecordTransactionActivity extends AppCompatActivity {
private Currency currency; private Currency currency;
private int transactionId; private int transactionId;
private SearchView mainSearchView;
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
@ -54,7 +58,7 @@ public class RecordTransactionActivity extends AppCompatActivity {
return true; return true;
} }
@Override /*@Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_record: case R.id.action_record:
@ -94,7 +98,7 @@ public class RecordTransactionActivity extends AppCompatActivity {
break; break;
} }
return true; return true;
} }*/
private boolean checkPriceText() private boolean checkPriceText()
{ {
@ -160,14 +164,18 @@ public class RecordTransactionActivity extends AppCompatActivity {
databaseManager = new DatabaseManager(this); databaseManager = new DatabaseManager(this);
preferenceManager = new PreferencesManager(this); preferenceManager = new PreferencesManager(this);
initializeViewElements(); //initializeViewElements();
coin = intent.getStringExtra("coin"); coin = intent.getStringExtra("coin");
symbol = intent.getStringExtra("symbol"); symbol = intent.getStringExtra("symbol");
transactionId = intent.getIntExtra("transactionId", -1); transactionId = intent.getIntExtra("transactionId", -1);
if(transactionId != -1) Toolbar toolbar = findViewById(R.id.searchCurrencyToolbar);
setSupportActionBar(toolbar);
/*if(transactionId != -1)
{ {
setTitle(PlaceholderManager.getEditTransactionString(coin, getBaseContext())); setTitle(PlaceholderManager.getEditTransactionString(coin, getBaseContext()));
@ -206,17 +214,17 @@ public class RecordTransactionActivity extends AppCompatActivity {
} }
}); });
initializeButtons(); //initializeButtons();
currency.getTimestampPrice(this, preferenceManager.getDefaultCurrency(), new Currency.PriceCallBack() { currency.getTimestampPrice(this, preferenceManager.getDefaultCurrency(), new Currency.PriceCallBack() {
@Override @Override
public void onSuccess(String price) { public void onSuccess(String price) {
purchasedPriceEditText.setText(price); purchasedPriceEditText.setText(price);
} }
}, calendar.getTimeInMillis() / 1000); }, calendar.getTimeInMillis() / 1000);*/
} }
private void initializeButtons() /*private void initializeButtons()
{ {
buyButton.setOnClickListener(new View.OnClickListener() { buyButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -262,7 +270,7 @@ public class RecordTransactionActivity extends AppCompatActivity {
buyButton = findViewById(R.id.buyButton); buyButton = findViewById(R.id.buyButton);
sellButton = findViewById(R.id.sellButton); sellButton = findViewById(R.id.sellButton);
transferButton = findViewById(R.id.transfertButton); transferButton = findViewById(R.id.transfertButton);
} }*/
private void createDatePicker() private void createDatePicker()
{ {

View File

@ -288,57 +288,58 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
{ {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext()); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext());
FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance(); FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance();
SwitchPreference touchdIdSwitch = (SwitchPreference) findPreference("enable_fingerprint");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
keyguardManager = (KeyguardManager) this.getActivity().getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) this.getActivity().getSystemService(FINGERPRINT_SERVICE);
try {
if(!fingerprintManager.isHardwareDetected())
{
touchdIdSwitch.setEnabled(false);
}
if(ActivityCompat.checkSelfPermission(this.getContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
{
touchdIdSwitch.setEnabled(false);
}
if(!fingerprintManager.hasEnrolledFingerprints())
{
touchdIdSwitch.setEnabled(false);
}
if(!keyguardManager.isKeyguardSecure())
{
touchdIdSwitch.setEnabled(false);
}
else
{
try {
generateKey();
} catch (FingerprintException e) {
e.printStackTrace();
}
if(initCipher())
{
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this.getContext(), newFragment);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
if(preferences.getBoolean("enable_fingerprint", false)) if(preferences.getBoolean("enable_fingerprint", false))
{ {
newFragment.setCancelable(false); newFragment.setCancelable(false);
newFragment.show(getFragmentManager(), "dialog"); newFragment.show(getFragmentManager(), "dialog");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
keyguardManager = (KeyguardManager) this.getActivity().getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) this.getActivity().getSystemService(FINGERPRINT_SERVICE);
try {
if(!fingerprintManager.isHardwareDetected())
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(ActivityCompat.checkSelfPermission(this.getContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(!fingerprintManager.hasEnrolledFingerprints())
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(!keyguardManager.isKeyguardSecure())
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
else
{
try {
generateKey();
} catch (FingerprintException e) {
e.printStackTrace();
}
if(initCipher())
{
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this.getContext(), newFragment);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
} }
} }
@ -720,9 +721,29 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
for(int i = 0; i < watchlistArray.length(); i++) for(int i = 0; i < watchlistArray.length(); i++)
{ {
JSONObject transactionObject = watchlistArray.getJSONObject(i); JSONObject watchlistObject = watchlistArray.getJSONObject(i);
databaseManager.addRowWatchlist(transactionObject, getContext(), enterPasswordCheckbox.isChecked()); databaseManager.addRowWatchlist(watchlistObject, getContext(), enterPasswordCheckbox.isChecked());
}
}
}
if(restoreApiKeysCheckbox.isChecked())
{
if(wipeApiKeyxCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_EXCHANGE_KEYS);
}
if(backupJson.has("apiKeys"))
{
JSONArray apiArray = backupJson.getJSONArray("apiKeys");
for(int i = 0; i < apiArray.length(); i++)
{
JSONObject apiKeysObject = apiArray.getJSONObject(i);
databaseManager.addRowApiKeys(apiKeysObject, getContext(), enterPasswordCheckbox.isChecked());
} }
} }
} }

View File

@ -96,25 +96,13 @@ public class BalanceManager {
public void updateExchangeKeys() public void updateExchangeKeys()
{ {
String publicKey = preferenceManager.getHitBTCPublicKey();
String privateKey = preferenceManager.getHitBTCPrivateKey();
hitBtcManagers.clear(); hitBtcManagers.clear();
if(preferenceManager.isHitBTCActivated() && publicKey != null && privateKey != null) hitBtcManagers = databaseManager.getHitBtcAccounts(context);
{
hitBtcManagers.add(new HitBtcManager(context, publicKey, privateKey));
}
publicKey = preferenceManager.getBinancePublicKey();
privateKey = preferenceManager.getBinancePrivateKey();
binanceManagers.clear(); binanceManagers.clear();
if(preferenceManager.isBinanceActivated() && publicKey != null && privateKey != null) binanceManagers = databaseManager.getBinanceAccounts();
{
binanceManagers.add(new BinanceManager(publicKey, privateKey));
}
} }
public List<Currency> getTotalBalance() public List<Currency> getTotalBalance()

View File

@ -71,6 +71,11 @@ public class CurrencyDetailsList {
public boolean isUpToDate() public boolean isUpToDate()
{ {
if(coinInfosHashmap == null)
{
upToDate = false;
}
return upToDate; return upToDate;
} }

View File

@ -49,6 +49,11 @@ public class CurrencyTickerList {
public boolean isUpToDate() public boolean isUpToDate()
{ {
if(currencyTickerList == null)
{
upToDate = false;
}
return upToDate; return upToDate;
} }

View File

@ -9,13 +9,17 @@ import android.util.Log;
import com.herbron.moodl.DataManagers.CurrencyData.Currency; import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction; import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.ExchangeManager.BinanceManager;
import com.herbron.moodl.DataManagers.ExchangeManager.HitBtcManager;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Iterator;
import java.util.List; import java.util.List;
/** /**
@ -24,7 +28,7 @@ import java.util.List;
public class DatabaseManager extends SQLiteOpenHelper{ public class DatabaseManager extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 7; private static final int DATABASE_VERSION = 8;
private static final String DATABASE_NAME = "Currencies.db"; private static final String DATABASE_NAME = "Currencies.db";
@ -43,6 +47,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
private static final String KEY_EXCHANGE_ID = "idExchange"; private static final String KEY_EXCHANGE_ID = "idExchange";
private static final String KEY_EXCHANGE_NAME = "name"; private static final String KEY_EXCHANGE_NAME = "name";
private static final String KEY_EXCHANGE_TYPE = "type";
private static final String KEY_EXCHANGE_DESCRIPTION = "description"; private static final String KEY_EXCHANGE_DESCRIPTION = "description";
private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey"; private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey";
private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey"; private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey";
@ -52,6 +57,9 @@ public class DatabaseManager extends SQLiteOpenHelper{
private static final String KEY_WATCHLIST_NAME = "name"; private static final String KEY_WATCHLIST_NAME = "name";
private static final String KEY_WATCHLIST_POSITION = "position"; private static final String KEY_WATCHLIST_POSITION = "position";
private static final int BINANCE_TYPE = 0;
private static final int HITBTC_TYPE = 1;
public DatabaseManager(Context context) public DatabaseManager(Context context)
{ {
super(context, DATABASE_NAME, null, DATABASE_VERSION); super(context, DATABASE_NAME, null, DATABASE_VERSION);
@ -73,6 +81,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_EXCHANGE_KEYS + "(" db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_EXCHANGE_KEYS + "("
+ KEY_EXCHANGE_ID + " INTEGER PRIMARY KEY," + KEY_EXCHANGE_ID + " INTEGER PRIMARY KEY,"
+ KEY_EXCHANGE_TYPE + " INTEGER,"
+ KEY_EXCHANGE_NAME + " TEXT," + KEY_EXCHANGE_NAME + " TEXT,"
+ KEY_EXCHANGE_DESCRIPTION + " TEXT," + KEY_EXCHANGE_DESCRIPTION + " TEXT,"
+ KEY_EXCHANGE_PUBLIC_KEY + " TEXT," + KEY_EXCHANGE_PUBLIC_KEY + " TEXT,"
@ -96,7 +105,10 @@ public class DatabaseManager extends SQLiteOpenHelper{
{ {
case 6: case 6:
db.execSQL("ALTER TABLE " + TABLE_EXCHANGE_KEYS db.execSQL("ALTER TABLE " + TABLE_EXCHANGE_KEYS
+ " ADD " + KEY_EXCHANGE_DESCRIPTION+ " VARCHAR"); + " ADD " + KEY_EXCHANGE_DESCRIPTION + " TEXT");
case 7:
db.execSQL("ALTER TABLE " + TABLE_EXCHANGE_KEYS
+ " ADD " + KEY_EXCHANGE_TYPE + " INTEGER");
} }
} }
@ -198,6 +210,9 @@ public class DatabaseManager extends SQLiteOpenHelper{
backupArray.put(backupObject); backupArray.put(backupObject);
} }
result.close();
db.close();
return backupArray; return backupArray;
} }
@ -207,6 +222,49 @@ public class DatabaseManager extends SQLiteOpenHelper{
db.execSQL("DELETE FROM "+ table); db.execSQL("DELETE FROM "+ table);
} }
public void addRawData(Context context, JSONObject rawValues, String table, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
while(rawValues.keys().hasNext())
{
String key = rawValues.keys().next();
try {
if(decrypt)
{
values.put(key, DataCrypter.decrypt(context, rawValues.getString(key)));
}
else
{
values.put(key, rawValues.getString(key));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting " + key + " " + e.getMessage());
}
}
db.insert(table, null, values);
db.close();
}
public void addRowApiKeys(JSONObject rawValues, Context context, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
try {
if(decrypt)
{
values.put(KEY_EXCHANGE_NAME, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_SYMBOL)));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting api key " + e.getMessage());
}
}
public void addRowWatchlist(JSONObject rawValues, Context context, boolean decrypt) public void addRowWatchlist(JSONObject rawValues, Context context, boolean decrypt)
{ {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
@ -226,10 +284,10 @@ public class DatabaseManager extends SQLiteOpenHelper{
values.put(KEY_WATCHLIST_POSITION, rawValues.getString(KEY_WATCHLIST_POSITION)); values.put(KEY_WATCHLIST_POSITION, rawValues.getString(KEY_WATCHLIST_POSITION));
} }
} catch (JSONException e) { } catch (JSONException e) {
Log.d("moodl", "Error while inserting transaction"); Log.d("moodl", "Error while inserting watchlist " + e.getMessage());
} }
db.insert(TABLE_MANUAL_CURRENCIES, null, values); db.insert(TABLE_WATCHLIST, null, values);
db.close(); db.close();
} }
@ -260,7 +318,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
values.put(KEY_CURRENCY_FEES, rawValues.getString(KEY_CURRENCY_FEES)); values.put(KEY_CURRENCY_FEES, rawValues.getString(KEY_CURRENCY_FEES));
} }
} catch (JSONException e) { } catch (JSONException e) {
Log.d("moodl", "Error while inserting transaction"); Log.d("moodl", "Error while inserting transaction " + e.getMessage());
} }
db.insert(TABLE_MANUAL_CURRENCIES, null, values); db.insert(TABLE_MANUAL_CURRENCIES, null, values);
@ -280,22 +338,48 @@ public class DatabaseManager extends SQLiteOpenHelper{
currencyList.add(new Currency(resultList.getString(2), resultList.getString(1))); currencyList.add(new Currency(resultList.getString(2), resultList.getString(1)));
} }
resultList.close();
db.close();
return currencyList; return currencyList;
} }
public void addCurrencyToManualCurrency(String symbol, double balance, Date date, double purchasedPrice, double fees) public List<HitBtcManager> getHitBtcAccounts(Context context)
{ {
String searchQuerry = "SELECT * FROM " + TABLE_EXCHANGE_KEYS + " WHERE " + KEY_EXCHANGE_TYPE + "='" + HITBTC_TYPE + "'";
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues(); Cursor resultList = db.rawQuery(searchQuerry, null);
values.put(KEY_CURRENCY_SYMBOL, symbol); List<HitBtcManager> accountList = new ArrayList<>();
values.put(KEY_CURRENCY_BALANCE, balance);
values.put(KEY_CURRENCY_DATE, date.getTime());
values.put(KEY_CURRENCY_PURCHASED_PRICE, purchasedPrice);
values.put(KEY_CURRENCY_FEES, fees);
db.insert(TABLE_MANUAL_CURRENCIES, null, values); while(resultList.moveToNext())
{
accountList.add(new HitBtcManager(context, resultList.getString(4), resultList.getString(5)));
}
resultList.close();
db.close(); db.close();
return accountList;
}
public List<BinanceManager> getBinanceAccounts()
{
String searchQuerry = "SELECT * FROM " + TABLE_EXCHANGE_KEYS + " WHERE " + KEY_EXCHANGE_TYPE + "='" + BINANCE_TYPE + "'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor resultList = db.rawQuery(searchQuerry, null);
List<BinanceManager> accountList = new ArrayList<>();
while(resultList.moveToNext())
{
accountList.add(new BinanceManager(resultList.getString(4), resultList.getString(5)));
}
resultList.close();
db.close();
return accountList;
} }
public List<Currency> getAllCurrenciesFromManualCurrency() public List<Currency> getAllCurrenciesFromManualCurrency()

View File

@ -48,6 +48,16 @@ public class PreferencesManager {
return settingPreferences.getString("hitbtc_privatekey", null); return settingPreferences.getString("hitbtc_privatekey", null);
} }
public String getBinancePublicKey()
{
return settingPreferences.getString("binance_publickey", null);
}
public String getBinancePrivateKey()
{
return settingPreferences.getString("binance_privatekey", null);
}
public boolean isHitBTCActivated() public boolean isHitBTCActivated()
{ {
return settingPreferences.getBoolean("enable_hitbtc", false); return settingPreferences.getBoolean("enable_hitbtc", false);
@ -74,16 +84,6 @@ public class PreferencesManager {
editor.apply(); editor.apply();
} }
public String getBinancePublicKey()
{
return settingPreferences.getString("binance_publickey", null);
}
public String getBinancePrivateKey()
{
return settingPreferences.getString("binance_privatekey", null);
}
public boolean isBinanceActivated() public boolean isBinanceActivated()
{ {
return settingPreferences.getBoolean("enable_binance", false); return settingPreferences.getBoolean("enable_binance", false);

View File

@ -3,15 +3,24 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.herbron.moodl.Activities.RecordTransactionActivity"> tools:context="com.herbron.moodl.Activities.RecordTransactionActivity">
<LinearLayout <android.support.v7.widget.Toolbar
android:id="@+id/searchCurrencyToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark" />
</LinearLayout> <ListView
android:id="@+id/listViewCurrencySelection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"/>
<LinearLayout <!--<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
@ -121,6 +130,6 @@
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
</LinearLayout> </LinearLayout>-->
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -2,9 +2,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_record" <item
android:icon="@drawable/ic_send_white_24dp" android:id="@+id/action_search"
android:title="@string/transaction_record" android:icon="@android:drawable/ic_menu_search"
app:showAsAction="always"/> android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView" />
</menu> </menu>