From 9dff26d0355ea9d0cdc60c518a1638c449b9ce84 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 13 Jun 2020 12:33:48 +0200 Subject: [PATCH] Improved settings search --- .../eu/faircode/email/FragmentOptions.java | 128 ++++++++++++------ 1 file changed, 86 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index 3ca8744e89..d1bce634af 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -28,6 +28,7 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.database.MatrixCursor; import android.os.Bundle; +import android.text.TextUtils; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; @@ -44,6 +45,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.SearchView; import androidx.constraintlayout.widget.Group; +import androidx.cursoradapter.widget.CursorAdapter; import androidx.cursoradapter.widget.SimpleCursorAdapter; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -58,6 +60,20 @@ import com.google.android.material.tabs.TabLayout; public class FragmentOptions extends FragmentBase { private ViewPager pager; private PagerAdapter adapter; + private String searching = null; + + private static int[] TAB_PAGES = { + R.layout.fragment_setup, + R.layout.fragment_options_synchronize, + R.layout.fragment_options_send, + R.layout.fragment_options_connection, + R.layout.fragment_options_display, + R.layout.fragment_options_behavior, + R.layout.fragment_options_privacy, + R.layout.fragment_options_encryption, + R.layout.fragment_options_notifications, + R.layout.fragment_options_misc + }; static String[] OPTIONS_RESTART = new String[]{ "first", "app_support", "notify_archive", "message_swipe", "message_select", "folder_actions", "folder_sync", @@ -78,12 +94,21 @@ public class FragmentOptions extends FragmentBase { "biometrics" }; + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putString("fair:searching", searching); + super.onSaveInstanceState(outState); + } + @Override @Nullable public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_options, container, false); setHasOptionsMenu(true); + if (savedInstanceState != null) + searching = savedInstanceState.getString("fair:searching"); + pager = view.findViewById(R.id.pager); adapter = new PagerAdapter(getChildFragmentManager()); pager.setAdapter(adapter); @@ -157,12 +182,13 @@ public class FragmentOptions extends FragmentBase { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_setup, menu); + final String saved = searching; final MenuItem menuSearch = menu.findItem(R.id.menu_search); final SearchView searchView = (SearchView) menuSearch.getActionView(); searchView.setQueryHint(getString(R.string.title_search)); - searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { + final SearchView.OnSuggestionListener onSuggestionListener = new SearchView.OnSuggestionListener() { @Override public boolean onSuggestionSelect(int position) { return false; @@ -171,46 +197,58 @@ public class FragmentOptions extends FragmentBase { @Override public boolean onSuggestionClick(int position) { Cursor cursor = searchView.getSuggestionsAdapter().getCursor(); - cursor.moveToPosition(position); - int id = cursor.getInt(cursor.getColumnIndex("_id")); - int tab = cursor.getInt(cursor.getColumnIndex("tab")); - pager.setCurrentItem(tab); - FragmentBase fragment = (FragmentBase) adapter.instantiateItem(pager, tab); - fragment.scrollTo(id); - menuSearch.collapseActionView(); + if (cursor != null && cursor.moveToPosition(position)) { + int tab = cursor.getInt(cursor.getColumnIndex("tab")); + int resid = cursor.getInt(cursor.getColumnIndex("resid")); + + pager.setCurrentItem(tab); + FragmentBase fragment = (FragmentBase) adapter.instantiateItem(pager, tab); + fragment.scrollTo(resid); + menuSearch.collapseActionView(); + } return true; } - }); + }; + + searchView.setOnSuggestionListener(onSuggestionListener); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - private int[] tabs = { - R.layout.fragment_setup, - R.layout.fragment_options_synchronize, - R.layout.fragment_options_send, - R.layout.fragment_options_connection, - R.layout.fragment_options_display, - R.layout.fragment_options_behavior, - R.layout.fragment_options_privacy, - R.layout.fragment_options_encryption, - R.layout.fragment_options_notifications, - R.layout.fragment_options_misc - }; + private View[] views = null; @Override public boolean onQueryTextSubmit(String query) { + searching = query; + + CursorAdapter adapter = searchView.getSuggestionsAdapter(); + if (adapter != null && adapter.getCount() > 0) + onSuggestionListener.onSuggestionClick(0); + return false; } @Override public boolean onQueryTextChange(String newText) { - MatrixCursor cursor = new MatrixCursor(new String[]{"_id", "tab", "title"}); + searching = newText; + suggest(newText); + return false; + } - if (newText != null && newText.length() > 2) { - LayoutInflater inflater = LayoutInflater.from(searchView.getContext()); - for (int tab = 0; tab < tabs.length; tab++) - getSuggestions(newText.toLowerCase(), tab, inflater.inflate(tabs[tab], null), cursor); + private void suggest(String query) { + MatrixCursor cursor = new MatrixCursor(new String[]{"_id", "tab", "resid", "title"}); + + if (query != null && query.length() > 1) { + if (views == null) { + views = new View[TAB_PAGES.length]; + LayoutInflater inflater = LayoutInflater.from(searchView.getContext()); + for (int tab = 0; tab < TAB_PAGES.length; tab++) + views[tab] = inflater.inflate(TAB_PAGES[tab], null); + } + + int id = 0; + for (int tab = 0; tab < TAB_PAGES.length; tab++) + id = getSuggestions(query.toLowerCase(), id, tab, views[tab], cursor); } searchView.setSuggestionsAdapter(new SimpleCursorAdapter( @@ -221,27 +259,33 @@ public class FragmentOptions extends FragmentBase { new int[]{android.R.id.text1}, 0 )); + } - return false; + private int getSuggestions(String query, int id, int tab, View view, MatrixCursor cursor) { + if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + for (int i = 0; i <= group.getChildCount(); i++) + id = getSuggestions(query, id, tab, group.getChildAt(i), cursor); + } else if (view instanceof TextView) { + String text = ((TextView) view).getText().toString(); + if (text.toLowerCase().contains(query)) + cursor.newRow() + .add(id++) + .add(tab) + .add(view.getId()) + .add(text); + } + + return id; } }); - super.onCreateOptionsMenu(menu, inflater); - } - - private void getSuggestions(String query, int tab, View view, MatrixCursor cursor) { - if (view instanceof ViewGroup) { - ViewGroup group = (ViewGroup) view; - for (int i = 0; i <= group.getChildCount(); i++) - getSuggestions(query, tab, group.getChildAt(i), cursor); - } else if (view instanceof TextView) { - String text = ((TextView) view).getText().toString(); - if (text.toLowerCase().contains(query)) - cursor.newRow() - .add("_id", view.getId()) - .add("tab", tab) - .add("title", text); + if (!TextUtils.isEmpty(saved)) { + menuSearch.expandActionView(); + searchView.setQuery(saved, false); } + + super.onCreateOptionsMenu(menu, inflater); } @Override