mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-04-10 18:37:57 -04:00
Refactoring of Search Behavior: Restoring of Previous Search Query After Coming Back from Card Interaction or Screen Rotation on Search
This commit is contained in:
@@ -54,6 +54,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
public static final String RESTART_ACTIVITY_INTENT = "restart_activity_intent";
|
||||
|
||||
private static final int MEDIUM_SCALE_FACTOR_DIP = 460;
|
||||
static final String STATE_SEARCH_QUERY = "SEARCH_QUERY";
|
||||
|
||||
private SQLiteDatabase mDatabase;
|
||||
private LoyaltyCardCursorAdapter mAdapter;
|
||||
@@ -61,6 +62,8 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
private SearchView mSearchView;
|
||||
private int mLoyaltyCardCount = 0;
|
||||
protected String mFilter = "";
|
||||
private String currentQuery = "";
|
||||
private String finalQuery = "";
|
||||
protected Object mGroup = null;
|
||||
protected DBHelper.LoyaltyCardOrder mOrder = DBHelper.LoyaltyCardOrder.Alpha;
|
||||
protected DBHelper.LoyaltyCardOrderDirection mOrderDirection = DBHelper.LoyaltyCardOrderDirection.Ascending;
|
||||
@@ -70,9 +73,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
private View mNoMatchingCardsText;
|
||||
private View mNoGroupCardsText;
|
||||
private TabLayout groupsTabLayout;
|
||||
|
||||
private Runnable mUpdateLoyaltyCardListRunnable;
|
||||
|
||||
private ActivityResultLauncher<Intent> mBarcodeScannerLauncher;
|
||||
private ActivityResultLauncher<Intent> mSettingsLauncher;
|
||||
|
||||
@@ -199,7 +200,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
protected void onCreate(Bundle inputSavedInstanceState) {
|
||||
SplashScreen.installSplashScreen(this);
|
||||
super.onCreate(inputSavedInstanceState);
|
||||
|
||||
// We should extract the share intent after we called the super.onCreate as it may need to spawn a dialog window and the app needs to be initialized to not crash
|
||||
extractIntentFields(getIntent());
|
||||
|
||||
@@ -298,7 +298,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
if (mSearchView != null && !mSearchView.isIconified()) {
|
||||
mFilter = mSearchView.getQuery().toString();
|
||||
}
|
||||
|
||||
// Start of active tab logic
|
||||
updateTabGroups(groupsTabLayout);
|
||||
|
||||
@@ -513,6 +512,24 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
// Saving currentQuery to finalQuery for user, this will be used to restore search history, happens when user clicks a card from list
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
finalQuery = currentQuery;
|
||||
// Putting the query also into outState for later use in onRestoreInstanceState when rotating screen
|
||||
if (mSearchView != null) {
|
||||
outState.putString(STATE_SEARCH_QUERY, finalQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// Restoring instance state when rotation of screen happens with the goal to restore search query for user
|
||||
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
finalQuery = savedInstanceState.getString(STATE_SEARCH_QUERY, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu inputMenu) {
|
||||
getMenuInflater().inflate(R.menu.main_menu, inputMenu);
|
||||
@@ -525,7 +542,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
mSearchView = (SearchView) searchMenuItem.getActionView();
|
||||
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
|
||||
mSearchView.setSubmitButtonEnabled(false);
|
||||
|
||||
mSearchView.setOnCloseListener(() -> {
|
||||
invalidateOptionsMenu();
|
||||
return false;
|
||||
@@ -550,6 +566,9 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
mSearchView.clearFocus();
|
||||
return false;
|
||||
}
|
||||
currentQuery = "";
|
||||
mFilter = "";
|
||||
updateLoyaltyCardList(false);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -564,7 +583,21 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
mFilter = newText;
|
||||
|
||||
// New logic to ensure search history after coming back from picked card - user will see the last search query
|
||||
if (newText.isEmpty()) {
|
||||
if(!finalQuery.isEmpty()){
|
||||
// Setting the query text for user after coming back from picked card from finalQuery
|
||||
mSearchView.setQuery(finalQuery, false);
|
||||
}
|
||||
else if(!currentQuery.isEmpty()){
|
||||
// Else if is needed in case user deletes search - expected behaviour is to show all cards
|
||||
currentQuery = "";
|
||||
mSearchView.setQuery(currentQuery, false);
|
||||
}
|
||||
} else {
|
||||
// Setting search query each time user changes the text in search to temporary variable to be used later in finalQuery String which will be used to restore search history
|
||||
currentQuery = newText;
|
||||
}
|
||||
TabLayout.Tab currentTab = groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition());
|
||||
mGroup = currentTab != null ? currentTab.getTag() : null;
|
||||
|
||||
@@ -573,6 +606,14 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// Check if we came from a picked card back to search, in that case we want to show the search view with previous search query
|
||||
if(!finalQuery.isEmpty()){
|
||||
// Expand the search view to show the query
|
||||
searchMenuItem.expandActionView();
|
||||
// Setting the query text to empty String due to behaviour of onQueryTextChange after coming back from picked card - onQueryTextChange is called automatically without users interaction
|
||||
finalQuery = "";
|
||||
mSearchView.setQuery(currentQuery, false);
|
||||
}
|
||||
}
|
||||
|
||||
return super.onCreateOptionsMenu(inputMenu);
|
||||
|
||||
@@ -3,18 +3,22 @@ package protect.card_locker;
|
||||
import static android.os.Looper.getMainLooper;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Color;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
@@ -210,9 +214,12 @@ public class MainActivityTest {
|
||||
|
||||
@Test
|
||||
public void testFiltering() {
|
||||
// FIXME: This test directly sets mFilter instead of using mSearchView, making it not test the search flow correctly
|
||||
// It may falsely succeed or fail, but we're leaving it here so we at least test something instead of nothing
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
MainActivity mainActivity = (MainActivity) activityController.get();
|
||||
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
@@ -244,6 +251,16 @@ public class MainActivityTest {
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
Configuration configuration = mainActivity.getResources().getConfiguration();
|
||||
configuration.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
mainActivity.onConfigurationChanged(configuration);
|
||||
|
||||
configuration.orientation = Configuration.ORIENTATION_PORTRAIT;
|
||||
mainActivity.onConfigurationChanged(configuration);
|
||||
|
||||
configuration.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
mainActivity.onConfigurationChanged(configuration);
|
||||
|
||||
assertEquals(View.GONE, helpSection.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
@@ -337,6 +354,12 @@ public class MainActivityTest {
|
||||
|
||||
mainActivity.mFilter = "second";
|
||||
|
||||
configuration.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
mainActivity.onConfigurationChanged(configuration);
|
||||
|
||||
configuration.orientation = Configuration.ORIENTATION_PORTRAIT;
|
||||
mainActivity.onConfigurationChanged(configuration);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
@@ -371,6 +394,10 @@ public class MainActivityTest {
|
||||
|
||||
mainActivity.mFilter = "company";
|
||||
|
||||
// Rotate to landscape (right)
|
||||
configuration.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
mainActivity.onConfigurationChanged(configuration);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
@@ -443,4 +470,43 @@ public class MainActivityTest {
|
||||
|
||||
database.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchQueryRestorationAfterNavigatingBack() {
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
MainActivity mainActivity = (MainActivity) activityController.get();
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
final Menu menu = shadowOf(Robolectric.setupActivity(MainActivity.class)).getOptionsMenu();
|
||||
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
|
||||
SearchView mSearchView = (SearchView) searchMenuItem.getActionView();
|
||||
|
||||
|
||||
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
|
||||
DBHelper.insertLoyaltyCard(database, "The First Store", "Initial note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
|
||||
DBHelper.insertLoyaltyCard(database, "The Second Store", "Secondary note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
|
||||
|
||||
String finalQuery = "store";
|
||||
assert mSearchView != null;
|
||||
mSearchView.setQuery(finalQuery, false);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
// Simulation of what happens when users comes back after picking up card
|
||||
// We simulate expanding and setting the Query that we want to restore (in code it is from finalQuery String)
|
||||
searchMenuItem.expandActionView();
|
||||
|
||||
mSearchView.setQuery(finalQuery, false);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertTrue(searchMenuItem.isActionViewExpanded());
|
||||
assertEquals("store", mSearchView.getQuery().toString());
|
||||
|
||||
database.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user