Android MaterialList源码解析

本文详细解析了Android库MaterialList的源码,包括功能介绍、总体设计、详细设计和自定义布局。MaterialList用于创建具有Material Design风格的ListView,支持滑动移除ItemView,通过CardProvider和Builder模式实现内容组装。文章还介绍了如何扩展布局,通过继承和自定义Action实现新功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MaterialList源码解析

项目地址:MaterialList,分析的版本:v3.2.2,Demo 地址:MaterialList Demo

本文结构

  • 1、功能介绍
  • 2、总体设计
  • 3、详细设计
  • 4、MaterialList自定义布局
  • 5、总结

1. 功能介绍

1.1 简介

MaterialList是一个帮助Android开发者获取漂亮CardView的Android库,通过这个库你可以很容易实现具有Material Design风格的ListView,MaterialList中内置了7种类型的CardView,

1.2 如何使用

首先,在你的layout中声明一个MaterialListView:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <com.dexafree.materialList.view.MaterialListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/material_listview"/>

</RelativeLayout>

接着,绑定MaterialListView到一个变量,并设置Item动画

mListView = (MaterialListView) findViewById(R.id.material_listview);
mListView.setItemAnimator(new SlideInLeftAnimator());
mListView.getItemAnimator().setAddDuration(300);
mListView.getItemAnimator().setRemoveDuration(300);

然后设置dismiss监听和ItemTouchListener

// Set the dismiss listener
mListView.setOnDismissCallback(new OnDismissCallback() {
    @Override
    public void onDismiss(@NonNull Card card, int position) {
                // Show a toast
         Toast.makeText(mContext, "You have dismissed a " + card.getTag(), Toast.LENGTH_SHORT).show();
            }
        });
// Add the ItemTouchListener
        mListView.addOnItemTouchListener(new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(@NonNull Card card, int position) {
                Log.d("CARD_TYPE", "" + card.getTag());
            }

            @Override
            public void onItemLongClick(@NonNull Card card, int position) {
                Log.d("LONG_CLICK", "" + card.getTag());
            }
        });

最后添加Card

 mListView.getAdapter().addAtStart(new Card.Builder(this)
                .setTag("BASIC_IMAGE_BUTTONS_CARD")
                .setDismissible()
                .withProvider(new CardProvider())
                .setLayout(R.layout.material_basic_image_buttons_card_layout)
                .setTitle("Hi there")
                .setDescription("I've been added on top!")
                .addAction(R.id.left_text_button, new TextViewAction(this)
                        .setText("left")
                        .setTextResourceColor(R.color.black_button))
                .addAction(R.id.right_text_button, new TextViewAction(this)
                        .setText("right")
                        .setTextResourceColor(R.color.orange_button))
                .setDrawable(R.drawable.dog)
                .endConfig()
                .build());

通过给Provider设置不同的layout,从而获取不同的CardView.
通过设置ListCardProviderR.layout.material_list_card_layout,可以实现带listViewCardView.

2、总体设计

2.1 MaterialList总体由四个部分组成

  • Crad作为整个工程的基本部件,不过Card内容的组装是由Card.Builder和CardProvider(CardProvider实现Observable接口)共同完成,ItemView内View的实例化和给View添加Action都由CardProvider完成。
  • CardLayout 继承自LinearLayout,作为ItemView它被MaterialListAdapter.ViewHolder包裹起来,同时实现Observer接口,监听CardProvider的数据变化
  • MaterialListAdapter继承自RecyclerView.Adapter,通过关联MaterialListView.OnAdapterItemsChanged实现添加ItemView和删除ItemView的回调,通过关联MaterialListView.OnSwipeAnimation实现删除ItemView的动画播放效果,同时实现Observer接口,监听CardProvider的数据变化
  • MaterialListView继承自RecyclerView,通过关联RecyclerItemClickListener,实现ItemView的单击和长按回调,通过关联SwipeDismissRecyclerViewTouchListener实现滑动删除ItemView的回调。

3、详细设计

3.1 类关系图

类关系图
以上是 MaterialList的主要类的关系图,跟总体设计中介绍的一样大致分为四部分。

3.2 核心功能介绍

3.2.1 Card是如何完成内容组装成为ItemView的
final CardProvider provider = new Card.Builder(this)
                        .setTag("WELCOME_CARD")
                        .setDismissible()
                        .withProvider(new CardProvider())
                        .setLayout(R.layout.material_welcome_card_layout)
                        .setTitle("Welcome Card")
                        .setTitleColor(Color.WHITE)
                        .setDescription("I am the description")
                        .setDescriptionColor(Color.WHITE)
                        .setSubtitle("My subtitle!")
                        .setSubtitleColor(Color.WHITE)
                        .setBackgroundColor(Color.BLUE)
                        .addAction(R.id.ok_button, new WelcomeButtonAction(this)
                                .setText("Okay!")
                                .setTextColor(Color.WHITE)
                                .setListener(new OnActionClickListener() {
                                    @Override
                                    public void onActionClicked(View view, Card card) {
                                        Toast.makeText(mContext, "Welcome!", Toast.LENGTH_SHORT).show();
                                    }
                                }));

我们通过观察上面的代码,首先我们通过new Card.Builder(this)获取Builder实例,接着设置setDismissible(),将属性设置为mDismissible,使它可以移除。

@NonNull
        public Builder setDismissible() {
            mDismissible = true;
            return this;
        }

然后我们通过withProvider(new CardProvider())注入CardProvider实例,此时将获得CardProvider实例,我们通过这个实例设置ItemView的color,layout,title,Action,最后通过provider.endConfig().build()我们就能获取实例Card,整个组合过程就是标准的Builder模式,不过Card就像一个空壳,真正持有ItemView核心属性的是CardProvider。
接着我们回到withProvider()和setLayout()这两个方法,我们知道获取不同风格的CardView就是通过设置不同的layout和CardProvider来实现,但这个布局视图控件是怎样的添加和初始化的呢?
首先我们看MaterialListAdapter的内部类ViewHolder,ViewHolder在类中关联了CardLayout。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值