回答
有幾種方法,你可以實現這種類型的效果,沒想到的詞彙應用程序是如何處理它,而是一個非常簡單的方法來得到一個非常類似的效果是使用多個RecyclerView.ViewHolder
類型,然後讓DefaultItemAnimator
負責動畫工作。這裏是去了解的一個方法:
型號
我們的模型也會包含我們顯示的數據以及一個type
通知我們RecyclerView.Adapter
這ReclerView.ViewHolder
膨脹。因此,它可能是這個樣子(AutoValue):
@AutoValue
public abstract class ExpandableModel {
public static final int TYPE_STATIC = 0;
public static final int TYPE_EXPANDED = 1;
public static final int TYPE_COLLAPSED = 2;
@Nullable public abstract List<ExpandableModel> data();
public abstract String title();
public abstract int progress();
public abstract int max();
public abstract int type();
public static ExpandableModel createExpanded(List<ExpandableModel> data,
String title, int progress, int max) {
return new AutoValue_ExpandableModel(data, title, progress, max, TYPE_EXPANDED);
}
public static ExpandableModel createCollapsed(List<ExpandableModel> data,
String title, int progress, int max) {
return new AutoValue_ExpandableModel(data, title, progress, max, TYPE_COLLAPSED);
}
public static ExpandableModel createExpanded(ExpandableModel model) {
return new AutoValue_ExpandableModel(
model.data(), model.title(), model.progress(), model.max(), TYPE_EXPANDED);
}
public static ExpandableModel createCollapsed(ExpandableModel model) {
return new AutoValue_ExpandableModel(
model.data(), model.title(), model.progress(), model.max(), TYPE_COLLAPSED);
}
public static ExpandableModel createStatic(String title, int progress, int max) {
return new AutoValue_ExpandableModel(null, title, progress, max, TYPE_STATIC);
}
}
ViewHolder
我們可以定義將結合一些ExpandableModel
數據基本ReclerView.ViewHolder
以及爲我們提供了一個很好的OnClickListener
回調。
public abstract class ExpandableViewHolder extends RecyclerView.ViewHolder {
public ExpandableViewHolder(ViewGroup parent, int layout) {
super(LayoutInflater.from(parent.getContext()).inflate(layout, parent, false));
}
public void setItemClickListener(OnItemClickListener clickListener) {
itemView.setOnClickListener(v -> {
final int adapterPosition = getAdapterPosition();
if (adapterPosition != RecyclerView.NO_POSITION) {
clickListener.onItemClick(itemView, adapterPosition);
}
});
}
public abstract void bind(ExpandableModel model);
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
}
}
ExpandedViewHolder
public class ExpandedViewHolder extends ExpandableViewHolder {
private final TextView title;
private final TextView completion;
private final ProgressBar progress;
private final RecyclerView recycler;
public ExpandedViewHolder(ViewGroup parent) {
super(parent, R.layout.adapter_view_expanded);
title = itemView.findViewById(R.id.expanded_category);
completion = itemView.findViewById(R.id.expanded_completion);
progress = itemView.findViewById(R.id.expanded_progress);
recycler = itemView.findViewById(R.id.expanded_recycler);
recycler.addItemDecoration(new SpaceItemDecoration(10));
}
@Override
public void bind(ExpandableModel model) {
title.setText(model.title());
completion.setText(model.progress() + "/" + model.max());
progress.setMax(model.max());
progress.setProgress(model.progress());
recycler.setAdapter(new ExpandableAdapter(model.data()));
}
}
ExpandedViewHolder佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="350dp"
android:background="#ffFFC857"
android:orientation="vertical">
<TextView
android:id="@+id/expanded_category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="#ffffffff"
android:textIsSelectable="false"
android:textSize="28sp"
tools:text="Basic Words" />
<TextView
android:id="@+id/expanded_completion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:textColor="#ffffffff"
android:textIsSelectable="false"
android:textSize="18sp"
tools:text="174/174 mastered" />
<ProgressBar
android:id="@+id/expanded_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
tools:progress="100" />
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.v7.widget.RecyclerView
android:id="@+id/expanded_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="4dp"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</LinearLayout>
CollapsedViewHolder
public class CollapsedViewHolder extends ExpandableViewHolder {
private final TextView title;
private final TextView completion;
private final ProgressBar progress;
public CollapsedViewHolder(ViewGroup parent) {
super(parent, R.layout.adapter_view_collapsed);
title = itemView.findViewById(R.id.collapsed_category);
completion = itemView.findViewById(R.id.collapsed_completion);
progress = itemView.findViewById(R.id.collapsed_progress);
}
@Override
public void bind(ExpandableModel model) {
title.setText(model.title());
completion.setText(model.progress() + "/" + model.max());
progress.setMax(model.max());
progress.setProgress(model.progress());
}
}
CollapsedViewHolder佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="165dp"
android:layout_margin="4dp"
android:background="#ffffffff"
android:orientation="vertical">
<TextView
android:id="@+id/collapsed_category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="#ff066FA5"
android:textIsSelectable="false"
android:textSize="28sp"
tools:text="Basic Words" />
<TextView
android:id="@+id/collapsed_completion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:textColor="#ffAEB8C3"
android:textIsSelectable="false"
android:textSize="18sp"
tools:text="174/174 mastered" />
<ProgressBar
android:id="@+id/collapsed_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
tools:progress="100" />
</LinearLayout>
適配器
現在,我們可以創建RecyclerView.Adapter
。基本上,無論何時點擊某個項目,我們將用TYPE_EXPANDED
或TYPE_COLLAPSED
ExpandableModel
and because DefaultItemAnimator
is already applied to RecyclerView
替換它,在這兩種類型的RecyclerView.ViewHolder
之間調用RecyclerView.Adapter.notifyItemChanged
會很好。
public class ExpandableAdapter extends RecyclerView.Adapter<ExpandableViewHolder> {
private final List<ExpandableModel> data = new ArrayList<>(0);
private int expandedPosition;
public ExpandableAdapter(Collection<ExpandableModel> data) {
this.data.addAll(data);
}
@Override
public ExpandableViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_EXPANDED:
final ExpandedViewHolder expandedHolder = new ExpandedViewHolder(parent);
expandedHolder.setItemClickListener((itemView, position) -> collapse(position));
return expandedHolder;
case TYPE_COLLAPSED:
final CollapsedViewHolder collapsedHolder = new CollapsedViewHolder(parent);
collapsedHolder.setItemClickListener((itemView, position) -> {
collapseCurrent();
expand(position);
});
return collapsedHolder;
case TYPE_STATIC:
final CollapsedViewHolder staticHolder = new CollapsedViewHolder(parent);
staticHolder.setItemClickListener((itemView, position) -> {
final ExpandableModel model = data.get(position);
Snackbar.make(itemView, model.title(), Snackbar.LENGTH_SHORT).show();
});
return staticHolder;
default:
throw new IllegalArgumentException("unknown type");
}
}
@Override
public void onBindViewHolder(ExpandableViewHolder holder, int position) {
holder.bind(data.get(holder.getAdapterPosition()));
}
@Override
public int getItemCount() {
return data.size();
}
@Override
public int getItemViewType(int position) {
return data.get(position).type();
}
private void collapseCurrent() {
final ExpandableModel curr = data.get(expandedPosition);
data.set(expandedPosition, ExpandableModel.createCollapsed(curr));
notifyItemChanged(expandedPosition);
}
private void collapse(int position) {
final ExpandableModel curr = data.get(position);
data.set(position, ExpandableModel.createCollapsed(curr));
notifyItemChanged(position);
}
private void expand(int position) {
final ExpandableModel curr = data.get(position);
data.set(position, ExpandableModel.createExpanded(curr));
notifyItemChanged(position);
expandedPosition = position;
}
}
僞數據
final Random ran = new SecureRandom();
final List<ExpandableModel> basic = new ArrayList<>(0);
for (int i = 0; i < 10; i++) {
final int max = 10;
final int progress = ran.nextInt(max + 1);
final String title = ("Basic Words: " + (i + 1));
basic.add(ExpandableModel.createStatic(title, progress, max));
}
final List<ExpandableModel> intermediate = new ArrayList<>(0);
for (int i = 0; i < 10; i++) {
final int max = 10;
final int progress = ran.nextInt(max + 1);
final String title = ("Intermediate Words: " + (i + 1));
intermediate.add(ExpandableModel.createStatic(title, progress, max));
}
final List<ExpandableModel> advanced = new ArrayList<>(0);
for (int i = 0; i < 10; i++) {
final int max = 10;
final int progress = ran.nextInt(max + 1);
final String title = ("Advanced Words: " + (i + 1));
advanced.add(ExpandableModel.createStatic(title, progress, max));
}
final List<ExpandableModel> data = new ArrayList<>(0);
data.add(ExpandableModel.createCollapsed(basic, "Basic Words", 7, 10));
data.add(ExpandableModel.createCollapsed(intermediate, "Intermediate Words", 5, 10));
data.add(ExpandableModel.createCollapsed(advanced, "Advanced Words", 3, 10));
final RecyclerView recycler = findViewById(android.R.id.list);
recycler.setAdapter(new ExpandableAdapter(data));
額外
public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private final int space;
public SpaceItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
final int childPosition = parent.getChildLayoutPosition(view);
if (childPosition == RecyclerView.NO_POSITION) {
return;
}
if (childPosition < 1 || childPosition >= 1) {
outRect.left = space;
}
if (childPosition == getTotalItemCount(parent) - 1) {
outRect.right = space;
}
}
private static int getTotalItemCount(RecyclerView parent) {
return parent.getAdapter().getItemCount();
}
}
結果(video)
你是一個救星..... –
- 1. Android如何在android
- 2. 如何在android
- 3. 如何在android
- 4. 如何在Android
- 5. 如何在Android
- 6. 如何在android
- 7. 如何在android
- 8. 如何在android
- 9. 如何在android
- 10. 如何在android
- 11. 如何在android
- 12. 如何在android
- 13. 如何在android
- 14. 如何在android
- 15. 如何在android
- 16. 如何在android
- 17. 如何在android
- 18. 如何在android
- 19. 如何在android
- 20. 如何在android
- 21. 如何在android
- 22. 如何在android
- 23. 如何在Android
- 24. 如何在android
- 25. 如何在android
- 26. 如何在Android
- 27. 如何在android
- 28. 如何在Android
- 29. 如何在android
- 30. 如何在Android
到目前爲止您嘗試過了什麼? –
我剛剛創建了最初的三個自定義視圖....正如我所說的,我不知道如何從第一個佈局轉換到具有平滑視圖轉換的第二個佈局。 –
試試這些以及 - https://github.com/wasabeef/awesome-android-ui – SanVed