代码之家  ›  专栏  ›  技术社区  ›  Ali

RecyclerView中的SmoothScroller

  •  1
  • Ali  · 技术社区  · 8 年前

    我有以下布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fafafa"
        android:orientation="vertical"
        android:paddingBottom="16dp"
        android:paddingEnd="16dp"
        android:paddingLeft="16dp"
        android:paddingStart="16dp">
    
        <View
            android:id="@+id/item_divider"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginBottom="16dp"
            android:background="#D3D3D3" />
    
        <TextView
            android:id="@+id/item_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#000"
            android:textSize="22sp"
            tools:text="Léon: The Professional" />
    
        <LinearLayout
            android:id="@+id/sub_item"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/sub_item_genre"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                tools:text="Genre:  Crime, Drama, Thriller" />
    
            <TextView
                android:id="@+id/sub_item_year"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                tools:text="Year: 1993" />
        </LinearLayout>
    </LinearLayout>
    

    在我的recyclerview适配器中:

    @Override
    public void onBindViewHolder(RecViewHolder holder, int position) {
            Movie movie = list.get(position);
    
            boolean expanded = movie.isExpanded();
            subItem.setVisibility(expanded ? View.VISIBLE : View.GONE);
    
            holder.title.setOnClickListener(v -> {
                boolean expanded = movie.isExpanded();
                movie.setExpanded(!expanded);
                notifyItemChanged(position);
            });
     }
    

    正如您在代码中看到的,当您单击一个项目时,子项目会被隐藏/显示。

    我想实现的是:当您单击列表中的最后一个项目时,我希望它显示整行(包括子项目)。此时,它将可见性更改为VISIBLE,但行的子项对用户不可见 until user scrolls to it

    在下图中 God Father when user clicks ?

    Picture

    1 回复  |  直到 8 年前
        1
  •  2
  •   aminography    8 年前

    如果你滚动到 RecyclerView LinearSmoothScroller 用于滚动。请尝试以下代码:

    public class RecAdapter extends RecyclerView.Adapter<RecAdapter.RecViewHolder> {
    
        private List<Movie> list;
        private RecyclerView mRecyclerView;
        private RecyclerView.SmoothScroller mSmoothScroller;
    
        public RecAdapter(List<Movie> list) {
            this.list = list;
        }
    
        @Override
        public RecViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater
                    .from(parent.getContext())
                    .inflate(R.layout.item_movie, parent, false);
            return new RecViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(RecViewHolder holder, int position) {
            Movie movie = list.get(position);
    
            holder.bind(movie);
    
            holder.itemView.setOnClickListener(v -> {
                boolean expanded = movie.isExpanded();
                movie.setExpanded(!expanded);
                notifyItemChanged(position);
    
                if (movie.isExpanded()) {
                    mSmoothScroller.setTargetPosition(position);
                    new Handler().postDelayed(() -> mRecyclerView.getLayoutManager().startSmoothScroll(mSmoothScroller), 100);
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return list == null ? 0 : list.size();
        }
    
        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            mRecyclerView = recyclerView;
    
            mSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
                @Override
                protected int getVerticalSnapPreference() {
                    return LinearSmoothScroller.SNAP_TO_ANY;
                }
    
                @Override
                protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                    return 150f / displayMetrics.densityDpi;
                }
            };
        }
    
        public class RecViewHolder extends RecyclerView.ViewHolder {
    
            private TextView title;
            private TextView genre;
            private TextView year;
            private View subItem;
    
            public RecViewHolder(View itemView) {
                super(itemView);
    
                title = itemView.findViewById(R.id.item_title);
                genre = itemView.findViewById(R.id.sub_item_genre);
                year = itemView.findViewById(R.id.sub_item_year);
                subItem = itemView.findViewById(R.id.sub_item);
            }
    
            private void bind(Movie movie) {
                boolean expanded = movie.isExpanded();
    
                subItem.setVisibility(expanded ? View.VISIBLE : View.GONE);
    
                title.setText(movie.getTitle());
                genre.setText("Genre: " + movie.getGenre());
                year.setText("Year: " + movie.getYear());
            }
        }
    }
    

    结果如下:

    enter image description here