6.如何使用CardView制作卡片布局效果

96
作者 Pich
2017.04.04 10:51 字数 332
/**
 * 作者:Pich
 * 原文链接:http://me.woblog.cn/
 * QQ群:129961195
 * 微信公众号:woblog
 * Github:https://github.com/lifengsofts
 */

详解RecyclerView系列文章目录

概述

卡片的效果现在的应用还是很常见的,特别是新闻应用,很适合用这类的布局,先来一张效果图:


同时实现这一的效果也很简单,只需要使用Google提供的CardView。

Item布局

在RecyclerView的item中写入CardView,它相当于一个FrameLayout,因此我们需要将他包裹到最外层。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/card_view_four"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="@dimen/activity_horizontal_margin"
  android:layout_marginLeft="@dimen/activity_horizontal_margin"
  android:layout_marginRight="@dimen/activity_horizontal_margin"
  android:layout_gravity="center"
  android:clickable="true"
  android:foreground="?android:attr/selectableItemBackgroundBorderless"
  app:cardCornerRadius="@dimen/activity_horizontal_margin"
  app:cardElevation="8dp">
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <ImageView
      android:id="@+id/iv"
      android:layout_width="match_parent"
      android:layout_height="100dp"
      android:scaleType="centerCrop"
      android:src="@mipmap/ic_launcher" />
    <TextView
      android:id="@+id/tv"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:padding="5dp"
      android:text="这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本" />
  </LinearLayout>
</android.support.v7.widget.CardView>

这里使用了几个常用的属性:

foreground:设置了他在Api21以后就有水波效果

cardCornerRadius:圆角的半径

cardElevation:阴影的大小

其他的属性我们在分析CardView的源码的时候详细讲解。

接下来就很简单了,使用我们前面说的方法显示这个Item就有上面的效果了。

自动计算Item高度(可选)

可以发现上面的Item中的图片是写死的,其他我们是可以动态计算出来的,让每个图片都最大显示,这样美观点,关键点就是在bindData方法中:

//如果有高度,就直接取出来不用再计算了
final Integer height = heights[position];
if (height == 0) {
  //没有高度,需要计算
  Glide.with(CardViewActivity.this).load(d).diskCacheStrategy(DiskCacheStrategy.ALL)
      .into(new SimpleTarget<GlideDrawable>() {
        @Override
        public void onResourceReady(GlideDrawable resource,
            GlideAnimation<? super GlideDrawable> glideAnimation) {
          Log.d("TAG", iv.getWidth() + "," + resource.getIntrinsicWidth());
          //计算ImageView的高度
          int imageWidth = resource.getIntrinsicWidth();
          int imageHeight = resource.getIntrinsicHeight();
          int imageViewWidth = iv.getWidth();

          double scale = imageWidth * 1.0 / imageViewWidth;
          LayoutParams layoutParams = iv.getLayoutParams();
          int h = (int) (imageHeight / scale);
          layoutParams.height = h;
          iv.setLayoutParams(layoutParams);
          iv.setImageDrawable(resource);

          heights[position]=h;
        }
      });
} else {
  //已经计算了,直接拿出来用
  LayoutParams layoutParams = iv.getLayoutParams();
  layoutParams.height = height;
  iv.setLayoutParams(layoutParams);

  Glide.with(CardViewActivity.this).load(d).diskCacheStrategy(DiskCacheStrategy.ALL)
    .into(iv);
}

这样就出现了这样的效果


这个计算方法也可以用到前面我们讲的瀑布流效果中,这样就可以解决Item不会到处跳动了。

RecyclerView