相同滚动下的水平和垂直RecyclerView

时间:2018-07-25 15:41:25

标签: android android-recyclerview instagram android-scrollview android-nestedscrollview

我必须做类似Instagram的事情。我有一个用于故事的水平RecyclerView,下面有一个用于Feed的垂直RecyclerView。我想完成相同的滚动行为(故事应与滚动一起进行,而不是固定不变)。我找到的唯一解决方案是NestedScrollView,但它对RecyclerViews的性能造成极大的影响,我的屏幕几乎永远死机。我尝试了很多技巧,例如nestedScrollEnabled,autoLayoutMeasure等,但没有任何效果。谢谢。

2 个答案:

答案 0 :(得分:2)

抱歉,如果这种解释过于抽象。让我知道您是否需要我更加露骨。

public class VerticalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

private static final int TYPE_HEADER = 0;
private static final int TYPE_POST = 1;

List<Post> posts;
List<FeedItems> feedItems; //this array is going to populate the horizontal recycler view. Notice that is passed it on the adapter constructor

public VerticalAdapter(List<Post> posts,List<FeedItems> feedItems) {
    this.posts = posts;
    this.feedItems = feedItems;
}

public void notifyFeedChanged(List<FeedItems> newFeedItems){
    this.feedItems.clear();
    this.feedItems = newFeedItems; //set the new feed items in the array
    notifyItemChanged(0); //tell the main recycler view "Hey, update your first position". This will cause the onBindViewHolder to be called again an thus, the new items will be set into the horizontal recycler view
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    if (viewType == TYPE_HEADER)
        return new HeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.your_header_layout, false));
    else if (viewType == TYPE_POST)
        return new HeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.your_post_layout, false));

    throw new RuntimeException("Don't know this type");
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {


    if (holder instanceof HeaderViewHolder){
        //set adapter for the horizontal recycler view
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(((HeaderViewHolder) holder).recyclerView.getContext(),LinearLayoutManager.HORIZONTAL, false)
        ((HeaderViewHolder) holder).recyclerView.setLayoutManager(linearLayoutManager);

        if (((HeaderViewHolder) holder).recyclerView.getAdapter() == null){ //only create the adapter the first time. the following times update the values
            AnotherAdaterYouNeedToCreateForTheHorizontalRecyclerView adapter = new AnotherAdaterYouNeedToCreateForTheHorizontalRecyclerView(feedItems);
            ((HeaderViewHolder) holder).recyclerView.setAdapter(adapter);
        }else {
            ((HeaderViewHolder) holder).recyclerView.getAdapter().notifyDataSetChanged();
        }

    }else if (holder instanceof PostViewHolder){
        //just do the normal post binding
    }
}

@Override
public int getItemCount() {
    return posts.size() + 1; // +1 because of the header
}

@Override
public int getItemViewType(int position) {
    return position == 0 ? TYPE_HEADER : TYPE_POST;
}

private class HeaderViewHolder extends RecyclerView.ViewHolder{

    RecyclerView recyclerView;

    public HeaderViewHolder(View itemView) {
        super(itemView);
        recyclerView = itemView.findViewById(R.id.the_recycler_view_id_on_the_heaedr_layout_file);
    }
}

private class PostViewHolder extends RecyclerView.ViewHolder{

    ImageView imageView;

    public PostViewHolder(View itemView) {
        super(itemView);
        imageView = itemView.findViewById(R.id.post_image_view_or_whatever);
    }
}

}

因此,您的垂直recyclerview垂直绘制了Post项目(或您的post类是什么),这很容易实现。现在,对于水平视图,您应该实现一个recyclerview标头(请查看我的Adapter示例)。页眉布局将具有另一个水平的recyclerview。

答案 1 :(得分:0)

在XML布局中,尝试将“标题”回收者视图和“张贴”回收者视图都保留在嵌套滚动视图中。它对我有用。

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
    android:background="#FFFFFF">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/tv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingStart="16dp"
                    android:paddingTop="8dp"
                    android:text="Welcome"
                    android:textAppearance="@style/TextAppearance.AppCompat.Large"
                    android:textColor="#000000"
                    android:textSize="24sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/date"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingStart="16dp"
                    android:paddingTop="8dp"
                    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                    android:textColor="@color/black_80" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    android:orientation="horizontal" />
            </LinearLayout>

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rvv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" />

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>
相关问题