1. 程式人生 > >6.如何使用CardView製作卡片佈局效果

6.如何使用CardView製作卡片佈局效果

/**
 * 作者: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不會到處跳動了。