implement global search
This commit is contained in:
parent
7c52602036
commit
46f1f687ac
|
@ -221,7 +221,12 @@ public class AppListAdapter extends RecyclerView.Adapter<AppListAdapter.ViewHold
|
|||
void cancelActionMode();
|
||||
}
|
||||
|
||||
// The ORIGINAL list of applications without filtering
|
||||
private List<ApplicationInfoWrapper> mOrigList = new ArrayList<>();
|
||||
// The list of applications that is ACTUALLY displayed
|
||||
// (after filtering by search query if applicable)
|
||||
private List<ApplicationInfoWrapper> mList = new ArrayList<>();
|
||||
private String mSearchQuery = null;
|
||||
private IShelterService mService;
|
||||
private Drawable mDefaultIcon;
|
||||
private String mLabelDisabled;
|
||||
|
@ -281,9 +286,33 @@ public class AppListAdapter extends RecyclerView.Adapter<AppListAdapter.ViewHold
|
|||
}
|
||||
|
||||
void setData(List<ApplicationInfoWrapper> apps) {
|
||||
mOrigList.clear();
|
||||
mList.clear();
|
||||
mIconCache.clear();
|
||||
mList.addAll(apps);
|
||||
mOrigList.addAll(apps);
|
||||
notifyChange();
|
||||
}
|
||||
|
||||
// null = clear search query
|
||||
void setSearchQuery(String query) {
|
||||
mSearchQuery = query;
|
||||
notifyChange();
|
||||
}
|
||||
|
||||
// Call this on ACTUAL data set change and/or search query change
|
||||
private void notifyChange() {
|
||||
mList.clear();
|
||||
if (mSearchQuery == null) {
|
||||
// No search query, do not filter
|
||||
mList.addAll(mOrigList);
|
||||
} else {
|
||||
// Filter by search query
|
||||
mList.addAll(mOrigList.stream()
|
||||
.filter((app) ->
|
||||
app.getPackageName().toLowerCase().contains(mSearchQuery)
|
||||
|| app.getLabel().toLowerCase().contains(mSearchQuery))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,19 @@ public class AppListFragment extends BaseFragment {
|
|||
}
|
||||
};
|
||||
|
||||
// Receiver for search event
|
||||
private BroadcastReceiver mSearchReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String query = intent.getStringExtra("text");
|
||||
if (query == "") {
|
||||
// Consider empty query as null
|
||||
query = null;
|
||||
}
|
||||
mAdapter.setSearchQuery(query);
|
||||
}
|
||||
};
|
||||
|
||||
static AppListFragment newInstance(IShelterService service, boolean isRemote) {
|
||||
AppListFragment fragment = new AppListFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
@ -119,6 +132,9 @@ public class AppListFragment extends BaseFragment {
|
|||
LocalBroadcastManager.getInstance(getContext())
|
||||
.registerReceiver(mContextMenuClosedReceiver,
|
||||
new IntentFilter(MainActivity.BROADCAST_CONTEXT_MENU_CLOSED));
|
||||
LocalBroadcastManager.getInstance(getContext())
|
||||
.registerReceiver(mSearchReceiver,
|
||||
new IntentFilter(MainActivity.BROADCAST_SEARCH_FILTER_CHANGED));
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
@ -130,6 +146,8 @@ public class AppListFragment extends BaseFragment {
|
|||
.unregisterReceiver(mRefreshReceiver);
|
||||
LocalBroadcastManager.getInstance(getContext())
|
||||
.unregisterReceiver(mContextMenuClosedReceiver);
|
||||
LocalBroadcastManager.getInstance(getContext())
|
||||
.unregisterReceiver(mSearchReceiver);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.widget.Toast;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
|
@ -40,6 +41,7 @@ import net.typeblog.shelter.util.Utility;
|
|||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
public static final String BROADCAST_CONTEXT_MENU_CLOSED = "net.typeblog.shelter.broadcast.CONTEXT_MENU_CLOSED";
|
||||
public static final String BROADCAST_SEARCH_FILTER_CHANGED = "net.typeblog.shelter.broadcast.SEARCH_FILTER_CHANGED";
|
||||
|
||||
private static final int REQUEST_PROVISION_PROFILE = 1;
|
||||
private static final int REQUEST_START_SERVICE_IN_WORK_PROFILE = 2;
|
||||
|
@ -330,6 +332,24 @@ public class MainActivity extends AppCompatActivity {
|
|||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.main_activity_menu, menu);
|
||||
|
||||
// Initialize the search button
|
||||
SearchView searchView = (SearchView) menu.findItem(R.id.main_menu_search).getActionView();
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
Intent intent = new Intent(BROADCAST_SEARCH_FILTER_CHANGED);
|
||||
intent.putExtra("text", newText.toLowerCase().trim());
|
||||
LocalBroadcastManager.getInstance(MainActivity.this)
|
||||
.sendBroadcast(intent);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
9
app/src/main/res/drawable/ic_search_tinted_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_search_tinted_24dp.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@color/colorAccent"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||
</vector>
|
|
@ -1,6 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/main_menu_search"
|
||||
android:icon="@drawable/ic_search_tinted_24dp"
|
||||
android:title="@string/search"
|
||||
app:showAsAction="always|collapseActionView"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView" />
|
||||
|
||||
<item
|
||||
android:id="@+id/main_menu_freeze_all"
|
||||
android:icon="@drawable/ic_freeze_tinted"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<string name="batch_operation">批量操作</string>
|
||||
|
||||
<!-- App Context Menu -->
|
||||
<string name="search">搜索</string>
|
||||
<string name="clone_to_work_profile">克隆到 Shelter (工作用户)</string>
|
||||
<string name="clone_to_main_profile">克隆到主用户</string>
|
||||
<string name="uninstall_app">卸载</string>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<string name="allow_cross_profile_widgets">Allow Widgets in Main Profile</string>
|
||||
|
||||
<!-- Action Bar Options Menu -->
|
||||
<string name="search">Search</string>
|
||||
<string name="freeze_all">Batch Freeze</string>
|
||||
<string name="create_freeze_all_shortcut">Create Batch Freeze Shortcut</string>
|
||||
<string name="freeze_all_shortcut">Freeze</string>
|
||||
|
|
Loading…
Reference in a new issue