Separate ExpandableViewHolder
This commit is contained in:
parent
18ab6b51fd
commit
976c299657
@ -15,7 +15,7 @@ import com.topjohnwu.core.container.Policy;
|
|||||||
import com.topjohnwu.core.database.MagiskDB;
|
import com.topjohnwu.core.database.MagiskDB;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.components.CustomAlertDialog;
|
import com.topjohnwu.magisk.components.CustomAlertDialog;
|
||||||
import com.topjohnwu.magisk.components.ExpandableView;
|
import com.topjohnwu.magisk.components.ExpandableViewHolder;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
import com.topjohnwu.magisk.utils.FingerprintHelper;
|
import com.topjohnwu.magisk.utils.FingerprintHelper;
|
||||||
|
|
||||||
@ -51,13 +51,13 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
|||||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||||
Policy policy = policyList.get(position);
|
Policy policy = policyList.get(position);
|
||||||
|
|
||||||
holder.setExpanded(expandList[position]);
|
holder.settings.setExpanded(expandList[position]);
|
||||||
holder.trigger.setOnClickListener(view -> {
|
holder.trigger.setOnClickListener(view -> {
|
||||||
if (holder.isExpanded()) {
|
if (holder.settings.isExpanded()) {
|
||||||
holder.collapse();
|
holder.settings.collapse();
|
||||||
expandList[position] = false;
|
expandList[position] = false;
|
||||||
} else {
|
} else {
|
||||||
holder.expand();
|
holder.settings.expand();
|
||||||
expandList[position] = true;
|
expandList[position] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -136,7 +136,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
|||||||
return policyList.size();
|
return policyList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
@BindView(R.id.app_name) TextView appName;
|
@BindView(R.id.app_name) TextView appName;
|
||||||
@BindView(R.id.package_name) TextView packageName;
|
@BindView(R.id.package_name) TextView packageName;
|
||||||
@ -150,24 +150,32 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
|||||||
@BindView(R.id.delete) ImageView delete;
|
@BindView(R.id.delete) ImageView delete;
|
||||||
@BindView(R.id.more_info) ImageView moreInfo;
|
@BindView(R.id.more_info) ImageView moreInfo;
|
||||||
|
|
||||||
private Container container = new Container();
|
ExpandableViewHolder settings;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
new PolicyAdapter$ViewHolder_ViewBinding(this, itemView);
|
new PolicyAdapter$ViewHolder_ViewBinding(this, itemView);
|
||||||
container.expandLayout = expandLayout;
|
settings = new ExpandableViewHolder(expandLayout) {
|
||||||
setupExpandable();
|
@Override
|
||||||
}
|
public void setExpanded(boolean expanded) {
|
||||||
|
super.setExpanded(expanded);
|
||||||
|
arrow.setRotation(expanded ? 180 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Container getContainer() {
|
public void expand() {
|
||||||
return container;
|
super.expand();
|
||||||
}
|
setRotate(new RotateAnimation(0, 180,
|
||||||
|
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setExpanded(boolean expanded) {
|
public void collapse() {
|
||||||
ExpandableView.super.setExpanded(expanded);
|
super.collapse();
|
||||||
arrow.setRotation(expanded ? 180 : 0);
|
setRotate(new RotateAnimation(180, 0,
|
||||||
|
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRotate(RotateAnimation rotate) {
|
private void setRotate(RotateAnimation rotate) {
|
||||||
@ -175,19 +183,5 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
|||||||
rotate.setFillAfter(true);
|
rotate.setFillAfter(true);
|
||||||
arrow.startAnimation(rotate);
|
arrow.startAnimation(rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void expand() {
|
|
||||||
ExpandableView.super.expand();
|
|
||||||
setRotate(new RotateAnimation(0, 180,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void collapse() {
|
|
||||||
ExpandableView.super.collapse();
|
|
||||||
setRotate(new RotateAnimation(180, 0,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import android.widget.TextView;
|
|||||||
import com.topjohnwu.core.container.SuLogEntry;
|
import com.topjohnwu.core.container.SuLogEntry;
|
||||||
import com.topjohnwu.core.database.MagiskDB;
|
import com.topjohnwu.core.database.MagiskDB;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.components.ExpandableView;
|
import com.topjohnwu.magisk.components.ExpandableViewHolder;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -84,13 +84,13 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S
|
|||||||
public void onBindItemViewHolder(LogViewHolder holder, int section, int position) {
|
public void onBindItemViewHolder(LogViewHolder holder, int section, int position) {
|
||||||
SuLogEntry entry = logEntries.get(section).get(position);
|
SuLogEntry entry = logEntries.get(section).get(position);
|
||||||
int realIdx = getItemPosition(section, position);
|
int realIdx = getItemPosition(section, position);
|
||||||
holder.setExpanded(itemExpanded.contains(realIdx));
|
holder.expandable.setExpanded(itemExpanded.contains(realIdx));
|
||||||
holder.itemView.setOnClickListener(view -> {
|
holder.itemView.setOnClickListener(view -> {
|
||||||
if (holder.isExpanded()) {
|
if (holder.expandable.isExpanded()) {
|
||||||
holder.collapse();
|
holder.expandable.collapse();
|
||||||
itemExpanded.remove(realIdx);
|
itemExpanded.remove(realIdx);
|
||||||
} else {
|
} else {
|
||||||
holder.expand();
|
holder.expandable.expand();
|
||||||
itemExpanded.add(realIdx);
|
itemExpanded.add(realIdx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -122,7 +122,7 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class LogViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
|
static class LogViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
@BindView(R.id.app_name) TextView appName;
|
@BindView(R.id.app_name) TextView appName;
|
||||||
@BindView(R.id.action) TextView action;
|
@BindView(R.id.action) TextView action;
|
||||||
@ -132,18 +132,12 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S
|
|||||||
@BindView(R.id.cmd) TextView command;
|
@BindView(R.id.cmd) TextView command;
|
||||||
@BindView(R.id.expand_layout) ViewGroup expandLayout;
|
@BindView(R.id.expand_layout) ViewGroup expandLayout;
|
||||||
|
|
||||||
private Container container = new Container();
|
ExpandableViewHolder expandable;
|
||||||
|
|
||||||
LogViewHolder(View itemView) {
|
LogViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
new SuLogAdapter$LogViewHolder_ViewBinding(this, itemView);
|
new SuLogAdapter$LogViewHolder_ViewBinding(this, itemView);
|
||||||
container.expandLayout = expandLayout;
|
expandable = new ExpandableViewHolder(expandLayout);
|
||||||
setupExpandable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Container getContainer() {
|
|
||||||
return container;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.components;
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
|
|
||||||
public interface ExpandableView {
|
|
||||||
|
|
||||||
class Container {
|
|
||||||
public ViewGroup expandLayout;
|
|
||||||
ValueAnimator expandAnimator, collapseAnimator;
|
|
||||||
boolean mExpanded = false;
|
|
||||||
int expandHeight = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide state info
|
|
||||||
Container getContainer();
|
|
||||||
|
|
||||||
default void setupExpandable() {
|
|
||||||
Container container = getContainer();
|
|
||||||
setExpanded(false);
|
|
||||||
container.expandLayout.getViewTreeObserver().addOnPreDrawListener(
|
|
||||||
new ViewTreeObserver.OnPreDrawListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreDraw() {
|
|
||||||
if (container.expandHeight == 0) {
|
|
||||||
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
|
|
||||||
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
|
|
||||||
container.expandLayout.measure(widthSpec, heightSpec);
|
|
||||||
container.expandHeight = container.expandLayout.getMeasuredHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
container.expandLayout.getViewTreeObserver().removeOnPreDrawListener(this);
|
|
||||||
container.expandAnimator = slideAnimator(0, container.expandHeight);
|
|
||||||
container.collapseAnimator = slideAnimator(container.expandHeight, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean isExpanded() {
|
|
||||||
return getContainer().mExpanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void setExpanded(boolean expanded) {
|
|
||||||
Container container = getContainer();
|
|
||||||
container.mExpanded = expanded;
|
|
||||||
ViewGroup.LayoutParams layoutParams = container.expandLayout.getLayoutParams();
|
|
||||||
layoutParams.height = expanded ? container.expandHeight : 0;
|
|
||||||
container.expandLayout.setLayoutParams(layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void expand() {
|
|
||||||
Container container = getContainer();
|
|
||||||
if (container.mExpanded) return;
|
|
||||||
container.expandLayout.setVisibility(View.VISIBLE);
|
|
||||||
container.expandAnimator.start();
|
|
||||||
container.mExpanded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void collapse() {
|
|
||||||
Container container = getContainer();
|
|
||||||
if (!container.mExpanded) return;
|
|
||||||
container.collapseAnimator.start();
|
|
||||||
container.mExpanded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default ValueAnimator slideAnimator(int start, int end) {
|
|
||||||
Container container = getContainer();
|
|
||||||
ValueAnimator animator = ValueAnimator.ofInt(start, end);
|
|
||||||
|
|
||||||
animator.addUpdateListener(valueAnimator -> {
|
|
||||||
int value = (Integer) valueAnimator.getAnimatedValue();
|
|
||||||
ViewGroup.LayoutParams layoutParams = container.expandLayout.getLayoutParams();
|
|
||||||
layoutParams.height = value;
|
|
||||||
container.expandLayout.setLayoutParams(layoutParams);
|
|
||||||
});
|
|
||||||
return animator;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.topjohnwu.magisk.components;
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
|
public class ExpandableViewHolder {
|
||||||
|
|
||||||
|
private ViewGroup expandLayout;
|
||||||
|
private ValueAnimator expandAnimator, collapseAnimator;
|
||||||
|
private boolean mExpanded = false;
|
||||||
|
private int expandHeight = 0;
|
||||||
|
|
||||||
|
public ExpandableViewHolder(ViewGroup viewGroup) {
|
||||||
|
expandLayout = viewGroup;
|
||||||
|
setExpanded(false);
|
||||||
|
expandLayout.getViewTreeObserver().addOnPreDrawListener(
|
||||||
|
new ViewTreeObserver.OnPreDrawListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreDraw() {
|
||||||
|
if (expandHeight == 0) {
|
||||||
|
expandLayout.measure(0, 0);
|
||||||
|
expandHeight = expandLayout.getMeasuredHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
expandLayout.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||||
|
expandAnimator = slideAnimator(0, expandHeight);
|
||||||
|
collapseAnimator = slideAnimator(expandHeight, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpanded() {
|
||||||
|
return mExpanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpanded(boolean expanded) {
|
||||||
|
mExpanded = expanded;
|
||||||
|
ViewGroup.LayoutParams layoutParams = expandLayout.getLayoutParams();
|
||||||
|
layoutParams.height = expanded ? expandHeight : 0;
|
||||||
|
expandLayout.setLayoutParams(layoutParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand() {
|
||||||
|
if (mExpanded) return;
|
||||||
|
expandLayout.setVisibility(View.VISIBLE);
|
||||||
|
expandAnimator.start();
|
||||||
|
mExpanded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void collapse() {
|
||||||
|
if (!mExpanded) return;
|
||||||
|
collapseAnimator.start();
|
||||||
|
mExpanded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValueAnimator slideAnimator(int start, int end) {
|
||||||
|
ValueAnimator animator = ValueAnimator.ofInt(start, end);
|
||||||
|
|
||||||
|
animator.addUpdateListener(valueAnimator -> {
|
||||||
|
int value = (Integer) valueAnimator.getAnimatedValue();
|
||||||
|
ViewGroup.LayoutParams layoutParams = expandLayout.getLayoutParams();
|
||||||
|
layoutParams.height = value;
|
||||||
|
expandLayout.setLayoutParams(layoutParams);
|
||||||
|
});
|
||||||
|
return animator;
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ import com.topjohnwu.magisk.components.BaseActivity;
|
|||||||
import com.topjohnwu.magisk.components.BaseFragment;
|
import com.topjohnwu.magisk.components.BaseFragment;
|
||||||
import com.topjohnwu.magisk.components.CustomAlertDialog;
|
import com.topjohnwu.magisk.components.CustomAlertDialog;
|
||||||
import com.topjohnwu.magisk.components.EnvFixDialog;
|
import com.topjohnwu.magisk.components.EnvFixDialog;
|
||||||
import com.topjohnwu.magisk.components.ExpandableView;
|
import com.topjohnwu.magisk.components.ExpandableViewHolder;
|
||||||
import com.topjohnwu.magisk.components.MagiskInstallDialog;
|
import com.topjohnwu.magisk.components.MagiskInstallDialog;
|
||||||
import com.topjohnwu.magisk.components.ManagerInstallDialog;
|
import com.topjohnwu.magisk.components.ManagerInstallDialog;
|
||||||
import com.topjohnwu.magisk.components.UninstallDialog;
|
import com.topjohnwu.magisk.components.UninstallDialog;
|
||||||
@ -50,9 +50,8 @@ import butterknife.BindView;
|
|||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
|
||||||
public class MagiskFragment extends BaseFragment
|
public class MagiskFragment extends BaseFragment
|
||||||
implements SwipeRefreshLayout.OnRefreshListener, ExpandableView, Topic.Subscriber {
|
implements SwipeRefreshLayout.OnRefreshListener, Topic.Subscriber {
|
||||||
|
|
||||||
private Container expandableContainer = new Container();
|
|
||||||
private static boolean shownDialog = false;
|
private static boolean shownDialog = false;
|
||||||
|
|
||||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||||
@ -83,6 +82,7 @@ public class MagiskFragment extends BaseFragment
|
|||||||
|
|
||||||
private UpdateCardHolder magisk;
|
private UpdateCardHolder magisk;
|
||||||
private UpdateCardHolder manager;
|
private UpdateCardHolder manager;
|
||||||
|
private ExpandableViewHolder snExpandableHolder;
|
||||||
private Transition transition;
|
private Transition transition;
|
||||||
|
|
||||||
@OnClick(R.id.safetyNet_title)
|
@OnClick(R.id.safetyNet_title)
|
||||||
@ -92,7 +92,7 @@ public class MagiskFragment extends BaseFragment
|
|||||||
safetyNetRefreshIcon.setVisibility(View.GONE);
|
safetyNetRefreshIcon.setVisibility(View.GONE);
|
||||||
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
|
||||||
SafetyNet.check(requireActivity());
|
SafetyNet.check(requireActivity());
|
||||||
collapse();
|
snExpandableHolder.collapse();
|
||||||
};
|
};
|
||||||
if (!SafetyNet.EXT_APK.exists()) {
|
if (!SafetyNet.EXT_APK.exists()) {
|
||||||
// Show dialog
|
// Show dialog
|
||||||
@ -134,8 +134,7 @@ public class MagiskFragment extends BaseFragment
|
|||||||
unbinder = new MagiskFragment_ViewBinding(this, v);
|
unbinder = new MagiskFragment_ViewBinding(this, v);
|
||||||
requireActivity().setTitle(R.string.magisk);
|
requireActivity().setTitle(R.string.magisk);
|
||||||
|
|
||||||
expandableContainer.expandLayout = expandLayout;
|
snExpandableHolder = new ExpandableViewHolder(expandLayout);
|
||||||
setupExpandable();
|
|
||||||
|
|
||||||
magisk = new UpdateCardHolder(inflater, root);
|
magisk = new UpdateCardHolder(inflater, root);
|
||||||
manager = new UpdateCardHolder(inflater, root);
|
manager = new UpdateCardHolder(inflater, root);
|
||||||
@ -168,7 +167,7 @@ public class MagiskFragment extends BaseFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onRefresh() {
|
public void onRefresh() {
|
||||||
safetyNetStatusText.setText(R.string.safetyNet_check_text);
|
safetyNetStatusText.setText(R.string.safetyNet_check_text);
|
||||||
setExpanded(false);
|
snExpandableHolder.setExpanded(false);
|
||||||
|
|
||||||
mSwipeRefreshLayout.setRefreshing(false);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
TransitionManager.beginDelayedTransition(root, transition);
|
TransitionManager.beginDelayedTransition(root, transition);
|
||||||
@ -207,11 +206,6 @@ public class MagiskFragment extends BaseFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Container getContainer() {
|
|
||||||
return expandableContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasGms() {
|
private boolean hasGms() {
|
||||||
PackageManager pm = app.getPackageManager();
|
PackageManager pm = app.getPackageManager();
|
||||||
PackageInfo info;
|
PackageInfo info;
|
||||||
@ -352,7 +346,7 @@ public class MagiskFragment extends BaseFragment
|
|||||||
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||||
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||||
|
|
||||||
expand();
|
snExpandableHolder.expand();
|
||||||
} else {
|
} else {
|
||||||
@StringRes int resid;
|
@StringRes int resid;
|
||||||
switch (response) {
|
switch (response) {
|
||||||
|
Loading…
Reference in New Issue
Block a user