CardView、CoordinatorLayout

CardView:

一、简介:
Android5.0新增了一个全新的控件–CardView,从本质上看,可以将CardView看做是FrameLayout在自身之上添加了圆角和阴影效果。请注意:CardView被包装为一种布局,并且经常在ListView和RecyclerView的Item布局中,作为一种容器使用。
CardView应该被使用在显示层次性的内容时;在显示列表或网格时更应该被选择,因为这些边缘可以使得用户更容易去区分这些内容。
比如以下效果可以用cardview来做:
920262.png










二、基本使用:
首先在gradle中加入cardview:
compile 'com.android.support:cardview-v7:23.4.0'

cardview实际上就是一个layout,里面可以放置你想要显示的控件,它让这些控件看上去像是包裹在一个卡片里
CardView继承于Framelayout,所以Framelayout的属性他都有,除此之外,还有很多自定义的属性
以第一张图片的布局为例:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray"
android:orientation="vertical"
tools:context=".MainActivity">

<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="200dp"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="#303069"
card_view:cardCornerRadius="10dp"

card_view:cardUseCompatPadding="true"
card_view:contentPadding="10dp">

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

<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:textColor="@android:color/white" />

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Content"
android:textColor="@android:color/white" />
</LinearLayout>
</android.support.v7.widget.CardView>

<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="300dp"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="#FFC456"
card_view:cardCornerRadius="10dp"

card_view:cardUseCompatPadding="true"
card_view:cardElevation="20dp"
card_view:contentPadding="10dp">

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

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:textColor="@android:color/white" />

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Content\n\tCradView挺漂亮的"
android:textColor="@android:color/white" />
</LinearLayout>
</android.support.v7.widget.CardView>

<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="#ffffff"
card_view:cardCornerRadius="10dp"

card_view:cardUseCompatPadding="true">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/aaa" />

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

</LinearLayout>
cardBackgroundColor:卡片的背景色
cardCornerRadius:四个角的圆角半径

cardUseCompatPadding:当设置了阴影,同时设置了这个值为true,则会自动根据阴影设置合适的内容边距,以显示全部的阴影(实际上是内边距,阴影也是cardview的一部分),如果设置为false则不会,这样如果阴影值很大,可能部分阴影区域看不到,默认false(可能不同版本系统不一样)
contentPadding:设置里面子控件的内边距,可以分别设置上下左右的边距,比如contentPaddingLeft
cardElevation:阴影的大小


三、点击动画:

5.0以上系统对cardview添加以下2个属性,点击时会有波纹效果:
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
5.0以下系统添加这个,点击时颜色会变深,但是不会有波纹效果


四、练习:CardView+RecyclerView(多布局):


307113.png

文字对应的布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/cardview_text"
c
card:cardCornerRadius="10dp"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="abc"
android:textSize="20sp"
android:gravity="center"/>

</android.support.v7.widget.CardView>
图片对应的布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="10dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/bbb"/>

</android.support.v7.widget.CardView>
adapter:
package com.example.zhouyi.cardviewtest;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
* Created by zhouyi on 16/6/19.
*/
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context mContext;

public MyAdapter(Context context){
mContext = context;
}



class TextViewHolder extends RecyclerView.ViewHolder{

public TextViewHolder(View itemView) {
super(itemView);
}
}

class ImageViewHolder extends RecyclerView.ViewHolder{
public ImageViewHolder(View itemView) {
super(itemView);
}
}



@Override
public int getItemViewType(int position) {
return position%2;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 0){
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_textitem,parent,false);
return new TextViewHolder(view);
}else {
return new ImageViewHolder(LayoutInflater.from(mContext).
inflate(R.layout.
layout_imageitem,null));
}
}

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

}

@Override
public int getItemCount() {
return 10;
}
}
注意如果要item布局的根元素设置的宽高起作用,必须在inflate的时候指定parent不为null,因为布局的宽高是相对父布局的,只有知道父布局才能起作用






CoordinatorLayout:



一、简介:
CoordinatorLayout使用新的思路通过协调调度子布局的形式实现触摸影响布局的形式产生动画效果。
主要实现以下效果:

  • 让浮动操作按钮上下滑动,为Snackbar留出空间。



  • 扩展或者缩小Toolbar或者头部,让主内容区域有更多的空间。







使用CoordinatorLayout时要注意以下几点:
1.CoordinatorLayout继承自ViewGroup
2. CoordinatorLayout应该做为顶层布局出现
3. CoordinatorLayout里面使用的滑动控件最好是5.0以后的新控件,比如用recyclerview,而不是listview,用nestedscrollview,而不是scrollview
4.必须导入design包支持

二、基本效果的实现:
  • 浮动操作按钮与Snackbar

默认情况下,如果FloatingActionButton放在底下,有可能跟下面弹出的snackbar重叠
把FloatingActionButton放到CoordinatorLayout中则会自动检测重叠,如果有重叠,就会把FloatingActionButton往上移动以避开重叠
<android.support.design.widget.CoordinatorLayout


android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.zhouyi.coordinatorlayouttest.MainActivity"
xmlns:android="http://schemas.android.com/apk/res/android">

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@mipmap/ic_launcher" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:onClick="onClick"
android:text="click" />


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

public void onClick(View view) {
Snackbar snackbar = Snackbar.make(view,"abc",Snackbar.LENGTH_INDEFINITE);
snackbar.show();
}
  • Toolbar的扩展与收缩

当Toobar底下有一个滑动控件(比如recyclerview),可以关联toolbar和这个滑动控件,当滑动控件滑动时,toolbar可以随之扩展或收缩,甚至消失或重现

首先,程序中要用Toobar代替Actionbar
在风格中设置没有actionbar:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

代码中设置toolbar:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("abcd");
this.setSupportActionBar(toolbar);

布局:
首先,顶层布局还是CoordinatorLayout,为了关联toolbar和recyclerview的滑动事件,需要做以下3件事情:
1.需要有一个AppBarLayout的布局包裹到Toolbar之上
2.Toolbar设置layout_scrollFlags自定义属性:
scroll:要随滑动控件一起滑动,必须设置这个标示,否则不会动
enterAlways:只要滑动控件向下滑动,toolbar就会出现
enterAlwaysCollapsed:滑动控件向下滑动时,只有到达滑动控件的顶部(比如recyclerview的第一个item出现),toolbar才会出现
exitUntilCollapsed:等下讲折叠的时候再看这个标志
3.滑动控件设置layout_behavior,这里设置为appbarlayout默认的behavior

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/rctest"/>
</android.support.design.widget.CoordinatorLayout>


  • 制造折叠效果


1.appbarlayout设置一个高度,这个高度是展开后的最大高度
2.toolbar不能直接放入appbarlayout中了,需要再包一层 collapsingtoolbarlayout
3.layout_scrollflags设置到collapsingtoolbarlayout中,设置为scroll和exituntilcollapsed,exituntilcollapsed代表完全折叠后,toolbar不会消失,如果只设置了scroll,则toolbar会滑出屏幕外
4.在appbarlayout中设置app:expanded="false"可以控制初始状态下不展开

collapsingToolbarLayout中其他属性设置:
expandedTitleMarginStart:toolbar向下扩展的时候,里面的title向右偏移的距离
contentScrim:toolbar的填充色


<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout

android:layout_width="match_parent"
android:layout_height="256dp">

<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="100dp"
android:id="@+id/collaspetoolba"
app:layout_scrollFlags="scroll|exitUntilCollapsed">


<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
/>


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

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


<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/rctest"/>
</android.support.design.widget.CoordinatorLayout>

CollapsingToolbarLayout中还可以放入其他控件,比如一个imageview,这样这个imageview也可以随着滑动控件一起滑动
可以设置以下属性,控制滑动的动画效果:
layout_collapseMode:设置为pin,则图片会随着滑动控件向上滑动知道消失,设置为parallax,会有一个折叠的视差,这个视差由app:layout_collapseParallaxMultiplier控制(0到1),值越小,视差越明显,设置为1时,图片固定不动,设置为0时没有视差(跟pin一样)
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout

android:layout_width="match_parent"
android:layout_height="256dp">

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collaspetoolba"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="100dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/bbb"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.1"
/>


<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"

/>

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

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


<android.support.v7.widget.RecyclerView
android:id="@+id/rctest"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.C oordinatorLayout>

还可以在recyclerview和appbarlayout之间放一个浮动按钮(放在coordinatorlayout中的recyclerview之后):
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
android:src="@mipmap/ic_launcher"
android:layout_margin="10dp"
android:clickable="true"/>

anchor控制按钮放在那个控件里,anchorgravity控制按钮放在控件的什么位置

recyclerview也可以用一个nestedscrollview替换:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed"/>
</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/nstscrollview">
<TextView
android:layout_width="match_parent"
android:layout_height="1000dp"
android:layout_gravity="bottom"
android:text="abcdef"/>

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

nestedscrollview相当于scrollview,只是scrollview不会产生滑动动画
NestedScrollview可以嵌套recyclerview,不会有滑动冲突
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
android:id="@+id/appbarlayout"
android:layout_width="match_parent"
android:layout_height="256dp">

<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@color/colorAccent"
app:expandedTitleMarginStart="200dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/aaa" />


<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="50dp" />

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

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

<android.support.design.widget.FloatingActionButton

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
app:layout_anchor="@id/appbarlayout"
app:layout_anchorGravity="right|bottom"
app:useCompatPadding="true" />

<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/scrollview">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:focusableInTouchMode="true"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="fitXY"
android:src="@drawable/aaa"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rcvtest"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>




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


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


listview也可以放在 CoordinatorLayout,如果要产生滑动动画,需要api19以后的sdk支持,再代码里调用:
ListView lsttest = (ListView) findViewById(R.id.lsttest);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
lsttest.setNestedScrollingEnabled(true);
}




三、自定义behavior
CoordinatorLayout里面的动画都是由behavior控制的,也可以自己写behavior,可以参照sdk里的源码来写,以FloatingActionButton为例,找到里面定义的behavior,分析其中的关键代码,我们可以照着写一个自己的behavior:
因为behavior等下要到xml中配置,所以第二个构造函数不能省,否则报错
主要重写2个方法,layoutDependsOn判断依赖的控件是不是snackbar(只对snackbar做处理),ondependentviewchanged在snackbar向上或向下滑动时会实时调用,在这里,我们得到snackbar移动的距离,同时对按钮做旋转操作
public class RotateBehavior  extends CoordinatorLayout.Behavior<FloatingActionButton>{

public RotateBehavior() {
}

public RotateBehavior(Context context, AttributeSet attrs) {
super(context,attrs);
}

@Override
public boolean layoutDependsOn(CoordinatorLayout parent,
FloatingActionButton child, View dependency) {
// We're dependent on all SnackbarLayouts (if enabled)
return dependency instanceof Snackbar.SnackbarLayout;
}

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child,
View dependency) {
float translationY = getFabTranslationYForSnackbar(parent, child);
float percentComplete = -translationY / dependency.getHeight();
child.setRotation(-90 * percentComplete);
child.setTranslationY(translationY);
return false;

}

private float getFabTranslationYForSnackbar(CoordinatorLayout parent,
FloatingActionButton fab) {
float minOffset = 0;
final List<View> dependencies = parent.getDependencies(fab);
for (int i = 0, z = dependencies.size(); i < z; i++) {
final View view = dependencies.get(i);
if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) {
minOffset = Math.
min(minOffset,
ViewCompat.getTranslationY(view) - view.getHeight());//考虑多个snackbar,取最大高度的(负值最小),snackbar最初始位置是底部和屏幕底部对齐,展示出来之前会先移动到顶部和屏幕屏幕底部对齐,所以向上展示的过程中, ViewCompat.getTranslationY(view)是正数,只是向上展示的过程中,正数的值越来越少 }  
 }
return minOffset;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值