1. 程式人生 > >FC 12.5 卡片式佈局

FC 12.5 卡片式佈局

CardView是實現卡片式佈局的重要控制元件(appcompat-v7),它是FrameLayout的加強版,只是額外增加了圓角和投影的效果,立體感。

CardView 的基本用法

  • 定義CardView佈局,通過app:cardCornerRadius屬性指定卡片圓角的弧度;

  • app:elevation屬性指定卡片的高度。與FloatingActionButton一致。

  • 將TextView放置在CardView中,這樣TextView就會顯示在卡片中了。

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        app:cardCornerRadius="4dp"
        android:elevation="5dp"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/tv_info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </android.support.v7.widget.CardView>

前幾篇文章,已經實現了很多Material Design效果,但是螢幕上的主要的區域還處於空白狀態,這裡,我們使用RecycleView來填充這個專案的主介面部分。

使用卡片佈局

新增依賴

compile 'com.android.support:cardview-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
compile 'com.github.bumptech.glide:glide:4.0.0-RC0'

(Glide庫是一個超級強大的圖片載入庫,不僅可以載入本地圖片,也可以載入網路圖片,GIF圖片,甚至是本地視訊。 )

修改antivity_main.xml(新增RecycleView)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_Layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/ic_done"
            app:elevation="8dp" />
    </android.support.design.widget.CoordinatorLayout>
    ...
</android.support.v4.widget.DrawerLayout>

新建實體類Fruit

public class Fruit {
    private String name;
    private int imageId;
    public Fruit(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }
    public String getName() {
        return name;
    }
    public int getImageId() {
        return imageId;
    }
}

定義RecycleView的子項佈局fruit_item.xml檔案

  • 使用CardView作為子項的最外層佈局(這樣RecycleeView每個元素都是卡片當中的)
  • Image中使用了scaleType屬性,指定圖片的縮放式。centerCrop(原有圖片充滿ImageView)。
<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/fruit_image"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop" />
        <TextView
            android:id="@+id/fruit_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp" />
    </LinearLayout>
</android.support.v7.widget.CardView>

為RecycleView準備FruitAdapter介面卡

Glide的用法:首先呼叫Glide的with()方法並傳入一個Context,Activity或Fragment引數,然後呼叫load()方法,傳入圖片的URL地址,也可以是本地路徑,或者是id,接著呼叫info()方法設定到具體的哪個ImageView

(因為圖片畫素很高,如果不進行壓縮就展示的話很容易引起記憶體溢位,使用Glide就不用更擔心了,因為Glide內部做了很多複雜的邏輯,包括了圖片壓縮,我們只需要按照Glide的標準去載入圖片就好了)

public class FruitAdapter extends RecyclerView.Adapter <FruitAdapter.ViewHolder>{
    private Context mContext;
    public FruitAdapter(List<Fruit> mFruitList) {
        this.mFruitList = mFruitList;
    }
    private List<Fruit> mFruitList;
    static class ViewHolder extends RecyclerView.ViewHolder {
        CardView cardView;
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(View view) {
            super(view);
            cardView = (CardView) itemView;
            fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            fruitName = (TextView) view.findViewById(R.id.fruit_name);
        }
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mContext == null) {
            mContext = parent.getContext();
        }
        View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item, parent, false);
        return new ViewHolder(view);
    }
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruitName.setText(fruit.getName());
        Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
    }
    @Override
    public int getItemCount() {
        return mFruitList.size();
    }
}

準備圖片

這裡使用郭神提供的精美的水果圖片【圖片地址:點我

修改MainActivity

  • 定義fruitList陣列,存放多個Fruit例項
  • initFruits方法,首先清空陣列fruitList中的束縛,然後使用隨機函式隨機生成水果新增到fruitList中。
  • 使用GridLayoutManager,第一個引數是Context,第二個引數是列數,這裡我們設定為兩列。
public class MainActivity extends AppCompatActivity {

    private DrawerLayout mDrawerLayout;
    private List<Fruit> fruitList = new ArrayList<>();
    private FruitAdapter adapter;
    private Fruit[] fruits = {new Fruit("Apple", R.drawable.apple), new Fruit("Banana", R.drawable.banana),
            new Fruit("Orange", R.drawable.orange), new Fruit("Watermelon", R.drawable.watermelon),
            new Fruit("Pear", R.drawable.pear), new Fruit("Grape", R.drawable.grape),
            new Fruit("Pineapple", R.drawable.pineapple), new Fruit("Strawberry", R.drawable.strawberry),
            new Fruit("Cherry", R.drawable.cherry), new Fruit("Mango", R.drawable.mango)};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        initFruits();
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycle_view);
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);

        ...
       
    }

    ...

    private void initFruits() {//初始化水果列表
        fruitList.clear();
        for (int i = 0; i < 25; i++) {
            Random random = new Random();
            int index = random.nextInt(fruits.length);
            fruitList.add(fruits[index]);
        }
    }

執行,結果如圖