Android第六次面试总结(Java设计模式二)

在 Android 开发里,ListView 和 RecyclerView 是常用的视图组件,用于展示大量数据列表。不过,这些视图组件本身无法直接展示原始数据源,需要借助 Adapter(适配器)把数据源适配成视图能够展示的数据,这便是适配器模式的实际应用。下面详细介绍 Adapter 在 ListView 和 RecyclerView 中的使用。

适配器模式原理

适配器模式的核心在于把一个类的接口转换为客户期望的另一个接口,让原本由于接口不兼容而不能一起工作的那些类可以协同工作。在 ListView 和 RecyclerView 的场景中,数据源(如数组、集合)和视图组件(ListView、RecyclerView)的接口不匹配,Adapter 就充当了中间的转换器,将数据源适配成视图组件能够识别和展示的形式。

ListView 中的适配器模式

示例代码
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;import java.util.ArrayList;
import java.util.List;public class ListViewAdapterExample extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(android.R.layout.activity_list_item);// 数据源List<String> dataSource = new ArrayList<>();dataSource.add("Item 1");dataSource.add("Item 2");dataSource.add("Item 3");// 创建适配器ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataSource);// 获取 ListView 实例ListView listView = findViewById(android.R.id.list);// 设置适配器listView.setAdapter(adapter);}
}
代码解释
  • 数据源List<String> dataSource 是一个字符串列表,代表原始的数据集合。
  • 适配器ArrayAdapter 是 Android 提供的一个适配器类,它将 List<String> 类型的数据源适配成 ListView 可以展示的形式。ArrayAdapter 接收三个参数:上下文、列表项的布局资源和数据源。
  • ListView:通过 findViewById 方法获取 ListView 实例,然后调用 setAdapter 方法将适配器设置给 ListView,这样 ListView 就可以根据适配器提供的数据来展示列表项。

RecyclerView 中的适配器模式

示例代码

 

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;// 自定义适配器类
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {private List<String> dataSource;private Context context;public MyAdapter(Context context, List<String> dataSource) {this.context = context;this.dataSource = dataSource;}@NonNull@Overridepublic MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);return new MyViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull MyViewHolder holder, int position) {String item = dataSource.get(position);holder.textView.setText(item);}@Overridepublic int getItemCount() {return dataSource.size();}static class MyViewHolder extends RecyclerView.ViewHolder {TextView textView;public MyViewHolder(@NonNull View itemView) {super(itemView);textView = itemView.findViewById(android.R.id.text1);}}
}
import android.os.Bundle;
import android.widget.LinearLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;public class RecyclerViewAdapterExample extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(android.R.layout.activity_list_item);// 数据源List<String> dataSource = new ArrayList<>();dataSource.add("Item 1");dataSource.add("Item 2");dataSource.add("Item 3");// 获取 RecyclerView 实例RecyclerView recyclerView = findViewById(android.R.id.list);// 设置布局管理器recyclerView.setLayoutManager(new LinearLayoutManager(this));// 创建适配器MyAdapter adapter = new MyAdapter(this, dataSource);// 设置适配器recyclerView.setAdapter(adapter);}
}
代码解释
  • 数据源:同样是 List<String> 类型的 dataSource,代表原始的数据集合。
  • 适配器:自定义的 MyAdapter 类继承自 RecyclerView.Adapter,它需要实现三个重要方法:
    • onCreateViewHolder:用于创建 ViewHolder 实例,ViewHolder 是一个用于缓存视图组件的容器。
    • onBindViewHolder:用于将数据源中的数据绑定到 ViewHolder 中的视图组件上。
    • getItemCount:返回数据源的大小。
  • RecyclerView:通过 findViewById 方法获取 RecyclerView 实例,先设置布局管理器(如 LinearLayoutManager),然后调用 setAdapter 方法将适配器设置给 RecyclerView,从而展示数据列表。

适配器模式的优势

  • 解耦数据源和视图:通过适配器模式,数据源和视图组件之间的耦合度降低,使得数据源和视图可以独立变化。
  • 可扩展性:可以根据需要自定义适配器,实现不同的视图展示效果,提高代码的可扩展性。
  • 代码复用:适配器可以被多个视图组件复用,提高代码的复用性。

在 Android 的 Jetpack 组件中,观察者模式有着广泛的应用,其中 LiveData 就是一个典型的例子,它很好地体现了观察者模式,并且借助注解来提升代码的安全性与可读性。下面详细介绍 LiveData 中的观察者模式以及相关注解的使用。

观察者模式在 LiveData 中的应用

原理

LiveData 是一个可观察的数据持有者类,它遵循观察者模式。LiveData 持有一个数据对象,当这个数据对象的状态发生变化时,所有注册的观察者(即 Observer)都会收到通知并更新自身状态。LiveData 还具备生命周期感知能力,它只会在观察者的生命周期处于活跃状态(如 STARTED 或 RESUMED)时才会通知观察者,避免了内存泄漏和不必要的更新。

示例代码
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import android.os.Bundle;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private MutableLiveData<String> dataLiveData;private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 初始化 LiveDatadataLiveData = new MutableLiveData<>();// 获取 TextView 实例textView = findViewById(R.id.textView);// 创建观察者Observer<String> observer = new Observer<String>() {@Overridepublic void onChanged(String newData) {// 当 LiveData 中的数据发生变化时,更新 TextView 的文本textView.setText(newData);}};// 注册观察者dataLiveData.observe(this, observer);// 更新 LiveData 中的数据updateData();}private void updateData() {// 模拟数据更新dataLiveData.setValue("New data");}
}
代码解释
  • LiveData 的创建:使用 MutableLiveData 类创建一个可变的 LiveData 对象 dataLiveData,用于持有数据。
  • 观察者的创建:创建一个 Observer 对象,实现 onChanged 方法,当 LiveData 中的数据发生变化时,该方法会被调用,从而更新 TextView 的文本。
  • 观察者的注册:调用 dataLiveData.observe(this, observer) 方法将观察者注册到 LiveData 上,其中 this 表示当前的 Activity,用于提供生命周期信息。
  • 数据的更新:调用 dataLiveData.setValue("New data") 方法更新 LiveData 中的数据,此时所有注册的观察者都会收到通知。

Jetpack 注解的应用

@NonNull 和 @Nullable 注解

在使用 LiveData 时,为了确保数据的非空性,可以使用 @NonNull 和 @Nullable 注解。这些注解可以帮助开发者在编译时发现潜在的空指针异常。

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;public class MyViewModel {private MutableLiveData<@NonNull String> nonNullLiveData = new MutableLiveData<>();private MutableLiveData<@Nullable String> nullableLiveData = new MutableLiveData<>();public LiveData<@NonNull String> getNonNullLiveData() {return nonNullLiveData;}public LiveData<@Nullable String> getNullableLiveData() {return nullableLiveData;}public void setNonNullData(@NonNull String data) {nonNullLiveData.setValue(data);}public void setNullableData(@Nullable String data) {nullableLiveData.setValue(data);}
}
代码解释
  • @NonNull 注解:表示该变量或参数不能为 null,如果尝试将 null 值赋给被 @NonNull 注解修饰的变量或参数,编译器会发出警告。
  • @Nullable 注解:表示该变量或参数可以为 null
@MainThread 和 @WorkerThread 注解

在更新 LiveData 时,需要注意更新操作必须在主线程中进行。可以使用 @MainThread 和 @WorkerThread 注解来明确方法的调用线程。

 

import androidx.annotation.MainThread;
import androidx.annotation.WorkerThread;
import androidx.lifecycle.MutableLiveData;public class MyViewModel {private MutableLiveData<String> liveData = new MutableLiveData<>();@MainThreadpublic void updateDataOnMainThread(String data) {liveData.setValue(data);}@WorkerThreadpublic void updateDataOnWorkerThread(String data) {// 在工作线程中更新 LiveData 需要使用 postValue 方法liveData.postValue(data);}
}
代码解释
  • @MainThread 注解:表示该方法必须在主线程中调用,setValue 方法必须在主线程中调用,因此使用 @MainThread 注解进行标记。
  • @WorkerThread 注解:表示该方法必须在工作线程中调用,postValue 方法可以在工作线程中调用,因此使用 @WorkerThread 注解进行标记。

总结

LiveData 是 Jetpack 中实现观察者模式的重要组件,它通过观察者模式实现了数据的实时更新和通知。同时,Jetpack 提供的注解(如 @NonNull@Nullable@MainThread@WorkerThread 等)可以帮助开发者提高代码的安全性和可读性,避免一些常见的错误。

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

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

相关文章

基于Spring Boot的乡村养老服务管理系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

### Java二维字符矩阵输入解析:正确读取由0和1组成的矩阵

在解决LeetCode等编程平台上的算法问题时&#xff0c;正确处理输入数据是解题的第一步。本文以Java语言为例&#xff0c;详细讲解如何正确读取由0和1组成的二维字符矩阵&#xff0c;并解决输入过程中可能遇到的换行符问题。 --- #### **问题背景** 题目要求从输入中读取一个二…

SEO监控看板搭建:基于Data Studio的实时数据可视化

在当今数字化营销的时代&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已经成为企业获取流量、提升品牌曝光的重要手段。然而&#xff0c;SEO的效果往往需要通过数据来评估和优化。为了更高效地监控SEO表现&#xff0c;许多企业开始使用数据可视化工具来搭建SEO监控看板…

模糊数学 | 模型 / 集合 / 关系 / 矩阵

注&#xff1a;本文为来自 “模糊数学 | 模型及其应用” 相关文章合辑。 略作重排。 如有内容异常&#xff0c;请看原文。 模糊数学模型&#xff1a;隶属函数、模糊集合的表示方法、模糊关系、模糊矩阵 wamg 潇潇 于 2019-05-06 22:35:21 发布 1.1 模糊数学简介 1965 年&a…

如何根据目标网站调整Python爬虫的延迟时间?

一、为什么需要调整爬虫的延迟时间&#xff1f; 1. 反爬虫机制的挑战 大多数网站&#xff08;尤其是电商平台如淘宝&#xff09;都部署了反爬虫机制&#xff0c;用于检测异常的访问行为。如果爬虫的请求频率过高&#xff0c;可能会触发以下反制措施&#xff1a; IP封禁&…

【嵌入式学习2】内存管理

## C语言编译过程 预处理&#xff1a;宏定义展开、头文件展开、条件编译&#xff0c;这里并不会检查语法&#xff0c;将#include #define这些头文件内容插入到源码中 gcc -E main.c -o main.i 编译&#xff1a;检查语法&#xff0c;将预处理后文件编译生成汇编文件&#xff…

案例分享|树莓派媒体播放器,重构商场广告的“黄金三秒”

研究显示&#xff0c;与传统户外广告相比&#xff0c;数字户外广告在消费者心中的记忆率提高了17%&#xff0c;而动态户外广告更是能提升16%的销售业绩&#xff0c;整体广告效率提升了17%。这一显著优势&#xff0c;使得越来越多资源和技术流入数字广告行业。 户外裸眼3D广告 无…

WindowsPE文件格式入门02.选项头其它和节表

https://www.bpsend.net/thread-444-1-1.html 选项头 IMAGE_OPTIONAL_HEADER&#xff1a;以供操作系统加载PE文件使用&#xff0c;32位必选。 重要字段&#xff1a; DWORD AddressOfEntryPoint&#xff1b; 入口点 DWORD ImageBase 建议模块地址…

【Arm+Qt+Opencv】基于人脸识别考勤系统实战

1.编译时问题汇总 windows下编译opencv-4.5.4 opencv-4.5.4编译 问题1&#xff1a;配套使用opencv-4.5.4,opencv_contrib-4.5.4,cmake3.22.3问题会少一点 问题2&#xff1a;在windows下哪里执行该命令 解决&#xff1a; 问题3&#xff1a;在对应cmake中搜索不到要修改的配置…

Linux与HTTP中的Cookie和Session

HTTP中的Cookie和Session 本篇介绍 前面几篇已经基本介绍了HTTP协议的大部分内容&#xff0c;但是前面提到了一点「HTTP是无连接、无状态的协议」&#xff0c;那么到底有什么无连接以及什么是无状态。基于这两个问题&#xff0c;随后解释什么是Cookie和Session&#xff0c;以…

【Tauri2】001——安装及运行

前言 笔者其实不想写教程&#xff0c;写教程很麻烦。 但是网上关于Tauri2的教程&#xff0c;要么不全&#xff0c;要么是Tauri1的&#xff0c;真的太少了&#xff0c;虽然有官网&#xff0c;还是太少了。 问Ai&#xff0c;也感觉比较离谱&#xff0c;有很多时候&#xff0c;…

【DFS】羌笛何须怨杨柳,春风不度玉门关 - 4. 二叉树中的深搜

本篇博客给大家带来的是二叉树深度优先搜索的解法技巧,在后面的文章中题目会涉及到回溯和剪枝,遇到了一并讲清楚. &#x1f40e;文章专栏: DFS &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的…

操作系统导论——第13章 抽象:地址空间

一、早期系统 从内存来看&#xff0c;早期的机器并没有提供多少抽象给用户。基本上&#xff0c;机器的物理内存如图13.1所示 操作系统曾经是一组函数&#xff08;实际上是一个库&#xff09;&#xff0c;在内存中&#xff08;在本例中&#xff0c;从物理地址0开始&#xff09;&…

网络爬虫-2:基础与理论

一.同步加载与异步加载 1.1同步加载定义: 页面所有内容一起加载出来,当某一个数据加载有问题,整个页面就不会加载出来(如HiFiNi音乐网站),所以又叫阻塞模式 1.2爬取步骤: 看netword->document 2.1异步加载定义: 数据是分开加载的,当某一份数据有异常时,不影响其他数据…

【Docker系列五】Docker Compose 简介

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

本地安装deepseek大模型,并使用 python 调用

首先进入 ollama 官网 https://ollama.com/点击下载 下载完成后所有都是下一步&#xff0c;就可以 点击搜索 Models &#xff1a; https://ollama.com/search然后点击下载&#xff1a; 选择后复制: ollama run deepseek-r1:32b例如&#xff1a; 让它安装完成后&#xff1…

【CC2530 教程 二】CC2530定时器实现微秒、毫秒、秒延时函数

目录 一、CC2530定时器&#xff1a; 二、CC2530定时器&#xff1a; &#xff08;1&#xff09;定时器1&#xff08;Timer1&#xff09;&#xff1a; &#xff08;2&#xff09;定时器2&#xff08;Timer2&#xff09;&#xff1a; &#xff08;3&#xff09;定时器3和定时…

23种设计模式-创建型模式-工厂方法

文章目录 简介场景问题1. 直接依赖具体实现2. 违反开闭原则3. 条件分支泛滥4. 代码重复风险 解决根本问题完整类图完整代码说明核心优势代码优化静态配置表动态策略 总结 简介 工厂方法是一种创建型设计模式&#xff0c;它提供了在父类中创建对象的接口&#xff0c;但允许子类…

Umi-OCR- OCR 文字识别工具,支持截图、批量图片排版解析

Umi-OCR 是免费开源的离线 OCR 文字识别软件。无需联网&#xff0c;解压即用&#xff0c;支持截图、批量图片、PDF 扫描件的文字识别&#xff0c;能识别数学公式、二维码&#xff0c;可生成双层可搜索 PDF。内置多语言识别库&#xff0c;界面支持多语言切换&#xff0c;提供命令…

【JavaEE】Mybatis基础使用注解 增删改查操作

目录 一、配置日志二、传递参数 #{}三、增(Insert)四、返回主键Options五、删&#xff08;Delete&#xff09;六、改&#xff08;Update&#xff09;七、查&#xff08;Select&#xff09; 一、配置日志 我们加上下面的代码在配置文件中&#xff0c;那么我们在日志中就可以看到…