学习Android的第十六天

目录

Android 自定义 Adapter

Adapter 接口

SpinnerAdapter

ListAdapter

BaseAdapter

自定义 BaseAdapter

参考文档

Android ListView 列表控件

ListView 的属性和方法

表头表尾分割线的设置

列表从底部开始显示 android:stackFromBottom

设置点击颜色 cacheColorHint

隐藏滑动条


Android 自定义 Adapter

在上一篇文章中我们知道了啥是 Adapter,也知道了 Adapter 的家族体系,也用过了几个Adapter。

本篇文章,我们就来自己实现一个 Adapter。

要实现自定义的 Adapter,通常继承自 BaseAdapter 类,并重写其中的方法来适配你的数据源。

首先,我们要做的就是要了解我们到底要重写哪些方法,因为 BaseAdapter 实现了 ListAdapter 和 SpinnerAdapter 接口,而这两个接口又继承自 Adapter

Adapter 接口

打开 Adapter API 文档,我们可以看到它有以下几个方法要实现

这些方法的说明如下:

  • int getCount(): 返回适配器中数据集的总数。
  • Object getItem(int position): 获取与数据集中指定位置关联的数据项。
  • long getItemId(int position): 获取与列表中指定位置关联的行 ID。
  • int getItemViewType(int position): 获取将由 getView(int, View, ViewGroup) 方法指定项目创建的视图类型。
  • View getView(int position, View convertView, ViewGroup parent): 获取显示数据集中指定位置的数据的视图。
  • int getViewTypeCount(): 返回将由其创建的视图类型的数量 getView(int, View, ViewGroup)。
  • boolean hasStableIds(): 项目 ID 在基础数据更改期间是否稳定。
  • boolean isEmpty(): 是否为空。
  • void registerDataSetObserver(DataSetObserver observer): 注册一个在此适配器使用的数据发生更改时调用的观察者。
  • unregisterDataSetObserver(DataSetObserver observer): 取消注册先前已通过此适配器注册的观察者  registerDataSetObserver(DataSetObserver)。

这些方法简要地描述了 Adapter 接口的功能,主要是用于获取数据项的数量、获取数据项本身以及与视图相关的操作。通过实现这些方法,可以创建自定义的适配器以满足特定的数据显示需求。

SpinnerAdapter

SpinnerAdapter 是用于在 Spinner(下拉框)中显示数据的接口。与其他 Adapter 不同的是,SpinnerAdapter 专门用于 Spinner 控件,因此只有一个公开方法:

  • View getDropDownView(int position, View convertView, ViewGroup parent): 根据下拉式弹出窗口中显示数据集中指定的位置获取数据的视图。

这个方法与 getView() 方法类似,但它专门用于在 Spinner 的下拉列表中显示数据项的视图。通常情况下,你会根据 position 参数来获取对应位置的数据项,并将其显示在一个视图中返回。需要注意的是,Spinner 在展开时会显示一个下拉列表,而这个方法返回的视图就是用于在下拉列表中显示的每个数据项的样式。

ListAdapter

ListAdapter 是用于在 ListView 中显示数据的接口,它有两个方法:

  • boolean areAllItemsEnabled(): 设置是否启用此适配器中的所有项目。如果所有的项目都是可用的,则返回 true;否则返回 false。当列表中的所有项都是可点击的时候,这个方法通常返回 true。
  • boolean isEnabled(int position): 判断指定位置上的项目是否启用。通常情况下,这个方法会根据列表中的每个项的状态来决定其是否可点击。如果指定位置上的项目是可用的(可以点击的),则返回 true;否则返回 false。

这两个方法主要用于控制 ListView 中每个项的可点击状态。

BaseAdapter

BaseAdapter 是 Android 中的一个抽象类,用于实现基本的适配器功能,通常用于在界面和数据之间进行数据绑定。

下面是对这些方法的简要说明:

  • boolean areAllItemsEnabled(): 判断是否启用了适配器中的所有项目。
  • CharSequence[] getAutofillOptions(): 获取可帮助 AutofillService 自动填充支持的视图的适配器数据的字符串表示形式。
  • View getDropDownView(int position, View convertView, ViewGroup parent): 根据下拉式弹出窗口中显示的数据集中指定的位置获取数据的视图。
  • int getItemViewType(int position): 获取由 getView(int, View, ViewGroup) 方法指定的项目创建的视图类型。
  • View getView(int position, View convertView, ViewGroup parent): 获取显示在数据集中指定位置的数据的视图。
  • boolean hasStableIds(): 在基础数据更改期间判断项目 id 是否稳定。
  • boolean isEmpty(): 判断适配器是否为空。
  • boolean isEnabled(int position): 判断指定位置上的项目是否启用。
  • void notifyDataSetChanged(): 通知附属的观察者,底层数据已被更改,任何反映数据集的视图都应该自行刷新。
  • void notifyDataSetInvalidated(): 通知所附的观察员,底层数据不再有效或可用。
  • void setAutofillOptions(CharSequence... options): 设置返回的值是由 getAutofillOptions() 方法返回的选项。
  • void registerDataSetObserver(DataSetObserver observer): 注册一个观察者,在适配器使用的数据发生更改时调用。
  • void unregisterDataSetObserver(DataSetObserver observer): 取消注册之前已经通过 registerDataSetObserver(DataSetObserver) 方法注册的观察者。

方法说明简单明了,主要就是获取数据项的数量和获取数据项,获取数据项的类型和视图。

现在我们看看我们要重写哪些方法

  1. 首先和监听器相关的都不用重写,因为暂时用不着,于是去掉

    1. notifyDataSetChanged()
    2. notifyDataSetInvalidated()
    3. registerDataSetObserver(DataSetObserver observer)
    4. registerDataSetObserver(DataSetObserver observer)
  2. 跟 自动填充 相关的也暂时用不着 (以后有机会介绍吧),于是去掉

    1. setAutofillOptions(CharSequence... options)
    2. getAutofillOptions()
  3. 有些方法可以有选择性的实现

    1. getDropDownView()
    2. areAllItemsEnabled()
    3. isEnabled()
    4. isEmpty()
    5. getItemViewType()
    6. getItemViewTypeCount()

好了,还剩下 4 个方法:

  • getView(int position, View convertView, ViewGroup parent): 这是一个最重要的方法,用于获取显示在数据集中指定位置的数据的视图。在这个方法中,你需要创建或者重用视图,并将数据绑定到视图上。
  • int getCount(): 这个方法返回数据集中的项目数量。在适配器中,你需要实现这个方法以提供数据集中项目的数量。
  • Object getItem(int position): 这个方法用于获取与数据集中指定位置关联的数据项。通常,你可以根据位置返回数据集中相应位置的对象。
  • long getItemId(int position): 这个方法用于获取与列表中指定位置关联的行 ID。一般来说,可以返回与该位置相关的数据项的唯一标识符,如果没有可以返回该位置。

这些方法是一个基本适配器必须实现的核心方法,它们用于将数据与视图进行绑定并确定数据的特征。

自定义 BaseAdapter

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="wrap_content" />
</LinearLayout>
package com.example.myapplication;import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 准备数据List<String> dataList = new ArrayList<>();dataList.add("项目 1:Java");dataList.add("项目 2:C#");dataList.add("项目 3:Python");dataList.add("项目 4:C++");dataList.add("项目 5:PHP");// 找到ListViewListView listView = findViewById(R.id.listView);// 创建适配器CustomAdapter adapter = new CustomAdapter(this, dataList);// 设置适配器listView.setAdapter(adapter);}// 自定义 BaseAdapterprivate static class CustomAdapter extends BaseAdapter {private List<String> mData;private LayoutInflater mInflater;// 构造函数public CustomAdapter(Context context, List<String> data) {mData = data;mInflater = LayoutInflater.from(context);}// 返回数据集的大小@Overridepublic int getCount() {return mData.size();}// 返回指定位置的数据项@Overridepublic String getItem(int position) {return mData.get(position);}// 返回指定位置的行ID@Overridepublic long getItemId(int position) {// 对于简单情况,我们返回位置作为IDreturn position;}// 返回指定位置的视图@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);holder = new ViewHolder();holder.textView = convertView.findViewById(android.R.id.text1);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}// 获取数据项并设置到TextView中String item = getItem(position);holder.textView.setText(item);return convertView;}// ViewHolder类,用于优化列表项的视图static class ViewHolder {TextView textView;}}
}

在这个示例中,我们创建了一个自定义的 CustomAdapter 类,继承自 BaseAdapter,并实现了其中的四个核心方法:getCount()、getItem()、getItemId() 和 getView()。同时,在 MainActivity 中,我们实例化了 CustomAdapter 并将其设置给了 ListView。 

 运行结果:

参考文档

  1. Android 官方 BaseAdapter

Android ListView 列表控件

关于 ListView ,其实 Android Adapter 适配器 和 Android 自定义 Adapter 都有已经使用过好几次了,我们这里就不再讲解基本的使用了。

ListView 的属性和方法

ListView 的常用属性:

  • android:footerDividersEnabled: 是否在 footerView(表尾)前绘制一个分隔条,默认为 true。
  • android:headerDividersEnabled: 是否在 headerView(表头)前绘制一个分隔条,默认为 true。
  • android:divider: 设置分隔条,可以用颜色分割,也可以用 drawable 资源分割。
  • android:dividerHeight: 设置分隔条的高度。
  • android:entries: ListView 要显示的数据资源,在 Android Adapter 适配器中我们有用到过。

这些属性可以用来定制 ListView 的外观和分隔线的显示。

至于方法,ListView 提供了很多与表头表尾分隔线相关的方法,但是我们在日常开发中常用的方法并不太多,通常使用的方法包括 setAdapter() 用于设置适配器,以及一些用于监听事件的方法,比如 setOnItemClickListener() 用于设置列表项的点击事件监听器。

表头表尾分割线的设置

ListView 没有直接设置表头和表尾的属性,但是你可以通过编程的方式在 Java 代码中设置表头和表尾。方法 addHeaderView(View v) 和 addFooterView(View v) 就是用来实现这个目的的。

这些方法允许你在 ListView 中添加表头和表尾的视图,其中 addHeaderView(View v) 方法用于添加表头,而 addFooterView(View v) 方法用于添加表尾。你可以传入一个自定义的 View 对象作为表头或表尾的内容。

此外,如果需要进一步控制表头或表尾的交互,可以使用重载的方法 addHeaderView(View v, Object data, boolean isSelectable) 和 addFooterView(View v, Object data, boolean isSelectable),其中 isSelectable 参数用于指定表头或表尾是否可以被选中。

记住,如果你使用了 addHeaderView() 方法,你必须在调用 setAdapter() 方法之前添加表头,否则会出现错误。这是因为添加表头必须在设置适配器之前完成。

例子:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="wrap_content" />
</LinearLayout>
package com.example.myapplication;import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 准备数据List<String> dataList = new ArrayList<>();dataList.add("项目 1:Java");dataList.add("项目 2:C#");dataList.add("项目 3:Python");dataList.add("项目 4:C++");dataList.add("项目 5:PHP");// 找到ListViewListView listView = findViewById(R.id.listView);// 创建适配器ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);// 添加表头// 注意:addHeaderView() 必须在 setAdapter() 之前调用// 如果表头不需要被选中,最后一个参数可以传入 false// 如果需要被选中,则传入 truelistView.addHeaderView(createHeaderView(), null, false);// 添加表尾// 同样,addFooterView() 也必须在 setAdapter() 之前调用listView.addFooterView(createFooterView(), null, false);// 设置适配器listView.setAdapter(adapter);}// 创建表头的视图private View createHeaderView() {TextView headerView = new TextView(this);headerView.setText("表头视图");// 设置表头样式,比如背景色、文字大小等headerView.setBackgroundColor(Color.BLUE); // 设置背景色为蓝色headerView.setTextColor(Color.WHITE); // 设置文字颜色为白色headerView.setTextSize(18); // 设置文字大小为 18spreturn headerView;}// 创建表尾的视图private View createFooterView() {TextView footerView = new TextView(this);footerView.setText("表尾视图");// 设置表尾样式,比如背景色、文字大小等footerView.setBackgroundColor(Color.GREEN); // 设置背景色为绿色footerView.setTextColor(Color.WHITE); // 设置文字颜色为白色footerView.setTextSize(18); // 设置文字大小为 18spreturn footerView;}
}

列表从底部开始显示 android:stackFromBottom

android:stackFromBottom="true" 是一个用于 ListView 的布局属性,用于设置列表从底部开始显示。

当设置为 true 时,ListView 将会从底部开始显示列表项,即最后一个列表项会显示在列表的底部,而第一个列表项会显示在列表的顶部。

下面是一个示例 XML 布局文件,演示如何使用 android:stackFromBottom="true" 属性:

<ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent"android:stackFromBottom="true" />

设置点击颜色 cacheColorHint

android:cacheColorHint 是一个用于 ListView 的属性,用于设置当滚动或点击时,背景色的缓存色。

默认情况下,ListView 在滚动时会绘制一个缓存位图来加速滚动的过程。而这个缓存位图的背景色默认是黑色。当你将一个有背景的 ListView 放在一个有颜色的背景上时,当你滚动 ListView 时,滚动过程中的空白部分会暴露出背景色,此时就会看到黑色背景,给人一种不连续的感觉。

通过设置 android:cacheColorHint 属性为透明色,即 #00000000,可以解决这个问题。这样,在滚动或点击时,空白部分就会显示成透明色,与背景融合,不会再出现黑色背景。

下面是一个示例 XML 布局文件,演示如何使用 android:cacheColorHint 属性:

<ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/listview_background"android:cacheColorHint="#00000000" />

隐藏滑动条

可以通过设置 android:scrollbars 属性为 none 来隐藏 ListView 的滚动条,也可以通过调用 setVerticalScrollBarEnabled(false) 来达到同样的效果。

1、使用 XML 属性 android:scrollbars="none":

<ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="none" />

2、使用 Java 代码 setVerticalScrollBarEnabled(false):

ListView listView = findViewById(R.id.listView);
listView.setVerticalScrollBarEnabled(false);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/259586.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在SpringBoot中@PathVariable与@RequestParam的区别

PathVariable GetMapping("/{userId}")public R<User> getUserById(PathVariable Long userId) {return userService.getUserById(userId);} // 根据id获取一条数据 function getStudentDataByIdAndDisplayInput(id) {// 发送 AJAX 请求$.ajax({url: /dorm/st…

政安晨:【完全零基础】认知人工智能(二)【超级简单】的【机器学习神经网络】—— 底层算法

如果小伙伴第一次看到这篇文章&#xff0c;可以先浏览一下我这个系列的上一篇文章&#xff1a; 政安晨&#xff1a;【完全零基础】认知人工智能&#xff08;一&#xff09;【超级简单】的【机器学习神经网络】 —— 预测机https://blog.csdn.net/snowdenkeke/article/details/…

数码管扫描显示-单片机通用模板

数码管扫描显示-单片机通用模板 一、数码管扫描的原理二、display.c的实现1、void Display(void) 各模式界面定义数据2、void BackupRamToDisRam(void)从缓存区刷新显示映射Ram3、void FreshDisplay(void) 映射显示Ram到主控的IO口4、void LcdDisplay_8bit(void) 映射显示Ram到…

数据结构——单链表专题

目录 1. 链表的概念及结构2. 实现单链表初始化尾插头插尾删头删查找在指定位置之前插入数据在指定位置之后插入数据删除指定位之前的节点删除指定位置之后pos节点销毁链表 3. 完整代码test.cSList.h 4. 链表的分类 1. 链表的概念及结构 在顺序表中存在一定的问题&#xff1a; …

【论文阅读笔记】Contrastive Learning with Stronger Augmentations

Contrastive Learning with Stronger Augmentations 摘要 基于提供的摘要&#xff0c;该论文的核心焦点是在对比学习领域提出的一个新框架——利用强数据增强的对比学习&#xff08;Contrastive Learning with Stronger Augmentations&#xff0c;简称CLSA&#xff09;。以下…

考研高数(导数的定义)

总结&#xff1a; 导数的本质就是极限。 函数在某点可导就必连续&#xff0c;连续就有极限且等于该点的函数值。 例题1&#xff1a;&#xff08;归结原则的条件是函数可导&#xff09; 例题2&#xff1a; 例题3&#xff1a;

星宸科技SSC369G 双4K高性价比AI IPC方案

一、方案描述 SSC369G 双4K高性价比AI IPC方案采用主芯片SSC369G&#xff0c;内核为CA55四核最高主频为1.5Ghz处理器。SOC内置集成一个64位的四核RISC处理器&#xff0c;先进的图像信号处理器&#xff08;ISP&#xff09;&#xff0c;高性能的H.265/H.264/MJPEG视频编解码器&a…

01.数据结构篇-链表

1.找出两个链表的交点 160. Intersection of Two Linked Lists (Easy) Leetcode / 力扣 例如以下示例中 A 和 B 两个链表相交于 c1&#xff1a; A: a1 → a2↘c1 → c2 → c3↗ B: b1 → b2 → b3 但是不会出现以下相交的情况&#xff0c;因为每个节点只有一个…

代码随想录算法训练营 DAY20 | 二叉树(7)

一、LeetCode 530 二叉搜索树的最小绝对值 题目链接&#xff1a;530.二叉搜索树的最小绝对值https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 思路一&#xff1a;利用搜索二叉树的中序遍历结果为有序数组的性质&#xff0c;将遍历结果保存到数组中&#xf…

扭蛋机小程序开发:发展优势

商场中精美的扭蛋机一直都是年轻人的心头好&#xff0c;目前&#xff0c;扭蛋机商品也不在局限于各种小型玩具&#xff0c;也逐渐与各类热门IP合作&#xff0c;打造出了各类手办、周边等&#xff0c;深受各个年龄层的喜爱。 如今&#xff0c;扭蛋机在互联网的推动下&#xff0…

Spring Security基础学习

一、SpringSecurity框架简介 二、SpringSecurity入门案例 三、SpringSecurity Web权限方案 四、SpringSecurity微服务权限方案 五、SpringSecurity原理总结

milvus insert api的数据结构源码分析

insert api的数据结构 一个完整的insert例子: import numpy as np from pymilvus import (connections,FieldSchema, CollectionSchema, DataType,Collection, )num_entities, dim 10, 3print("start connecting to Milvus") connections.connect("default&q…

【FastAPI】P1 安装与第一个 FastAPI 应用

目录 FastAPI 安装第一个 FastAPI 应用代码拆解分析 FastAPI 安装 FastAPI 是用于快速构建 API 的 web 框架&#xff0c;依赖 Python 3.8 及更高版本。使用 pip 命令安装 fastapi&#xff1a; pip install fastapi安装异步处理 ASGI 的服务器 Uvicorn&#xff1a; pip insta…

设置墙、楼板每层的厚度和材质——群问题整理003

你好&#xff0c;这里是BIM的乐趣&#xff0c;我是九哥~ 今天分享的是设置墙、楼板等每层的厚度和材质。 我们都知道&#xff0c;Revit中墙、板这类系统族&#xff0c;厚度设置和普通族是不太一样的&#xff0c;他的厚度参数可读&#xff0c;但是并不可设置&#xff0c;因为我…

【数据仓库】主题域和数据域

数据域与主题域区别 https://www.cnblogs.com/datadance/p/16898254.html 数据域是自下而上&#xff0c;以业务数据视角来划分数据&#xff0c;一般进行完业务系统数据调研之后就可以进行数据域的划分。针对公共明细层&#xff08;DWD&#xff09;进行主题划分。主题域则自上而…

LabVIEW智能监测系统

LabVIEW智能监测系统 设计与实现一个基于LabVIEW的智能监测系统&#xff0c;通过高效的数据采集和处理能力&#xff0c;提高监测精度和响应速度。系统通过集成传感器技术与虚拟仪器软件&#xff0c;实现对环境参数的实时监测与分析&#xff0c;进而优化监控过程&#xff0c;提…

后端开发怎么学?

后端开发怎么学&#xff1f; 后端开发可以简单地理解为与前端开发相对应的开发方向。前端开发主要负责构建用户界面、维护用户体验等方面的工作&#xff0c;而后端开发则主要负责处理数据、逻辑和算法等方面的工作。后端开发旨在为前端应用程序提供支持&#xff0c;以帮助实现可…

前端vue金额用逗号分隔

实现效果 代码 template部分 <el-input v-model"state.val"></el-input><div>{{ priceFor(state.val) }}</div> js部分 const state reactive({ val: });const priceFor (val)> {if(!val){return }else if(val.length<4){return…

简单介绍数据结构的基本概念

数据结构的基本概念 常用术语 数据 数据&#xff08;Data&#xff09;是客观事物的符号表示&#xff0c;是所有能输入到计算机中并被计算机程序处理的符号的总称。例如&#xff1a;整数、字符串、图形、图像、声音和动画等 数据元素 数据元素&#xff08;Data Element&…

RocketMQ(四):功能特性——备份

1 消息发送重试和流控机制 本节介绍Apache RocketMQ的消息发送重试机制和消息流控机制 1.1 消息发送重试机制 1.1.1 重试基本概念 Apache RocketMQ 客户端连接服务端发起消息发送请求时&#xff0c;可能会因为网络故障、服务异常等原因导致调用失败。为保证消息的可靠性&…