1

나는 아래와 같이 View 트랜지션을 추가하고 싶은 프로젝트에서 일하고 있습니다. 나는 어디에서 시작해야할지 모르겠다. 아무도 나를 도울 수 있니?android에서 이와 같은 뷰 전환을 디자인하는 방법

+0

지금까지 해보신 것은 무엇입니까? –

+0

방금 ​​전에 처음 세 개의 사용자 정의보기를 만들었습니다 .... 제가 말했듯이 첫 번째 레이아웃에서 두 번째 레이아웃으로 어떻게 부드럽게 전환 할 수 있는지 전혀 모르겠습니다. –

+0

잘보십시오 - https://github.com/wasabeef/awesome-android-ui – SanVed

답변

1

당신이 효과의 유형을 달성 할 수있는 몇 가지 방법이 있습니다, 그 어휘 응용 프로그램이 처리하지만, 매우 유사한 효과를 얻을 수있는 아주 쉬운 방법입니다 방법을 모르고는 여러 RecyclerView.ViewHolder 유형을 사용하는 것입니다 없습니다 DefaultItemAnimator 애니메이션 작업을 처리하도록합시다. 우리의 모델은 우리의 RecyclerView.AdapterReclerView.ViewHolder이 팽창 알리기 위해 type뿐만 아니라 우리가 표시하고있는 데이터를 포함 할 것입니다

모델 : 여기 그것에 대해 이동하는 방법 중 하나입니다. 우리는 몇 가지 ExpandableModel 데이터를 바인딩하는 기본 ReclerView.ViewHolder을 정의 할뿐만 아니라 좋은 OnClickListener 콜백을 우리에게 제공 할 수

@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

: 그래서,이 (AutoValue) 같이 보일 수 있습니다.

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

01,234,278,398,

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_COLLAPSEDExpandableModeland because DefaultItemAnimator is already applied to RecyclerView으로 전화를 걸면 RecyclerView.Adapter.notifyItemChanged으로 전화하면 RecyclerView.ViewHolder의 두 유형간에 제대로 움직입니다.

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

당신은 생명의 은인입니다 ..... –

관련 문제