继承BaseAdapter的子类的基本实现和改进
基本过程:新建TopicAdapter,继承BaseAdapter,重写需要重写的方法。
第一步:增加一个带多个参数的构造函数和对应的属性,其目的是为了传递适配器使用过程所必需的参数
为了传递参数方便,增加TopicAdapter的带多个参数的构造函数,这样在Activity使用Adapter的时候方便使用,这里的多参数的构造函数仅仅是为了传递参数而已。
private List<Topic> dataList; private int listviewItemRId; private File cacheDir; private LayoutInflater inflater; /** * 此构造函数是自己添加的,输入参数的值需要有对应的属性来接收 * (也可以使用setter方法来实现传值,但个人不赞成) * @param context 应用上下文,此处是为了通过context得到LayoutInflater实例 * @param dataList 传递给Adapter的数据List * @param listviewItemRId 显示ListView的条目Item的布局文件的RID * @param cacheDir 用于缓存数据和图片文件的SD卡文件路径 */ public TopicAdapter(Context context, List<Topic> dataList, int listviewItemRId, File cacheDir){ String serverName = Context.LAYOUT_INFLATER_SERVICE; this.inflater = (LayoutInflater)context.getSystemService(serverName); this.dataList = dataList; this.listviewItemRId = listviewItemRId; this.cacheDir = cacheDir; }
第二步、重写几个比较简单的方法
@Override public int getCount() { return dataList.size(); } @Override public Object getItem(int position) { return dataList.get(position); } @Override public long getItemId(int position) { return position; }
第三步、重写getView的方法,详见具体实现。
/** * 返回待显示(第position条)Item所对应的View * @param position: 是待显示item所对应的index * @param convertView: 是待显示item所对应的View * @param parent: 是待显示item所对应的View的parent */ @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView = null; TextView textView = null; /**convertView先判断是否为空,如果为空则需要重新创建,然后获得imageView和textView组件; * 如果不为空的,则从缓存中获得获得imageView和textView组件; * 最后为imageView和textView准备对应的数据**/ if(convertView == null){ convertView = inflater.inflate(listviewItemRId, null); imageView = (ImageView) convertView.findViewById(R.id.imageView); textView = (TextView) convertView.findViewById(R.id.textView); convertView.setTag(new DataWrapper(imageView, textView)); }else{ DataWrapper dataWrapper = (DataWrapper) convertView.getTag(); imageView = dataWrapper.imageView; textView = dataWrapper.textView; } try { Topic topic = dataList.get(position); textView.setText(topic.title); Uri imageURI = TopicService.getImage(topic.imageSrc, cacheDir); imageView.setImageURI(imageURI); } catch (Exception e) { e.printStackTrace(); } return convertView; } private final class DataWrapper{ public ImageView imageView; public TextView textView; public DataWrapper(ImageView imageView, TextView textView) { this.imageView = imageView; this.textView = textView; } }
以上的两行代码可能存在较为严重的性能问题,即可能出现ANR的错误。
所以第五步、使用多线程来修改。是修改为以下的代码
try { Topic topic = dataList.get(position); textView.setText(topic.title); //Uri imageURI = TopicService.getImage(topic.imageSrc, cacheDir); //imageView.setImageURI(imageURI); asyncImageLoad(imageView, topic.imageSrc); } catch (Exception e) { e.printStackTrace(); }
新增新的asyncImageLoad()的方法
private void asyncImageLoad(final ImageView imageView, final String path) { final Handler handler = new Handler(){ public void handleMessage(Message msg) {//运行在主线程中 /**主线程的handleMessage接到回传数据后,更新imageView的数据**/ Uri uri = (Uri)msg.obj; if(uri!=null && imageView!= null) imageView.setImageURI(uri); } }; Runnable runnable = new Runnable() { public void run() {//在子线程中运行 try { Uri uri = TopicService.getImage(path, cacheDir); /*通过handler的sendMessage()来回传数据到主线程*/ handler.sendMessage(handler.obtainMessage(10, uri)); } catch (Exception e) { e.printStackTrace(); } } }; new Thread(runnable).start(); }
第六步、使用AsyncTask优化第五步的多线程代码
private void asyncImageLoad(ImageView imageView, String path) { AsyncImageTask asyncImageTask = new AsyncImageTask(imageView); asyncImageTask.execute(path); /**通过asyncImageTask.execute(path)调用AsyncImageTask的doInBackground()方法 * path是第一个参数,所以在doInBackground()的params[0]的值其实是path */ } private final class AsyncImageTask extends AsyncTask<String, Integer, Uri>{ private ImageView imageView; public AsyncImageTask(ImageView imageView) { this.imageView = imageView; } protected Uri doInBackground(String... params) {//子线程中执行的 try { /**这里接收到execute传入的path的值进行处理,处理结果Uri返回给onPostExecute**/ return TopicService.getImage(params[0], cacheDir); } catch (Exception e) { e.printStackTrace(); } return null; } protected void onPostExecute(Uri result) {//运行在主线程 if(result!=null && imageView!= null) imageView.setImageURI(result); } }
相关推荐
开发者需要继承BaseAdapter,并实现其四个主要方法:`getCount()`、`getItem(int position)`、`getItemId(int position)`和`getView(int position, View convertView, ViewGroup parent)`。`getCount()`返回数据源的...
开发者需要继承BaseAdapter并重写其中的方法,如`getCount()`返回数据集大小,`getItem()`获取指定位置的数据,`getView()`则用于构建ListView中的每一项视图。BaseAdapter允许开发者自定义数据到视图的映射,从而...
2. **创建BaseAdapter子类** 首先,你需要创建一个继承自BaseAdapter的子类,并实现其中的必要方法。这些方法包括: - `getCount()`: 返回数据源中的元素数量。 - `getItem(int position)`: 获取指定位置的数据...
通过继承`BaseAdapter`并实现其必要的方法,我们可以控制列表项的布局和数据的填充。 接下来,我们来看描述:“使用BaseAdapter必须写一个类继承它,同时BaseAdapter是一个抽象类,继承它必须实现它的方法”。的确...
- 创建一个继承自BaseAdapter的子类,实现以上四个方法。 - 在`getView()`中,根据position获取数据,然后使用LayoutInflater从XML布局文件中创建或复用视图,设置视图内容。 - 数据变更时,调用`...
源码中,BaseAdapter定义了一些基本的空实现,供子类去扩展。例如,`getViewTypeCount()`和`getViewType(int position)`用于处理多种类型的列表项,这在显示复杂列表时非常有用。同时,BaseAdapter还提供了一些辅助...
- 自定义BaseAdapter时,通常会创建一个继承自BaseAdapter的子类,并重写上述方法,以适应特定的数据结构和视图需求。 4. **优化BaseAdapter**: - 使用ViewHolder模式:通过创建一个ViewHolder类来保存视图引用...
1. 创建BaseAdapter子类:首先,我们需要继承BaseAdapter并实现其四个必须的方法:getCount()、getItem(int position)、getItemId(int position)和getView(int position, View convertView, ViewGroup parent)。...
在Android开发中,`BaseAdapter` 是一个非常重要的组件,它是连接数据源和视图(ListView、GridView等)的关键桥梁。本篇文章将详细介绍如何自定义一个通用的`BaseAdapter`,以便于在多个不同的列表视图中重用,减少...
1. **创建Adapter子类**:创建一个新的类,继承自BaseAdapter,并实现其抽象方法。 2. **数据模型**:定义一个数据模型类,用来存储每行数据。 3. **布局文件**:为每个列表项创建一个布局文件,定义其UI元素。 4...
4. **SQLite数据库**:在Android中,使用SQLiteOpenHelper子类创建和管理数据库。我们需要创建一个表,包含字段如ID(自增长)、用户名、留言内容和时间戳。每当用户提交留言,就插入一条新记录。 5. **...
ListView通过Adapter(适配器)来连接数据源和视图,BaseAdapter是Adapter的一种基础实现,可以自定义以适应不同的数据源。在这个例子中,我们关注的是如何将SQLite数据库的数据通过BaseAdapter展现到ListView上。 ...
在Android开发中,Adapter是连接数据源与UI组件的关键,ArrayAdapter和BaseAdapter都是实现这一功能的类,但它们有着不同的特性和使用场景。这里我们将深入探讨ArrayAdapter和BaseAdapter的区别,以及如何在实际开发...
总之,要在Android的ListView中加载网络图片并支持滑动,需要自定义BaseAdapter,重写getView()方法,使用ViewHolder优化性能,同时处理好图片的加载和内存管理。如果选择继承ListActivity,可以简化布局文件的设置...
在Android架构设计中,深入理解和应用面向对象编程(OOP)的基本原则至关重要。高焕堂,作为一位知名的Android架构师,强调了OOP在构建高效、可维护的Android应用程序中的核心地位。本知识点将深入探讨OOP的关键概念...
在Android平台上,构建一个简单的记事本应用是一个常见的学习任务,它可以帮助开发者深入理解Android的基础组件和数据存储机制。在这个项目中,我们主要涉及到以下几个关键的技术点: 1. **ListView**:ListView是...
1. **抽象通用Adapter**:创建一个泛型的BaseAdapter子类,接受任何类型的列表数据,这样就可以在不同的数据结构和视图中复用同一Adapter。 2. **ViewHolder模板**:定义一个基类ViewHolder,包含所有常见的视图...
通过以上所述,我们可以理解自定义BaseAdapter在Android开发中的重要性和实现方式,以及如何通过优化使其具有可复用性。这不仅可以提高代码质量,还能降低维护成本,是Android开发中不可或缺的一个技术点。
1. **创建子类**:继承这个“实用的Baseadapter”,并实现抽象的`getView()`方法。在这个方法中,我们需要根据数据项创建并设置UI元素。 2. **设置数据源**:在Adapter的构造函数中,我们可以传入数据源,如...
1. 自定义Adapter:你需要继承BaseAdapter或者ArrayAdapter,并重写其中的方法,如getView(),在这个方法中你可以创建并设置ListView每一项的布局,包括按钮。 2. 设置按钮事件:在getView()方法中,找到Button组件...