android精美卡片式布局Cardview_RecyclerView

Posted 轻烟散入五侯家

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android精美卡片式布局Cardview_RecyclerView相关的知识,希望对你有一定的参考价值。

一、activity_main.xml要这么写,其中主要是包含一个RecyclerView.

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">
<!--    CoordinatorLayout是一个加强版的FrameLayout-->
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
<!--        AppBarLayout实际是一个垂直方向的LinearLayout,它在内部做了很多滚动事件的封装-->
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
<!--            将layout_scrollFlags的属性指定成了scroll|enterAlways|snap,scroll表示当RecyclerView向上滚动的时候,Toolbar会跟着一起向上滚动并实现隐藏。-->
<!--            enterAlways表示当RecyclerView向下滚动的时候,Toolbar会跟着一起向下滚动并重新显示。snap表示当Toolbar还没有完全隐藏或显示的时候,会根据当前滚动的-->
<!--            距离,自动选择是隐藏还是显示。-->
            <androidx.appcompat.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"
                app:layout_scrollFlags="scroll|enterAlways|snap"/>
        </com.google.android.material.appbar.AppBarLayout>

        <!-- 下面layout_behavior使用ScrollingViewBehavior这个布局行为,这样recyclerview_view这个控件就不会遮挡上面的toolbar,而且当recyclerview_view滚动的时候会把滚动事件通知给上面的toolbar-->
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.drawerlayout.widget.DrawerLayout>

二、RecyclerView子项所需要的一个实体类Fruit,要这么写

package com.example.magicalpai.beautiful_cardview;

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;
    }
}

三、RecyclerView子项对应的布局fruit_item.xml,要这么写

<?xml version="1.0" encoding="utf-8"?>
<!--这个是为recycler_view的子项指定的布局-->
<!--CardView也是一个FrameLayout,只是额外提供了圆角和阴影的效果。这里使用CardView来作为子项的最外层布局,从而使得RecyclerView中的每个元素都是在卡片当中的。-->
<androidx.cardview.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:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/fruit_image"
            android:layout_width="match_parent"
            android:layout_height="100dp"/>
<!--        下面这条被注释的的代码会让图片保持原有比例填满ImageView,超出的部分将被裁切掉-->
<!--            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>
</androidx.cardview.widget.CardView>

四、RecyclerView 的适配器FruitAdapter类,要这么写

package com.example.magicalpai.beautiful_cardview;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.magicalpai.R;

import java.util.List;

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private Context mContext;
    private List<Fruit> mFruitList;
    static class ViewHolder extends RecyclerView.ViewHolder {
        CardView cardView;
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(View view) {
            super(view);
            cardView = (CardView) view;
            fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            fruitName = (TextView) view.findViewById(R.id.fruit_name);
        }
    }
    public FruitAdapter(List<Fruit> fruitList) {
        mFruitList = fruitList;
    }
    @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);
        final ViewHolder holder = new ViewHolder(view);
        //为每一个子项的cardView注册事件
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText(v.getContext(), "you clicked image " + fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruitName.setText(fruit.getName());
        /*
        Glide的用法:调用Glide.with()方法并传入一个Context、Activity或Fragment参数,然后调用load()方法去加载图片,
        可以是一个URL地址,也可以是一个本地路径,或者是一个资源id,最后调用into()方法将图片设置到具体某一个ImageView中就可以了
        Glide会对高清图片进行压缩,这样就不会发生内存溢出的问题了
        使用Glide,在app/build.grade文件中添加implementation 'com.github.bumptech.glide:glide:3.8.0即可
        */
        Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
    }
    @Override
    public int getItemCount() {
        return mFruitList.size();
    }
}

五、主方法MainActivity,要这么写

package com.example.magicalpai.beautiful_cardview;

import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;

import com.example.magicalpai.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    private Fruit[] fruits = {new Fruit("Apple", R.drawable.apple), new Fruit("Banana",R.drawable.banana), new Fruit("Watermelon",R.drawable.watermelon)};
    private List<Fruit> fruitList = new ArrayList<>();
    private FruitAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView=(RecyclerView)findViewById(R.id.recycler_view);
        //GridLayoutManager的构造方法接收两个参数,第一个是Context,第二个是列数,这里我们希望每一行中会有两列数据
        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 < 50; i++) {
            Random random = new Random();
            int index = random.nextInt(fruits.length);
            fruitList.add(fruits[index]);
        }
    }
}

六、这样就可以实现以下效果
在这里插入图片描述
滚动界面toolbar会自动隐藏,点击第一个水果还会有相应的提示。

以上是关于android精美卡片式布局Cardview_RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

安卓笔记——卡片布局

卡片布局CardView

Android实现叠加卡片效果

列表卡片效果

Android 布局管理器

Android StackView 类型的横向滑动布局