2016-08-23 91 views
10

我想实现一个屏幕,我有一个包含RecyclerView的卡片视图。Scrollable CardView与RecyclerView里面

CardView应该与回收站视图内容的高度相同,这意味着如果RecyclerView有少量项目,我应该看到卡的底部角落和底部阴影,但是如果RecyclerView有很多项目,卡片视图应该与RecyclerView一起“滚动”,以使Cardview的底角和阴影位于RecylerView的底部。

这应该是什么样子时,RecyclerView是在顶部: List at top

当用户开始滚动,顶角消失与RecyclerView滚动: List during scroll

最后,当用户到达RecyclerView的底部,CardView的底角和阴影出现: List at end

从现在开始,我设法实现了一个工作实现通过把CardView内RecyclerView和NestedScrollView内CardView但是这打破了扫视姿势......

<android.support.design.widget.CoordinatorLayout 
    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:clipChildren="false" 
    android:id="@+id/containerLayout" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" 
    android:orientation="vertical" 
    tools:ignore="MissingPrefix"> 

    <android.support.v4.widget.NestedScrollView 
     android:clipToPadding="false" 
     android:layout_height="match_parent" 
     android:layout_width="match_parent" 
     android:paddingBottom="16dp" 
     android:paddingLeft="85dp" 
     android:paddingRight="85dp" 
     android:paddingTop="16dp"> 

     <android.support.v7.widget.CardView 
      android:layout_height="wrap_content" 
      android:layout_width="match_parent" 
      app:cardBackgroundColor="?android:attr/windowBackground"> 

      <android.support.v7.widget.RecyclerView 
       android:id="@+id/recyclerView" 
       android:layout_height="wrap_content" 
       android:layout_width="match_parent"/> 
     </android.support.v7.widget.CardView> 
    </android.support.v4.widget.NestedScrollView> 
</android.support.design.widget.CoordinatorLayout> 

你对我如何能实现这样的设计有任何提示或想法?我想这CoordinatorLayout能帮助我,但我无法找到任何东西...

谢谢

+1

我面临同样的问题。 'android:nestedScrollingEnabled =“false”'修复了扔手势,但如果你的RecyclerView足够大,界面就会超级滞后。你有什么进展吗? – vyndor

+0

@ pdegand59我在想一个没有** NestedScrollView **的解决方案,但是把一个滚动监听器放到一个'RecyclerView'中。当你从下往上滚动时,'CardView'会出现在屏幕上_当你到达物品的末端时,底部会显示出来。这可以通过使用'cardView.animate().y(theNewPosition).setDuration(0).start()'来实现。这只是一个想法,我没有在代码上进行测试。 – JJ86

+1

请注意,在NestedScrollView中使用'RecyclerView'就像在'ScrollView'中使用'LinearLayout'一样。将不会有回收,'RecyclerView'将具有itemHeight * itemCount的高度。如果你不担心这个问题,用'ScrollView'替换'NestedScrollView',你就会有一个手势。 – Oknesif

回答

0

我具有基于Constraintlayout一个建议,我以前使用过。 您可以创建两个Guideline来设置在卷动过程中CardView的开始和结束位置。让我来说明XML为我假设你要离开的屏幕空间约10%是空的顶部视图

<android.support.constraint.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:clipChildren="false" 
android:id="@+id/containerLayout" 
android:layout_height="match_parent" 
android:layout_width="match_parent" 
android:orientation="vertical" 
tools:ignore="MissingPrefix"> 

<android.support.constraint.Guideline 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/guideline" 
    android:orientation="horizontal" 
    app:layout_constraintGuide_percent="0.1"/> 

<android.support.constraint.Guideline 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/guideline2" 
    android:orientation="horizontal" 
    app:layout_constraintGuide_percent="0.9"/> 

<android.support.v7.widget.CardView 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    app:cardBackgroundColor="?android:attr/windowBackground" 

    app:layout_constraintTop_toTopOf="@+id/guideline"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerView" 
     android:layout_height="wrap_content" 
     android:layout_width="match_parent" /> 
</android.support.v7.widget.CardView> 

这里的起始位置。如果你想要更少或更多,请调整。

一旦用户开始滚动,您可以将Cardview的顶部约束调整到父项的顶部,一旦他到达列表的底部,您可以将Cardview的底部约束调整为guideline2,这将使10%下面的屏幕空间。

这应该达到预期的效果,没有太多的性能问题,因为您正在消除滚动视图。

如果您需要我详细说明我的答案的任何部分,请让我知道。

4

提出Oknesif的操纵适配器的想法,我用三个布局(topitem,middleitem,bottomitem)制作了一个适配器,其中包含两个用于topitem和bottomitem的XML可绘制形状。因此,我能够完全摆脱NestedScrollViewCardView

这是什么样子:

enter image description here

这里是代码。首先,MainActivity

public class MainActivity extends AppCompatActivity { 
    final static int LIST_SIZE = 100; 

    final static int TOP = 0; 
    final static int BOTTOM = LIST_SIZE; 
    final static int MIDDLE = 1; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity); 

     final ArrayList<Integer> list = new ArrayList<>(); 
     for (int i = 0; i < LIST_SIZE; i++) { 
      list.add(i); 
     } 

     class Viewholder extends RecyclerView.ViewHolder { 
      TextView textView; 

      Viewholder(View itemView) { 
       super(itemView); 
       textView = itemView.findViewById(R.id.textView); 
      } 
     } 

     RecyclerView recyclerView = findViewById(R.id.recyclerView); 
     final RecyclerView.Adapter<Viewholder> adapter = new RecyclerView.Adapter<Viewholder>() { 
      LayoutInflater inflater = LayoutInflater.from(MainActivity.this); 

      @Override 
      public Viewholder onCreateViewHolder(ViewGroup parent, int viewType) { 
       switch (viewType) { 
        case TOP: 
         return new Viewholder(inflater.inflate(R.layout.topitem, parent, false)); 
        case BOTTOM: 
         return new Viewholder(inflater.inflate(R.layout.bottomitem, parent, false)); 
        case MIDDLE: 
        default: 
         return new Viewholder(inflater.inflate(R.layout.middleitem, parent, false)); 
       } 
      } 

      @Override 
      public void onBindViewHolder(Viewholder holder, int position) { 
       holder.textView.setText(String.valueOf(list.get(position))); 
       if (position != 0 && position != LIST_SIZE - 1) { 
        int color = position % 2 == 0 ? android.R.color.holo_orange_dark : android.R.color.holo_orange_light; 
        holder.itemView.setBackgroundColor(getResources().getColor(color)); 
       } 
      } 

      @Override 
      public int getItemCount() { 
       return LIST_SIZE; 
      } 

      @Override 
      public int getItemViewType(int position) { 
       int itemViewType; 
       switch (position) { 
        case 0: 
         itemViewType = TOP; 
         break; 
        case LIST_SIZE - 1: 
         itemViewType = BOTTOM; 
         break; 
        default: 
         itemViewType = MIDDLE; 
       } 
       return itemViewType; 
      } 
     }; 
     recyclerView.setAdapter(adapter); 
     recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this)); 
    } 
} 

res/layout/activity.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/containerLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerView" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:clipToPadding="false" 
     android:paddingLeft="25dp" 
     android:paddingRight="25dp" /> 
</android.support.design.widget.CoordinatorLayout> 

res/layout/topitem.xml

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/topbackground" 
    android:layout_marginTop="50dp" 
    android:textAlignment="center" 
    android:textColor="@android:color/white" 
    android:textSize="24sp" 
    android:textStyle="bold" /> 

res/layout/middleitem.xml

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textAlignment="center" 
    android:textColor="@android:color/white" 
    android:textSize="24sp" 
    android:textStyle="bold" /> 

res/layout/bottomitem.xml

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/bottombackground" 
    android:layout_marginBottom="50dp" 
    android:textAlignment="center" 
    android:textColor="@android:color/white" 
    android:textSize="24sp" 
    android:textStyle="bold" /> 

res/drawable/topbackground.xml

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <corners 
     android:topLeftRadius="5dp" 
     android:topRightRadius="5dp" /> 
    <solid android:color="@android:color/holo_orange_dark" /> 
</shape> 

res/drawable/bottombackground.xml

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <corners 
     android:bottomLeftRadius="5dp" 
     android:bottomRightRadius="5dp" /> 
    <solid android:color="@android:color/holo_orange_light" /> 
</shape> 

编辑:

添加此行的底部XML项目布局:

android:elevation="12dp" 

更改背景为白色,给出以下结果:

enter image description here

+0

你可以尝试在单元格上有高程的白色背景吗?我确信在每个单元的侧面分离处会有一些阴影重叠。 这就是为什么这样做的目标是在整个列表中仅使用1个cardview的主要原因 – pdegand59

+0

你的影子被夹在侧面。将'clipToPadding =“false”'添加到recyclerview – pdegand59

+0

是的,你是对的。当填充没有被裁剪时以及在所有三种布局都有提升时,会有“阴影”从单元格分离中爬出。但是,在底部布局上使用高程只会给您我刚发布的结果。这是你想要的吗? – kalabalik

1

它只是代码

recycler.setNestedScrollingEnabled(false); 

简单的线条,不要忘记将cardview高度WRAP_CONTENT

相关问题