处理RecyclerView,NestedScrollView和CardView [英] Dealing With RecyclerView, NestedScrollView, and CardView

本文介绍了处理RecyclerView,NestedScrollView和CardView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将在我的应用程序中实现以下用户界面:

I'm going to achieve this UI in my App:

好吧,我之前尝试过的一些方法:

Well, Some ways that I tried before:

1.使用CollapsingToolbarLayout 我将CardViewCardView insid放在了AppBarLAyout中.

1. Using CollapsingToolbarLayout I put my CardView insid of CollapsingToolbarLayout and put them all in AppBarLAyout.

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed" >

            <CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                />
                  <!-- My Views Goes there -->
            </CardView

            <android.support.v7.widget.Toolbar
                android:id="@+id/flexible.example.toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@null"
                app:layout_collapseMode="pin"
                style="@style/ToolBarWithNavigationBack"
                />
        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <RecyclerView
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
    ></RecyclerView>

</android.support.design.widget.CoordinatorLayout>

P.S:我删除了不相关的代码,不要提及我

P.S: I removed unrelated codes, don't mention me

这种方式可以正常工作,但是!!!当CardView的高度高于屏幕高度时,它的内容就会被AppBarLayout接收,并且不会显示给用户

This Way works correctly but!!! When CardView height goes taller than screen height, it's content igonered by AppBarLayout and does not show to user

2.使用NestedScrollView 我将CardViewRecyclerView放在NestedScrollView内.但是问题是,当用户到达RecyclerView的末尾然后再滚动回到顶部时,猛冲变得漫长而麻烦,并停止了一些用户不得不滚动越来越多才能到达顶部的地方!

2. Using NestedScrollView I put CardView and RecyclerView inside NestedScrollView. But the problem is When User Reached To end of RecyclerView and then scroll back to top, fling goes laggy and buggy and stop some where ans user have to scroll more and more to get to top!

<android.support.v4.widget.NestedScrollView
    android:id="@+id/nested_scrollbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:scrollbars="none" >
        <LinearLayout
            android:id="@+id/nested_scrollbar_linear"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

                <android.support.v7.widget.CardView
                    android:id="@+id/flexible.example.cardview"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:cardBackgroundColor="@color/post_card_backgroind"
                    app:cardCornerRadius="0dp"
                    app:cardElevation="0dp">

                </android.support.v7.widget.CardView>

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/list_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="@dimen/four"
                    android:layout_marginEnd="@dimen/four"
                    android:layout_marginLeft="@dimen/four"
                    android:layout_marginRight="@dimen/four"
                    android:layout_marginStart="@dimen/four"
                    android:layout_marginTop="@dimen/four"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

如何解决此问题? 我不想使用为recyclerview标头的适配器,我从其中一些获得了与性能相关的问题.

How can fix this issue?! I don't want use adapters that make header for recyclerview, I got performance related issue from some of them.

答案

RecyclerView放入NestedScrollView并应用.setNestedScrollingEnabled并将其设置为false

Put RecyclerView inside NestedScrollView as you can see in 2 and apply .setNestedScrollingEnabled and set it to false

推荐答案

您应使用

You should use getItemViewType. It is easy and won't create any performance overhead. Change the code in your Adapter like this:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    class CardViewHolder extends RecyclerView.ViewHolder {
        ...
    }

    class ItemViewHolder extends RecyclerView.ViewHolder {
        ...
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return 0; // Card Type
        } else {
            return 1; // Item Type
        };
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         switch (viewType) {
             case 0: 
                 // Card Type
                 return new CardViewHolder(...);
             case 1: 
                 // Item Type
                 return new ItemViewHolder(...);
         }
    }

    // Optional
    // If your data list does not contain CardView data
    // You may need to add extra count in adapter

    @Override
    public final int getItemCount() {
        // Add one count for CardView data
        return list.size() + 1;
    }

    @Override
    public T getItem(int position) {
        // As the position is change because of CardView at position 0
        // So you may have to decrement the corresponding index 
        return list.get(position - 1);
    }
}


如果您不想更新适配器,可以使用

If you don't want to update the adapter, you can use

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
              <!-- Views Goes there -->
        </CardView>
        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            // This is the key
            android:nestedScrollingEnabled="false"/>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

android:nestedScrollingEnabled可通过xml在API级别21中使用.
对于较低的API,请使用Java方法,即recyclerView.setNestedScrollingEnabled(false);ViewCompat.setNestedScrollingEnabled(recyclerView, false);

android:nestedScrollingEnabled is available in API Level 21 through xml.
For lower APIs use java method i.e. recyclerView.setNestedScrollingEnabled(false); or ViewCompat.setNestedScrollingEnabled(recyclerView, false);

注意(12-12-2016)

使用嵌套滚动时.请注意RecyclerView的已知问题,不是按此处 Arpit Ratan ).因此,我建议使用第一个解决方案,即使用 getItemViewType .有关更多详细信息,请参见完整且更好的答案,例如

When using nested scroll. Be aware of the known issue of RecyclerView not recycling views as asked here and here (apparent reason answered by Arpit Ratan and me respectively). So I'll suggest to go with the first solution i.e. using getItemViewType. For more details, see complete and better answers like this or this.


您可以使用 setFullSpan .如果StaggeredGridLayoutManager的方向是垂直的,则可以使用以下代码将其宽度扩展到全屏:

You can use setFullSpan. If the orientation of your StaggeredGridLayoutManager is vertical, you can use the following code to span it's width to full screen:

public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    if (position == 0) {
        StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();
        layoutParams.setFullSpan(true);
    }
}

这篇关于处理RecyclerView,NestedScrollView和CardView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆