Small UI improvements

This commit is contained in:
topjohnwu 2019-03-13 05:11:18 -04:00
parent 1e24c72c11
commit 3e35de9b39
3 changed files with 49 additions and 55 deletions

View File

@ -58,6 +58,8 @@ public class ApplicationAdapter extends SectionedAdapter
private static final String SAFETYNET_PROCESS = "com.google.android.gms.unstable";
private static final String GMS_PACKAGE = "com.google.android.gms";
private static int BOTTOM_MARGIN = -1;
private List<HideAppInfo> fullList, showList;
private List<HideTarget> hideList;
private PackageManager pm;
@ -71,6 +73,10 @@ public class ApplicationAdapter extends SectionedAdapter
AsyncTask.SERIAL_EXECUTOR.execute(this::loadApps);
}
private static ViewGroup.MarginLayoutParams getMargins(RecyclerView.ViewHolder vh) {
return (ViewGroup.MarginLayoutParams) vh.itemView.getLayoutParams();
}
@Override
public int getSectionCount() {
return showList.size();
@ -78,13 +84,17 @@ public class ApplicationAdapter extends SectionedAdapter
@Override
public int getItemCount(int section) {
return showList.get(section).expanded ? showList.get(section).processes.size() : 0;
HideAppInfo app = showList.get(section);
return app.expanded ? app.processList.size() : 0;
}
@Override
public AppViewHolder onCreateSectionViewHolder(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_hide_app, parent, false);
return new AppViewHolder(v);
AppViewHolder vh = new AppViewHolder(v);
if (BOTTOM_MARGIN < 0)
BOTTOM_MARGIN = getMargins(vh).bottomMargin;
return vh;
}
@Override
@ -96,45 +106,34 @@ public class ApplicationAdapter extends SectionedAdapter
@Override
public void onBindSectionViewHolder(AppViewHolder holder, int section) {
HideAppInfo app = showList.get(section);
IndeterminateCheckBox.OnStateChangedListener listener =
(IndeterminateCheckBox indeterminateCheckBox, @Nullable Boolean stat) -> {
if (stat != null) {
for (HideProcessInfo p : app.processes) {
String cmd = Utils.fmt("magiskhide --%s %s %s",
stat ? "add" : "rm", app.info.packageName, p.name);
Shell.su(cmd).submit();
p.hidden = stat;
}
}
};
holder.app_name.setText(app.name);
holder.app_icon.setImageDrawable(app.info.loadIcon(pm));
holder.package_name.setText(app.info.packageName);
holder.checkBox.setOnStateChangedListener(null);
holder.checkBox.setOnStateChangedListener(listener);
holder.checkBox.setOnStateChangedListener(app.listener);
holder.checkBox.setState(app.getState());
if (app.expanded) {
holder.checkBox.setVisibility(View.GONE);
setBottomMargin(holder.itemView, 0);
getMargins(holder).bottomMargin = 0;
} else {
holder.checkBox.setVisibility(View.VISIBLE);
setBottomMargin(holder.itemView, 2);
getMargins(holder).bottomMargin = BOTTOM_MARGIN;
}
holder.itemView.setOnClickListener((v) -> {
int index = getItemPosition(section, 0);
if (app.expanded) {
app.expanded = false;
notifyItemRangeRemoved(index, app.processes.size());
setBottomMargin(holder.itemView, 2);
notifyItemRangeRemoved(index, app.processList.size());
getMargins(holder).bottomMargin = BOTTOM_MARGIN;
holder.checkBox.setOnStateChangedListener(null);
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setState(app.getState());
holder.checkBox.setOnStateChangedListener(listener);
holder.checkBox.setOnStateChangedListener(app.listener);
} else {
holder.checkBox.setVisibility(View.GONE);
setBottomMargin(holder.itemView, 0);
getMargins(holder).bottomMargin = 0;
app.expanded = true;
notifyItemRangeInserted(index, app.processes.size());
notifyItemRangeInserted(index, app.processList.size());
}
});
}
@ -142,21 +141,17 @@ public class ApplicationAdapter extends SectionedAdapter
@Override
public void onBindItemViewHolder(ProcessViewHolder holder, int section, int position) {
HideAppInfo hideApp = showList.get(section);
HideProcessInfo target = hideApp.processes.get(position);
HideProcessInfo target = hideApp.processList.get(position);
holder.process.setText(target.name);
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(target.hidden);
holder.checkbox.setOnCheckedChangeListener((v, isChecked) -> {
String pair = Utils.fmt("%s %s", hideApp.info.packageName, target.name);
if (isChecked) {
Shell.su("magiskhide --add " + pair).submit();
target.hidden = true;
} else {
Shell.su("magiskhide --rm " + pair).submit();
target.hidden = false;
}
holder.checkbox.setOnCheckedChangeListener((v, checked) -> {
Shell.su(Utils.fmt("magiskhide --%s %s %s", checked ? "add" : "rm",
hideApp.info.packageName, target.name)).submit();
target.hidden = checked;
});
getMargins(holder).bottomMargin =
position == hideApp.processList.size() - 1 ? BOTTOM_MARGIN : 0;
}
public void filter(String constraint) {
@ -179,18 +174,6 @@ public class ApplicationAdapter extends SectionedAdapter
AsyncTask.SERIAL_EXECUTOR.execute(this::loadApps);
}
private void setBottomMargin(View view, int dp) {
ViewGroup.LayoutParams params = view.getLayoutParams();
ViewGroup.MarginLayoutParams marginParams;
if (params instanceof ViewGroup.MarginLayoutParams) {
marginParams = (ViewGroup.MarginLayoutParams) params;
} else {
marginParams = new ViewGroup.MarginLayoutParams(params);
}
marginParams.bottomMargin = Utils.dpInPx(dp);
view.setLayoutParams(marginParams);
}
private void addProcesses(Set<String> set, ComponentInfo[] infos) {
if (infos != null)
for (ComponentInfo info : infos)
@ -258,7 +241,7 @@ public class ApplicationAdapter extends SectionedAdapter
filter = filter.toLowerCase();
if (contains(target.name, filter))
return true;
for (HideProcessInfo p : target.processes) {
for (HideProcessInfo p : target.processList) {
if (contains(p.name, filter))
return true;
}
@ -268,16 +251,27 @@ public class ApplicationAdapter extends SectionedAdapter
class HideAppInfo implements Comparable<HideAppInfo> {
String name;
ApplicationInfo info;
List<HideProcessInfo> processes;
List<HideProcessInfo> processList;
boolean expanded;
IndeterminateCheckBox.OnStateChangedListener listener;
HideAppInfo(ApplicationInfo appInfo, Set<String> set) {
info = appInfo;
name = Utils.getAppLabel(info, pm);
expanded = false;
processes = StreamSupport.stream(set)
processList = StreamSupport.stream(set)
.map(process -> new HideProcessInfo(info.packageName, process))
.sorted().collect(Collectors.toList());
listener = (IndeterminateCheckBox box, @Nullable Boolean status) -> {
if (status != null) {
for (HideProcessInfo p : processList) {
String cmd = Utils.fmt("magiskhide --%s %s %s",
status ? "add" : "rm", info.packageName, p.name);
Shell.su(cmd).submit();
p.hidden = status;
}
}
};
}
@Override
@ -293,7 +287,7 @@ public class ApplicationAdapter extends SectionedAdapter
Boolean getState() {
boolean all = true;
boolean hidden = false;
for (HideProcessInfo p : processes) {
for (HideProcessInfo p : processList) {
if (!p.hidden)
all = false;
else
@ -357,7 +351,7 @@ public class ApplicationAdapter extends SectionedAdapter
@BindView(R.id.package_name) TextView package_name;
@BindView(R.id.checkbox) IndeterminateCheckBox checkBox;
public AppViewHolder(@NonNull View itemView) {
AppViewHolder(@NonNull View itemView) {
super(itemView);
new ApplicationAdapter$AppViewHolder_ViewBinding(this, itemView);
}
@ -368,7 +362,7 @@ public class ApplicationAdapter extends SectionedAdapter
@BindView(R.id.process) TextView process;
@BindView(R.id.checkbox) CheckBox checkbox;
public ProcessViewHolder(@NonNull View itemView) {
ProcessViewHolder(@NonNull View itemView) {
super(itemView);
new ApplicationAdapter$ProcessViewHolder_ViewBinding(this, itemView);
}

View File

@ -44,7 +44,7 @@ public abstract class SectionedAdapter<S extends RecyclerView.ViewHolder, C exte
if (info.position == -1)
return SECTION_TYPE;
else
return getItemViewType(info.section, info.position);
return getItemViewType(info.section, info.position);
}
public int getItemViewType(int section, int position) {

View File

@ -7,16 +7,16 @@
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginStart="@dimen/card_horizontal_margin"
android:layout_marginTop="0dp"
android:layout_marginEnd="@dimen/card_horizontal_margin"
android:layout_marginBottom="0dp"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardCornerRadius="0dp"
app:cardElevation="@dimen/card_elevation">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/info_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:paddingTop="2dp"
android:paddingBottom="2dp">
<TextView
android:id="@+id/process"