[zzerX@blog ~ ]:

记一次使用开源项目FlexibleAdapter

前序

经过一段时间的学习,认识到了Android的ListView和RecyclerView,用这两个控件进行了开发,最后发现前者已经逐渐显现出弊端,后者实现效果则需要进行不少的工作,于是再github找到了这么一个RecyclerView的开源项目 FlexibleAdapter.

项目不大却有如此多的功能实现,让我认识到自己还有很长一段路要走,也希望通过这次使用开源项目过程中提升自己。

坎坷

勉强用翻译看完了github上的介绍,第一个想法是百度看看有没有其他人使用的心得,结果…几乎没有,百度关于FlexibleAdapter的寥寥几篇文章还都只是github. README的复制文章。所以只能使用项目的wiki上浏览教程【FlexibleAdapter - wiki】。

我也该改变自己的想法,不能一味的依赖别人的心得,也需要自己理解,凝结自己的心得。

依靠翻译加上自己的理解和手动,完成了FlexibleAdapter的简单使用,把之前用ListView和RecyclerView实现的功能,用FlexibleAdapter实现。

食用

添加依赖

app > gradle.build添加依赖

dependencies {
    // Using JCenter
    implementation 'eu.davidea:flexible-adapter:5.1.0'
    implementation 'eu.davidea:flexible-adapter-ui:1.0.0'
    implementation 'eu.davidea:flexible-adapter-livedata:1.0.0-b3'
    // From 1.0.0-b3, library is compiled with data binding v2
    implementation 'eu.davidea:flexible-adapter-databinding:1.0.0'
}

首先在activity_main.xml添加RecyclerView,如果没有添加包则添加:

implementation 'androidx.recyclerview:recyclerview:1.1.0'

flexible_adapter_activity_main

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

然后是定义每一个item的布局xml,在网上找了一组枪的数据,图片和文字放在了assets文件夹内进行关联,并使用AssetsReader读取。

flexible_adapter_item_flexible.xml
<?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="4dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
<ImageView
    android:id="@+id/gun_img"
    android:layout_width="200dp"
    android:src="@mipmap/ic_launcher_round"
    android:layout_height="match_parent"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        <TextView
            android:id="@+id/gun_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Medium Text"/>
        <TextView
            android:id="@+id/gun_introduction"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="10dp"
            android:layout_margin="16dp"
            android:text="Medium Text"/>
    </LinearLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView>

然后我们需要定义项目,也就是Item类;不同的是这个对象需要继承AbstractFlexibleItem<yourItem.yourViewHolder>,yourItem.yourViewHolder就是当前类和类中的ViewHolder.

然后我们需要重写这5个方法

  • public boolean equals(Object o)

    • item相同的情况
  • public int hashCode()

    • 如果重写了上面的方法,最好也重写这个
  • public int getLayoutRes()

    • 获取项目类型id值
  • public yourViewHolder createViewHolder(View view, FlexibleAdapter adapter)

    • 负责每个子项的布局
  • public void bindViewHolder(FlexibleAdapter adapter, yourViewHolder holder, int position, List payloads)

    • 负责将每个子项holder绑定数据。

    当然还要创建一个ViewHolder类 public class yourViewHolder extends RecyclerView.ViewHolder

    Gun.java
    public class Gun extends AbstractFlexibleItem<com.learndemo.androidx.FlexibleAdapterLearn.Gun.MyViewHolder>{
    
            private String name;
            private String introduction;
            private Bitmap img;
    
            public Gun(String name, String introduction, Bitmap img) {
                this.name = name;
                this.introduction = introduction;
                this.img = img;
            }
    
            @Override
            public boolean equals(Object inObject) {
                if (inObject instanceof com.learndemo.androidx.FlexibleAdapterLearn.Gun) {
                    com.learndemo.androidx.FlexibleAdapterLearn.Gun inItem = (com.learndemo.androidx.FlexibleAdapterLearn.Gun) inObject;
                    return this.name.equals(inItem.name);
                }
                return false;
            }
    
            @Override
            public int hashCode() {
                return name.hashCode();
            }
    
    
            @Override
            public int getLayoutRes() {
                return R.layout.flexible_adapter_item_flexible;
            }
    
    
            @Override
            public com.learndemo.androidx.FlexibleAdapterLearn.Gun.MyViewHolder createViewHolder(View view, FlexibleAdapter<IFlexible> adapter) {
                return new com.learndemo.androidx.FlexibleAdapterLearn.Gun.MyViewHolder(view, adapter);
            }
    
            @Override
            public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, com.learndemo.androidx.FlexibleAdapterLearn.Gun.MyViewHolder holder,
                                       int position,
                                       List<Object> payloads) {
                holder.gun_name.setText(name);
                // Title appears disabled if item is disabled
                holder.gun_name.setEnabled(isEnabled());
                holder.gun_img.setImageBitmap(img);
                holder.gun_introduction.setText(introduction);
            }
    
            public class MyViewHolder extends FlexibleViewHolder {
    
                public TextView gun_name;
                public TextView gun_introduction;
                public ImageView gun_img;
    
                public MyViewHolder(View view, FlexibleAdapter adapter) {
                    super(view, adapter);
                    gun_name = (TextView) view.findViewById(R.id.gun_name);
                    gun_introduction = (TextView) view.findViewById(R.id.gun_introduction);
                    gun_img = (ImageView) view.findViewById(R.id.gun_img);
                }
            }
    
    }
    
    
    

    原文对这个自定义Item的解释【Implement and customize the item (MyItem and MyViewHolder classes)

    然后就是MainActivity了

    主要部分:

    public List<Gun> getDatabaseList() {
            List<Gun> list = new ArrayList<>();
            String[] names = new String[]{
                    "意大利伯莱塔92F型手枪",
                    "奥地利格洛克17型手枪",
                    "美国柯尔特M2000型手枪",
                    "德国P229型手枪",
                    "中国QSG92式手枪",
                    "德国HKP7型手枪",
                    "美国鲁格P85式手枪",
                    "美国M1911A1式手枪",
                    "捷克CZ83型手枪",
                    "前苏联托卡列夫手枪"};
            String[] introduction = AssetsReader.getText("introduction.txt",context).split("。");
            Log.v("split",introduction[0]);
            for (int i = 1; i <= 10; i++) {
                list.add(new Gun(names[i-1], introduction[i-1], AssetsReader.getImage(context, "33752726_" + i + ".jpg")));
            }
            return list;
        }

    到这里一个简单的展示就完成了,根据之前的项目,我还需要完成Item的点击事件、长按事件、单选多选事件、item子项点击事件,接下来就能慢慢体会到开源项目的强大之处。

    点击事件与长按事件

    , — Aug 13, 2021