diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0016b94f..89011554 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -22,9 +22,6 @@
-
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/BlackListActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/BlackListActivity.java
index bc1e3337..52a7def1 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/BlackListActivity.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/BlackListActivity.java
@@ -19,11 +19,12 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.meowcat.edxposed.manager.adapters.AppAdapter;
import org.meowcat.edxposed.manager.adapters.AppHelper;
import org.meowcat.edxposed.manager.adapters.BlackListAdapter;
+import org.meowcat.edxposed.manager.adapters.CompatListAdapter;
import org.meowcat.edxposed.manager.databinding.ActivityBlackListBinding;
public class BlackListActivity extends BaseActivity implements AppAdapter.Callback {
private SearchView searchView;
- private BlackListAdapter appAdapter;
+ private AppAdapter appAdapter;
private SearchView.OnQueryTextListener searchListener;
private ActivityBlackListBinding binding;
@@ -34,10 +35,12 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
}
};
private Handler handler = new Handler();
+ private boolean isCompat;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ isCompat = getIntent().getBooleanExtra("compat_list", false);
binding = ActivityBlackListBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
@@ -47,10 +50,11 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
bar.setDisplayHomeAsUpEnabled(true);
}
setupWindowInsets(binding.snackbar, binding.recyclerView);
- binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
final boolean isWhiteListMode = isWhiteListMode();
- appAdapter = new BlackListAdapter(this, isWhiteListMode, binding);
+ appAdapter = isCompat ? new CompatListAdapter(this, binding) : new BlackListAdapter(this, isWhiteListMode, binding);
+ appAdapter.setHasStableIds(true);
binding.recyclerView.setAdapter(appAdapter);
+ binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
if (!XposedApp.getPreferences().getBoolean("md2", false)) {
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL);
@@ -60,7 +64,6 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
handler.postDelayed(runnable, 300);
binding.swipeRefreshLayout.setOnRefreshListener(appAdapter::refresh);
-
searchListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
@@ -87,7 +90,7 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
@Override
public void onResume() {
super.onResume();
- if (!AppHelper.isBlackListMode()) {
+ if (!isCompat && !AppHelper.isBlackListMode()) {
new MaterialAlertDialogBuilder(this)
.setMessage(R.string.warning_list_not_enabled)
.setPositiveButton(R.string.Settings, (dialog, which) -> {
@@ -104,7 +107,9 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
private void changeTitle(boolean isBlackListMode, boolean isWhiteListMode) {
- if (isBlackListMode) {
+ if (isCompat) {
+ setTitle(R.string.nav_title_compat_list);
+ } else if (isBlackListMode) {
setTitle(isWhiteListMode ? R.string.title_white_list : R.string.title_black_list);
} else {
setTitle(R.string.nav_title_black_list);
@@ -124,12 +129,16 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
handler.removeCallbacks(runnable);
binding.swipeRefreshLayout.setRefreshing(false);
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
- appAdapter.filter(queryStr);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ appAdapter.getFilter().filter(queryStr);
+ }
+ });
}
@Override
public void onItemClick(View v, ApplicationInfo info) {
- getSupportFragmentManager();
AppHelper.showMenu(this, getSupportFragmentManager(), v, info);
}
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/CompatListActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/CompatListActivity.java
deleted file mode 100644
index 5dcf221f..00000000
--- a/app/src/main/java/org/meowcat/edxposed/manager/CompatListActivity.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.meowcat.edxposed.manager;
-
-import android.content.pm.ApplicationInfo;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.widget.SearchView;
-import androidx.recyclerview.widget.DividerItemDecoration;
-import androidx.recyclerview.widget.LinearLayoutManager;
-
-import org.meowcat.edxposed.manager.adapters.AppAdapter;
-import org.meowcat.edxposed.manager.adapters.AppHelper;
-import org.meowcat.edxposed.manager.adapters.CompatListAdapter;
-import org.meowcat.edxposed.manager.databinding.ActivityBlackListBinding;
-
-public class CompatListActivity extends BaseActivity implements AppAdapter.Callback {
-
- private SearchView searchView;
- private CompatListAdapter appAdapter;
-
- private SearchView.OnQueryTextListener searchListener;
- private ActivityBlackListBinding binding;
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- binding = ActivityBlackListBinding.inflate(getLayoutInflater());
- setContentView(binding.getRoot());
- setSupportActionBar(binding.toolbar);
- binding.toolbar.setNavigationOnClickListener(view -> finish());
- ActionBar bar = getSupportActionBar();
- if (bar != null) {
- bar.setDisplayHomeAsUpEnabled(true);
- }
- setupWindowInsets(binding.snackbar, binding.recyclerView);
- binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
- appAdapter = new CompatListAdapter(this, binding);
- binding.recyclerView.setAdapter(appAdapter);
- if (!XposedApp.getPreferences().getBoolean("md2", false)) {
- DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this,
- DividerItemDecoration.VERTICAL);
- binding.recyclerView.addItemDecoration(dividerItemDecoration);
- }
- appAdapter.setCallback(this);
-
- binding.swipeRefreshLayout.setRefreshing(true);
- binding.swipeRefreshLayout.setOnRefreshListener(appAdapter::refresh);
-
- searchListener = new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String query) {
- appAdapter.filter(query);
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(String newText) {
- appAdapter.filter(newText);
- return false;
- }
- };
- }
-
- @Override
- public boolean onCreateOptionsMenu(@NonNull Menu menu) {
- getMenuInflater().inflate(R.menu.menu_app_list, menu);
- searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
- searchView.setOnQueryTextListener(searchListener);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public void onDataReady() {
- binding.swipeRefreshLayout.setRefreshing(false);
- String queryStr = searchView != null ? searchView.getQuery().toString() : "";
- appAdapter.filter(queryStr);
- }
-
- @Override
- public void onItemClick(View v, ApplicationInfo info) {
- AppHelper.showMenu(this, getSupportFragmentManager(), v, info);
-
- }
-
- @Override
- public void onBackPressed() {
- if (searchView.isIconified()) {
- super.onBackPressed();
- } else {
- searchView.setIconified(true);
- }
- }
-
- @Override
- public void onPointerCaptureChanged(boolean hasCapture) {
-
- }
-}
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java
index 48470b38..d08fb183 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java
@@ -196,6 +196,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}).show();
}
adapter = new ModuleAdapter();
+ adapter.setHasStableIds(true);
moduleUtil.addListener(this);
binding.recyclerView.setAdapter(adapter);
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
@@ -561,7 +562,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
boolean changed = moduleUtil.isModuleEnabled(packageName) ^ isChecked;
if (changed) {
moduleUtil.setModuleEnabled(packageName, isChecked);
- moduleUtil.updateModulesList(true);
+ moduleUtil.updateModulesList(true, binding);
}
});
mSwitch.setChecked(moduleUtil.isModuleEnabled(item.packageName));
@@ -617,6 +618,11 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
}
+ @Override
+ public long getItemId(int position) {
+ return items.get(position).hashCode();
+ }
+
class ViewHolder extends RecyclerView.ViewHolder {
ImageView appIcon;
TextView appName;
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java
index 3ec2781c..cf567bd4 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java
@@ -415,7 +415,8 @@ public class SettingsActivity extends BaseActivity {
Activity activity = getActivity();
if (activity != null) {
Intent intent = new Intent();
- intent.setClass(activity, CompatListActivity.class);
+ intent.putExtra("compat_list",true);
+ intent.setClass(activity, BlackListActivity.class);
activity.startActivity(intent);
}
return true;
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java b/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java
index 92c199c1..393e84a0 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java
@@ -10,6 +10,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Filter;
+import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
@@ -32,7 +33,7 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
-public class AppAdapter extends RecyclerView.Adapter {
+public class AppAdapter extends RecyclerView.Adapter implements Filterable {
protected final Context context;
private final ApplicationInfo.DisplayNameComparator displayNameComparator;
@@ -84,6 +85,7 @@ public class AppAdapter extends RecyclerView.Adapter {
AppHelper.makeSurePath();
checkedList = generateCheckedList();
sortApps();
+ showList = fullList;
if (callback != null) {
callback.onDataReady();
}
@@ -195,6 +197,16 @@ public class AppAdapter extends RecyclerView.Adapter {
});
}
+ @Override
+ public long getItemId(int position) {
+ return showList.get(position).packageName.hashCode();
+ }
+
+ @Override
+ public Filter getFilter() {
+ return new ApplicationFilter();
+ }
+
@Override
public int getItemCount() {
return showList.size();
@@ -246,17 +258,18 @@ public class AppAdapter extends RecyclerView.Adapter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
- if (constraint == null || constraint.length() == 0) {
+ if (constraint.toString().isEmpty()) {
showList = fullList;
} else {
- showList = new ArrayList<>();
+ ArrayList filtered = new ArrayList<>();
String filter = constraint.toString().toLowerCase();
for (ApplicationInfo info : fullList) {
if (lowercaseContains(InstallApkUtil.getAppLabel(info, pm), filter)
|| lowercaseContains(info.packageName, filter)) {
- showList.add(info);
+ filtered.add(info);
}
}
+ showList = filtered;
}
return null;
}
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/util/ModuleUtil.java b/app/src/main/java/org/meowcat/edxposed/manager/util/ModuleUtil.java
index d107356a..5a72b3ee 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/util/ModuleUtil.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/util/ModuleUtil.java
@@ -16,8 +16,11 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
+import com.google.android.material.snackbar.Snackbar;
+
import org.meowcat.edxposed.manager.R;
import org.meowcat.edxposed.manager.XposedApp;
+import org.meowcat.edxposed.manager.databinding.ActivityModulesBinding;
import org.meowcat.edxposed.manager.repo.ModuleVersion;
import org.meowcat.edxposed.manager.repo.RepoDb;
@@ -207,11 +210,19 @@ public final class ModuleUtil {
}
public synchronized void updateModulesList(boolean showToast) {
+ updateModulesList(showToast, null);
+ }
+
+ public synchronized void updateModulesList(boolean showToast, ActivityModulesBinding binding) {
try {
Log.i(XposedApp.TAG, "ModuleUtil -> updating modules.list");
int installedXposedVersion = XposedApp.getXposedVersion();
if (!XposedApp.getPreferences().getBoolean("skip_xposedminversion_check", false) && installedXposedVersion <= 0 && showToast) {
- Toast.makeText(XposedApp.getInstance(), R.string.notinstalled, Toast.LENGTH_SHORT).show();
+ if (binding != null) {
+ Snackbar.make(binding.snackbar, R.string.notinstalled, Snackbar.LENGTH_SHORT).show();
+ } else {
+ showToast(R.string.notinstalled);
+ }
return;
}
@@ -221,7 +232,11 @@ public final class ModuleUtil {
for (InstalledModule module : enabledModules) {
if (!XposedApp.getPreferences().getBoolean("skip_xposedminversion_check", false) && (module.minVersion > installedXposedVersion || module.minVersion < MIN_MODULE_VERSION) && showToast) {
- Toast.makeText(XposedApp.getInstance(), R.string.notinstalled, Toast.LENGTH_SHORT).show();
+ if (binding != null) {
+ Snackbar.make(binding.snackbar, R.string.notinstalled, Snackbar.LENGTH_SHORT).show();
+ } else {
+ showToast(R.string.notinstalled);
+ }
continue;
}
@@ -241,11 +256,19 @@ public final class ModuleUtil {
FileUtils.setPermissions(XposedApp.ENABLED_MODULES_LIST_FILE, 00664, -1, -1);
if (showToast) {
- showToast(R.string.xposed_module_list_updated);
+ if (binding != null) {
+ Snackbar.make(binding.snackbar, R.string.xposed_module_list_updated, Snackbar.LENGTH_SHORT).show();
+ } else {
+ showToast(R.string.xposed_module_list_updated);
+ }
}
} catch (IOException e) {
Log.e(XposedApp.TAG, "ModuleUtil -> cannot write " + MODULES_LIST_FILE, e);
- Toast.makeText(XposedApp.getInstance(), "cannot write " + MODULES_LIST_FILE + e, Toast.LENGTH_SHORT).show();
+ if (binding != null) {
+ Snackbar.make(binding.snackbar, "cannot write " + MODULES_LIST_FILE + e, Snackbar.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(XposedApp.getInstance(), "cannot write " + MODULES_LIST_FILE + e, Toast.LENGTH_SHORT).show();
+ }
}
}
diff --git a/build.gradle b/build.gradle
index 591879ac..a124535b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.0-beta02'
+ classpath 'com.android.tools.build:gradle:4.0.0-beta03'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.2'
// NOTE: Do not place your application dependencies here; they belong