7

我将在我的应用程序中实现这个 UI: 用户界面

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

1.使用CollapsingToolbarLayout 我把我CardViewCollapsingToolbarLayout内部和把它们都放在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>

PS:我删除了无关代码,别提我了

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

2. 使用NestedScrollView I putCardViewRecyclerViewinside NestedScrollView。但问题是当用户到达 RecyclerView 的末尾然后滚动回顶部时,fling 变得迟缓和错误并停止一些用户必须越来越多地滚动才能到达顶部的地方!

<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 制作标题的适配器,我从其中一些那里得到了与性能相关的问题。

回答

如您在2中看到的那样放入RecyclerView内部并应用并将其设置为NestedScrollView.setNestedScrollingEnabledfalse

4

2 回答 2

10

您应该使用getItemViewType。这很容易,不会产生任何性能开销。像这样更改代码Adapter

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);
    }
}


更新 1

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

<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);

注意(2016 年 12 月 12 日)

使用嵌套滚动时。请注意 RecyclerView 的已知问题,而不是按照此处此处的要求回收视图( Arpit Ratan分别回答了明显的原因)。所以我建议使用第一个解决方案,即使用getItemViewType。有关更多详细信息,请参阅完整和更好的答案,例如thisthis


更新 2

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

public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    if (position == 0) {
        StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();
        layoutParams.setFullSpan(true);
    }
}
于 2016-05-25T13:27:53.157 回答
4

2.使用中的问题

但问题是当用户到达 RecyclerView 的末尾然后滚动回顶部时

可以通过android:descendantFocusability="blocksDescendants在第一个布局中添加来处理,NestedScrollView如下所示:

<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:descendantFocusability="blocksDescendants" >

它对我有用。NestedScrollView 在 Recyclerview 调整大小时滚动到顶部

于 2017-05-02T09:37:38.627 回答