【15】Android 适配器 - Adapter

目录

前言

继承关系

ArrayAdapter

构造函数

简单示例

使用资源文件

SimpleAdapter

构造函数

示例

SimpleCursorAdapter


前言

Adapter MVC 模式中 Controller 的一部分;MVC模式Model-View-Controller(模型-视图-控制器) 模式,它包括:

  • Model(模型)             模型代表一个存取数据的对象或JAVAPOJO。它也可以带有逻辑,在数据变化时更新控制器。
  • View(视图)               视图代表模型包含的数据的可视化。
  • Controller(控制器)  控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

Adnroid 中:Adapter 的作用可简单理解为 Model(数据) → Controller(显示方式) → View(用户界面)

继承关系

BaseAdapter 是一个抽象类,继承它需要实现较多的方法,所以也就具有较高的灵活性;

ArrayAdapter 数组适配器,使用有一定的局限性,只能显示一行文本数据。支持泛型。

SimpleAdapter 有最好的扩充性,可以自定义出各种效果。

SimpleCursorAdapter 可以适用于简单的纯文字型ListView。可以认为是SimpleAdapter对数据库的简单结合,能方便地把数据库的内容以列表的形式展示出来。

此外,还有 BRVAH ,它是非常流行的 RecyclerAdapter框架 ,能高效的使用 RecyclerView官网BRVAHGitHub。有时间去学习学习。

ArrayAdapter

构造函数

ArrayAdapter (Context context, int resource, T[] objects)为例,三个参数分是:

context    Context: The current context.(上下文)
resource

int: The resource ID for a layout file containing a TextView to use when instantiating views.(资源布局ID)    

objectsT: The objects to represent in the ListView.(数据)

对于 resource,系统黑给我们提供了一些 ListView模板,常用的有

  • simple_list_item_1 : 单独一行的文本框
  • simple_list_item_2 : 两个文本框组成
  • simple_list_item_checked : 每项都是由一个已选中的列表项
  • simple_list_item_multiple_choice : 都带有一个复选框
  • simple_list_item_single_choice : 都带有一个单选钮

简单示例

activity_adapter.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Adapter_Activity"
    android:padding="20dp"
    android:gravity="center|top"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Adapter"
        android:textSize="30dp"
        android:layout_marginBottom="30dp"/>


    <ListView
        android:id="@+id/list_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

Adapter_Activity.java

package com.example.mytest_button;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Adapter_Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_adapter);

        //要显示的数据
        String[] strs = {"凉风有信","秋叶无边"};
        //创建ArrayAdapter
        ArrayAdapter<String>adapter = new ArrayAdapter<String>
                (this,android.R.layout.simple_list_item_1,strs);
        //获取ListView对象,通过setAdapter设置适配器
        ListView list_test = findViewById(R.id.list_test);
        list_test.setAdapter(adapter);
    }
}

效果图

使用资源文件

app-->main-->res-->values 文件夹中创建资源文件 arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="myarray">
        <item>语文</item>
        <item>数学</item>
        <item>英语</item>
        <item>物理</item>
        <item>化学</item>
        <item>生物</item>
        <item>政治</item>
        <item>历史</item>
        <item>地理</item>
        <item>体育</item>
    </string-array>
</resources>

在ListView属性下加多一条设置

android:entries = "@array/myarray"

回到 Adapter_Activity.java中,在 setContentView() 后面加上:

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
        R.array.myarray,
        android.R.layout.simple_list_item_multiple_choice);

效果图

SimpleAdapter

构造函数

SimpleAdapter (Context context,
                List<? extends Map<String, ?>> data,
                int resource,
                String[] from,
                int[] to)

Parameters(参数)

context 

Context: The context where the View associated with this SimpleAdapter is running(上下文)
dataList: A List of Maps. Each entry in the List corresponds to one row in the list. The Maps contain the data for each row, and should include all the entries specified in "from"(数据)
resource          int: Resource identifier of a view layout that defines the views for this list item. The layout file should include at least those named views defined in "to"(视图布局的资源标识符)                                                                                 
fromString: A list of column names that will be added to the Map associated with each item.(列名称列表)
toint: The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter.(列值)

示例

首先自定义列表项每一项的布局

activity_adapter.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Adapter_Activity"
    android:padding="20dp"
    android:orientation="horizontal">

    <!--头像-->
    <ImageView
        android:id="@+id/imgtou"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:baselineAlignBottom="true"
        android:paddingLeft="8dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="8dp"
            android:textColor="#1A1818"
            android:textSize="20sp"/>

        <TextView
            android:id="@+id/says"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="8dp"
            android:textColor="#8B121516"
            android:textSize="14sp"/>

    </LinearLayout>

</LinearLayout>

效果图

创建一个xml文件,放 ListView 控件

listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/list_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</LinearLayout>

Adapater_Activity.java

package com.example.mytest_button;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Adapter_Activity extends AppCompatActivity {

    //声明及初始化
    private  String[] names = {"野蛮人","射手","幽灵"};
    private String[] says= {"hhhhhhhhhh~","biubiubiu~","OhhuOhhuOhhu~"};
    private int[] imgIDs = new int[]{R.drawable.user3,R.drawable.user1,R.drawable.user2};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //注意这里加载的View是ListView所在的xml文件
        setContentView(R.layout.listview);

    List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();

    //将数据按格式加入data,这里不推荐用汉字
    for (int i = 0; i < names.length; i++){
        Map<String,Object> showitem = new HashMap<String,Object>();
        showitem.put("头像",imgIDs[i]);
        showitem.put("名字",names[i]);
        showitem.put("消息",says[i]);
        data.add(showitem);
    }

    //创建SimpleAdapter
    SimpleAdapter simAdapt = new SimpleAdapter(this,
            data,
            R.layout.activity_adapter,
            new String[]{"头像","名字","消息"},
            new int[]{R.id.imgtou,R.id.name,R.id.says});

    //通过setAdapter方法为 ListView 设置Adapter
    ListView listView = (ListView) findViewById(R.id.list_test);
    listView.setAdapter(simAdapt);

    }
}

效果图

 

SimpleCursorAdapter

SimpleCursorAdapter API15(Android 4.0.3)中被弃用

现在一般用 BaseAdapter ,关于它的使用方法可以看我的博文: 传送门

一种优雅的方式来使用RecyclerView核心思想  想必大家都遇到过,在一个列表显示不同样式的需求。在RecyclerView可以通过ViewType进行区分,如果样式特别多的时候就会使得代码非常冗余,不利于开发及维护。那么有没有一种优雅的方法解决这个问题呢?  技术经理给你说,接下来的项目由你负责,明天下班前把排期同步出来。这时你应该怎么做?由于你是Android端的RD,你对Android的排期是比较了解的,但是iOS端、FE端、Server端的排期怎么办呢?聪明的你立即把任务派发下去了,给每个端的负责人说,明天午之前把排期汇总给我。  没错,在多样式列表的设计也可以采用这种策略,给RecyclerView设置的Adapter不做具体的处理,而是由它派发出去。实现方案  1. addDelegate 向Adapter注册委托Adapter;  2. addDataList 设置数据;  3. layout 渲染布局,Adapter查找到对应的委托Adapter,由委托Adapter去做具体渲染。如何使用引入compile 'com.kevin:delegationadapter:1.0.2' // 扩展库,使得databinding更简易,可以不引入 compile 'com.kevin:delegationadapter-extras:1.0.0'用法 1. 同一数据类型多种样式// 设置LayoutManager LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); // 设置Adapter delegationAdapter = new DelegationAdapter(); // 添加委托Adapter delegationAdapter.addDelegate(new OnePicAdapterDelegate()); delegationAdapter.addDelegate(new ThreePicAdapterDelegate()); delegationAdapter.addDelegate(new MorePicAdapterDelegate()); delegationAdapter.addDelegate(new VideoAdapterDelegate()); recyclerView.setAdapter(delegationAdapter);2. 不同数据类型多种样式// 设置LayoutManager LinearLayoutManager layoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layoutManager); // 设置Adapter mDelegationAdapter = new DelegationAdapter(); mDelegationAdapter.addDelegate(new StringAdapterDelegate()); mDelegationAdapter.addDelegate(new IntegerAdapterDelegate()); mDelegationAdapter.addDelegate(new FloatAdapterDelegate()); mDelegationAdapter.addDelegate(new DoubleAdapterDelegate()); // 添加委托Adapter mRecyclerView.setAdapter(mDelegationAdapter); // 设置数据 List<Object> dataList = new ArrayList<>(); dataList.add("今天天气怎么样?");  // 添加一个String类型数据 dataList.add("大晴天,有点热。");  // 添加一个String类型数据 dataList.add("温度多少度呢?");    // 添加一个String类型数据 dataList.add(29);                // 添加一个int类型数据 dataList.add("具体是多少?");      // 添加一个String类型数据 dataList.add(29.5F);             // 添加一个Float类型数据 dataList.add(29.527921364978D);  // 添加一个Double类型数据 mDelegationAdapter.setDataItems(dataList); 3. 同一数据多种类型// 设置LayoutManager mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 设置LayoutManager mDelegationAdapter = new DelegationAdapter(); // 添加委托Adapter mDelegationAdapter.addDelegate(new ServiceInfoAdapterDelegate()); mDelegationAdapter.addDelegate(new BillItemAdapterDelegate()); mDelegationAdapter.addDelegate(new ChargeInfoAdapterDelegate()); mBinding.recyclerView.setAdapter(mDelegationAdapter); // 设置数据 String newsListStr = LocalFileUtils.getStringFormAsset(this, "bill.json"); Bill bill = new Gson().fromJson(newsListStr, Bill.class); List<Object> dataList = new ArrayList<>(); dataList.add(new ItemData(bill, ServiceInfoDelegateAdapter.TAG)); dataList.addAll(bill.details); dataList.add(new ItemData(bill, ChargeInfoDelegateAdapter.TAG)); mDelegationAdapter.setDataItems(dataList);4. 添加头部// 设置LayoutManager LinearLayoutManager layoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layoutManager); // 设置Adapter mDelegationAdapter = new DelegationAdapter(); // 添加委托Adapter mDelegationAdapter.addDelegate(new TextAdapterDelegate()); mDelegationAdapter.addDelegate(new BannerAdapterDelegate()); mRecyclerView.setAdapter(mDelegationAdapter); // 添加头部 mDelegationAdapter.addHeaderItem("这是添加的添加的头部数据"); 5. 添加尾部// 设置LayoutManager LinearLayoutManager layoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layoutManager); // 设置Adapter mDelegationAdapter = new DelegationAdapter(); // 添加委托Adapter mDelegationAdapter.addDelegate(new TextAdapterDelegate()); mDelegationAdapter.addDelegate(new BannerAdapterDelegate()); mRecyclerView.setAdapter(mDelegationAdapter); // 添加尾部 mDelegationAdapter.addFotterItem("这是添加的添加的尾部数据"); 6. 带兜底的委托Adapter// 设置LayoutManager LinearLayoutManager layoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layoutManager); // 设置Adapter mDelegationAdapter = new DelegationAdapter(); // 添加委托Adapter mDelegationAdapter.addDelegate(new TextAdapterDelegate()); // 添加兜底的委托Adapter mDelegationAdapter.setFallbackDelegate(new FallbackAdapterDelegate()); mRecyclerView.setAdapter(mDelegationAdapter);THANKS TO 1. MultiItem 委托思想来源 2. AdapterDelegates 委托架子来源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值