Material Design学习(四)——卡片式布局

继续使用上篇文章的项目,拷贝一份并改名为day20_CardView

一、CardView

CardView也是FrameLayout的一种,不过提供了额外的圆角和阴影等效果

1、添加依赖

    implementation 'androidx.recyclerview:recyclerview:1.1.0' // 瀑布布局
    implementation 'androidx.cardview:cardview:1.0.0' // 卡片布局
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' // 加载图片的库

2、主布局

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/recycler_view"/>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/fab"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/done"/>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

3、实体类

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

4、菜单项布局

fruit_item_xml
scaleType指定缩放属性,centerCrop按比例缩放填满imageView

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop"
            android:id="@+id/fruit_image"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/fruit_name"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp"/>
        
    </LinearLayout>

</androidx.cardview.widget.CardView>

5、适配器

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 = view.findViewById(R.id.fruit_image);
            fruitName = view.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List<Fruit> fruitList){
        mFruitList = fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull 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(@NonNull 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();
    }
}

Glide用来加载图片:
Glide.with()参数传入ContextActivityFragment
load()加载图片,可以是URL或本地路径,甚至是资源id
into()设置到某个资源里

6、主活动

public class MainActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    private Fruit[] fruits = {
            new Fruit("苹果", R.drawable.the_apple), new Fruit("香蕉", R.drawable.the_banana),
            new Fruit("鸭梨", R.drawable.the_pear), new Fruit("葡萄", R.drawable.the_grape),
            new Fruit("菠萝", R.drawable.the_pinapple), new Fruit("草莓", R.drawable.the_strawberry),
            new Fruit("樱桃", R.drawable.the_cherry), new Fruit("芒果", R.drawable.the_mango)};
    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 = findViewById(R.id.recycler_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 < 50; i++){
            Random random = new Random();
            int index = random.nextInt(fruits.length);
            fruitList.add(fruits[index]);
        }
    }
    
}

代码没啥好解释的,看不懂就多写几遍

【参考文章】
运行:
在这里插入图片描述
但是发现,ToolBar怎么被RecyclerView遮住了?!
解决这个问题就要借助AppBarLayout

二、AppBarLayout

因为CoordinatorLayout属于FrameLayout,所以内部元素会自动在摆放在左上角,从而产生被遮挡现象。这个问题可以通过偏移来解决,但不是最好的办法。

AppBarLayout 实际上是一个垂直方向的LinearLayout,在内部做了许多滚动事件的封装,并应用了Material Design的设计理念

使用方法:

  1. Toolbar 嵌套到AppBarLayout
  2. RecyclerView指定一个布局行为:app:layout_behavior="@string/appbar_scrolling_view_behavior"

主布局:

。。。。。。
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:background="?attr/colorPrimary"
            android:layout_height="?attr/actionBarSize"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        </com.google.android.material.appbar.AppBarLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/recycler_view"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
。。。。。。

运行:
在这里插入图片描述
这次虽然取消了遮挡,但是没体现出Material Design的优势
ToolBar再设置一个属性:

app:layout_scrollFlags="scroll|enterAlways|snap"
  • scroll :当RecyclerView向上滚动时,Toolbar跟着向上滚动,并隐藏
  • enterAlways:当RecyclerView向下滚动时,Toolbar一起向下滚动并重新显示
  • snapToolbar再没有完全隐藏或显示时,根据滚动举例,自动选择隐藏还是显示

运行:
在这里插入图片描述

发布了180 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41205771/article/details/104418823