Make swtichbar an item of rv (#1817)
This commit is contained in:
parent
2cb973656d
commit
81e2b5cfb7
|
|
@ -67,6 +67,7 @@ import org.lsposed.manager.App;
|
||||||
import org.lsposed.manager.BuildConfig;
|
import org.lsposed.manager.BuildConfig;
|
||||||
import org.lsposed.manager.ConfigManager;
|
import org.lsposed.manager.ConfigManager;
|
||||||
import org.lsposed.manager.R;
|
import org.lsposed.manager.R;
|
||||||
|
import org.lsposed.manager.databinding.ItemMasterSwitchBinding;
|
||||||
import org.lsposed.manager.databinding.ItemModuleBinding;
|
import org.lsposed.manager.databinding.ItemModuleBinding;
|
||||||
import org.lsposed.manager.ui.dialog.BlurBehindDialogBuilder;
|
import org.lsposed.manager.ui.dialog.BlurBehindDialogBuilder;
|
||||||
import org.lsposed.manager.ui.fragment.AppListFragment;
|
import org.lsposed.manager.ui.fragment.AppListFragment;
|
||||||
|
|
@ -86,6 +87,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import rikka.core.util.ResourceUtils;
|
import rikka.core.util.ResourceUtils;
|
||||||
import rikka.material.app.LocaleDelegate;
|
import rikka.material.app.LocaleDelegate;
|
||||||
|
import rikka.widget.mainswitchbar.MainSwitchBar;
|
||||||
import rikka.widget.mainswitchbar.OnMainSwitchChangeListener;
|
import rikka.widget.mainswitchbar.OnMainSwitchChangeListener;
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
|
@ -105,18 +107,43 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
||||||
private List<AppInfo> showList = new ArrayList<>();
|
private List<AppInfo> showList = new ArrayList<>();
|
||||||
private List<String> denyList = new ArrayList<>();
|
private List<String> denyList = new ArrayList<>();
|
||||||
|
|
||||||
|
public RecyclerView.Adapter<RecyclerView.ViewHolder> switchAdaptor = new RecyclerView.Adapter<>() {
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new RecyclerView.ViewHolder(ItemMasterSwitchBinding.inflate(activity.getLayoutInflater(), parent, false).masterSwitch) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||||
|
var mainSwitchBar = (MainSwitchBar) holder.itemView;
|
||||||
|
mainSwitchBar.setChecked(enabled);
|
||||||
|
mainSwitchBar.addOnSwitchChangeListener(switchBarOnCheckedChangeListener);
|
||||||
|
// bug of MainSwitchBar, force set the checkedChangeListener
|
||||||
|
fragment.runOnUiThread(mainSwitchBar::show);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final OnMainSwitchChangeListener switchBarOnCheckedChangeListener = new OnMainSwitchChangeListener() {
|
private final OnMainSwitchChangeListener switchBarOnCheckedChangeListener = new OnMainSwitchChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSwitchChanged(Switch view, boolean isChecked) {
|
public void onSwitchChanged(Switch view, boolean isChecked) {
|
||||||
|
enabled = isChecked;
|
||||||
if (!moduleUtil.setModuleEnabled(module.packageName, isChecked)) {
|
if (!moduleUtil.setModuleEnabled(module.packageName, isChecked)) {
|
||||||
view.setChecked(!isChecked);
|
view.setChecked(!isChecked);
|
||||||
|
enabled = !isChecked;
|
||||||
}
|
}
|
||||||
var tmpChkList = new HashSet<>(checkedList);
|
var tmpChkList = new HashSet<>(checkedList);
|
||||||
if (isChecked && !tmpChkList.isEmpty() && !ConfigManager.setModuleScope(module.packageName, tmpChkList)) {
|
if (isChecked && !tmpChkList.isEmpty() && !ConfigManager.setModuleScope(module.packageName, tmpChkList)) {
|
||||||
view.setChecked(false);
|
view.setChecked(false);
|
||||||
|
enabled = false;
|
||||||
}
|
}
|
||||||
enabled = isChecked;
|
fragment.runOnUiThread(ScopeAdapter.this::notifyDataSetChanged);
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -205,7 +232,7 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRecommended() {
|
private void checkRecommended() {
|
||||||
if (!fragment.binding.masterSwitch.isChecked()) {
|
if (!enabled) {
|
||||||
fragment.showHint(R.string.module_is_not_activated_yet, false);
|
fragment.showHint(R.string.module_is_not_activated_yet, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -359,7 +386,9 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewRecycled(@NonNull ViewHolder holder) {
|
public void onViewRecycled(@NonNull ViewHolder holder) {
|
||||||
holder.checkbox.setOnCheckedChangeListener(null);
|
if (holder.checkbox != null) {
|
||||||
|
holder.checkbox.setOnCheckedChangeListener(null);
|
||||||
|
}
|
||||||
super.onViewRecycled(holder);
|
super.onViewRecycled(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -480,9 +509,6 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
||||||
public void refresh(boolean force) {
|
public void refresh(boolean force) {
|
||||||
setLoaded(null, false);
|
setLoaded(null, false);
|
||||||
enabled = moduleUtil.isModuleEnabled(module.packageName);
|
enabled = moduleUtil.isModuleEnabled(module.packageName);
|
||||||
fragment.binding.masterSwitch.addOnSwitchChangeListener(null);
|
|
||||||
fragment.binding.masterSwitch.setChecked(enabled);
|
|
||||||
fragment.binding.masterSwitch.addOnSwitchChangeListener(switchBarOnCheckedChangeListener);
|
|
||||||
fragment.runAsync(() -> {
|
fragment.runAsync(() -> {
|
||||||
List<PackageInfo> appList = AppHelper.getAppList(force);
|
List<PackageInfo> appList = AppHelper.getAppList(force);
|
||||||
denyList = AppHelper.getDenyList(force);
|
denyList = AppHelper.getDenyList(force);
|
||||||
|
|
@ -640,7 +666,7 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
||||||
|
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
fragment.searchView.clearFocus();
|
fragment.searchView.clearFocus();
|
||||||
if (isLoaded && fragment.binding.masterSwitch.isChecked() && checkedList.isEmpty()) {
|
if (isLoaded && enabled && checkedList.isEmpty()) {
|
||||||
var builder = new BlurBehindDialogBuilder(activity);
|
var builder = new BlurBehindDialogBuilder(activity);
|
||||||
builder.setMessage(!recommendedList.isEmpty() ? R.string.no_scope_selected_has_recommended : R.string.no_scope_selected);
|
builder.setMessage(!recommendedList.isEmpty() ? R.string.no_scope_selected_has_recommended : R.string.no_scope_selected);
|
||||||
if (!recommendedList.isEmpty()) {
|
if (!recommendedList.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.widget.SearchView;
|
import androidx.appcompat.widget.SearchView;
|
||||||
|
import androidx.recyclerview.widget.ConcatAdapter;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
|
@ -87,7 +88,10 @@ public class AppListFragment extends BaseFragment {
|
||||||
scopeAdapter = new ScopeAdapter(this, module);
|
scopeAdapter = new ScopeAdapter(this, module);
|
||||||
scopeAdapter.setHasStableIds(true);
|
scopeAdapter.setHasStableIds(true);
|
||||||
scopeAdapter.registerAdapterDataObserver(observer);
|
scopeAdapter.registerAdapterDataObserver(observer);
|
||||||
binding.recyclerView.setAdapter(scopeAdapter);
|
var concatAdapter = new ConcatAdapter();
|
||||||
|
concatAdapter.addAdapter(scopeAdapter.switchAdaptor);
|
||||||
|
concatAdapter.addAdapter(scopeAdapter);
|
||||||
|
binding.recyclerView.setAdapter(concatAdapter);
|
||||||
binding.recyclerView.setHasFixedSize(true);
|
binding.recyclerView.setHasFixedSize(true);
|
||||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
|
binding.recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
|
||||||
binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top));
|
binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top));
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import android.util.AttributeSet;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.recyclerview.widget.ConcatAdapter;
|
||||||
|
|
||||||
import org.lsposed.manager.R;
|
import org.lsposed.manager.R;
|
||||||
import org.lsposed.manager.util.SimpleStatefulAdaptor;
|
import org.lsposed.manager.util.SimpleStatefulAdaptor;
|
||||||
|
|
@ -61,6 +62,14 @@ public class EmptyStateRecyclerView extends StatefulRecyclerView {
|
||||||
protected void dispatchDraw(Canvas canvas) {
|
protected void dispatchDraw(Canvas canvas) {
|
||||||
super.dispatchDraw(canvas);
|
super.dispatchDraw(canvas);
|
||||||
var adapter = getAdapter();
|
var adapter = getAdapter();
|
||||||
|
if (adapter instanceof ConcatAdapter) {
|
||||||
|
for (var a : ((ConcatAdapter) adapter).getAdapters()) {
|
||||||
|
if (a instanceof EmptyStateAdapter) {
|
||||||
|
adapter = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (adapter instanceof EmptyStateAdapter && ((EmptyStateAdapter<?>) adapter).isLoaded() && adapter.getItemCount() == 0) {
|
if (adapter instanceof EmptyStateAdapter && ((EmptyStateAdapter<?>) adapter).isLoaded() && adapter.getItemCount() == 0) {
|
||||||
final int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
|
final int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
|
||||||
final int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
|
final int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
|
||||||
|
|
|
||||||
|
|
@ -74,41 +74,29 @@
|
||||||
app:layout_fitsSystemWindowsInsets="@integer/internal_fragment_bottom_insets"
|
app:layout_fitsSystemWindowsInsets="@integer/internal_fragment_bottom_insets"
|
||||||
app:tint="?attr/colorOnPrimary" />
|
app:tint="?attr/colorOnPrimary" />
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<LinearLayout
|
||||||
android:id="@+id/swipe_refresh_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipe_refresh_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<LinearLayout
|
<org.lsposed.manager.ui.widget.EmptyStateRecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:clipToPadding="false"
|
||||||
|
android:fadeScrollbars="true"
|
||||||
<rikka.widget.mainswitchbar.MainSwitchBar
|
android:scrollbarStyle="insideOverlay"
|
||||||
android:id="@+id/master_switch"
|
android:scrollbars="vertical"
|
||||||
android:layout_width="match_parent"
|
app:borderBottomVisibility="never"
|
||||||
android:layout_height="wrap_content"
|
app:borderTopDrawable="@null"
|
||||||
android:fillViewport="true"
|
app:borderTopVisibility="whenTop"
|
||||||
android:text="@string/enable_module" />
|
app:fitsSystemWindowsInsets="@integer/internal_fragment_bottom_insets" />
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
<org.lsposed.manager.ui.widget.EmptyStateRecyclerView
|
</LinearLayout>
|
||||||
android:id="@+id/recycler_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:fadeScrollbars="true"
|
|
||||||
android:scrollbarStyle="insideOverlay"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
app:borderBottomVisibility="never"
|
|
||||||
app:borderTopDrawable="@null"
|
|
||||||
app:borderTopVisibility="whenTop"
|
|
||||||
app:fitsSystemWindowsInsets="@integer/internal_fragment_bottom_insets" />
|
|
||||||
</LinearLayout>
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rikka.widget.mainswitchbar.MainSwitchBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/master_switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/enable_module" />
|
||||||
Loading…
Reference in New Issue