Android Adapter的几个方法

1  ListView是在什么时候设置对Adapter的数据监听的?

在setAdapter(ListAdapter adapter)中,会先取消ListView中原来的mAdapter中的数据监听(mAdapter.unregisterDataSetObserver(mDataSetObserver);),然后再设置对新设置的adapter的数据监听。

2  getView(int position, View convertView, ViewGroup parent)

我们都知道mAdapter的getView方法很重要,那么该方法在ListView是怎么被利用的呢? 在ListView的源码中没有发现getView方法的调用,于是我们去ListView的父类AbsListView。在AbsListView中的obtainView中调用了getView,其主要代码逻辑部分为:

 1     View obtainView(int position, boolean[] isScrap) {
 2         isScrap[0] = false;
 3         View scrapView;
 4         //从回收器中获取view
 5         scrapView = mRecycler.getScrapView(position);
 6
 7         View child;
 8         if (scrapView != null) {
 9             ...
10             //若不为空,则传入convertView,这样的话重用了view,同时更新了数据
11             child = mAdapter.getView(position, scrapView, this);
12             ...
13         } else {
14             //若为空,则在getView中重新创建HolderView,且填入数据
15             child = mAdapter.getView(position, null, this);
16             ...
17         }
18         return child;
19     }

而obtainView又会在ListView的measure以及生成整个ListView等中用到。

对于重写getView方法最终要的应该就是要记得convertView的重用了,没有重用几乎都会造成内存卸了。

3  getCount()

Adapter的getCount()用来干啥?  在ListView中,在onMeasure以及触控分发响应等过程中都会用到Adapter的getCount()函数。毫无疑问的是:它应该返回底层数据的数据个数。

4  getItem(int position)

getItem()在AdapterView中被调用,然后供用户调用:从这两个函数的描述我们可以看出,我们应该在Adapter的getItem()方法中返回position对应的数据,但是不是说一定要返回用于在Item的View上展示的数据,这个还是看需求,虽然可能大部分情况都是返回View中展示的数据。

    /**
     * Gets the data associated with the specified position in the list.
     *
     * @param position Which data to get
     * @return The data associated with the specified position in the list
     */
    public Object getItemAtPosition(int position) {
        T adapter = getAdapter();
        return (adapter == null || position < 0) ? null : adapter.getItem(position);
    }

    /**
     * @return The data corresponding to the currently selected item, or
     * null if there is nothing selected.
     */
    public Object getSelectedItem() {
        T adapter = getAdapter();
        int selection = getSelectedItemPosition();
        if (adapter != null && adapter.getCount() > 0 && selection >= 0) {
            return adapter.getItem(selection);
        } else {
            return null;
        }
    }

纵观整个结构,可以说存在这样的三层:dataLists(原底层数据)--Adapter--AdapterView,有了getItem()方法的存在,我们可以直接利用Adapter来获取数据,而不需要获取底层dataLists的引用;有了getItemAtPosition()方法的存在,我们可以直接利用AdapterView 获取底层数据,而不需要获取其Adapter的引用。这样的话,对于编程的简便性以及解耦性都好很多。

5    getItemId(int position)

在AdapterView中发现它的一些调用,

 1     public long getItemIdAtPosition(int position) {
 2         T adapter = getAdapter();
 3         return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position);
 4     }
 5
 6
 7     private void fireOnSelected() {
 8         if (mOnItemSelectedListener == null)
 9             return;
10
11         int selection = this.getSelectedItemPosition();
12         if (selection >= 0) {
13             View v = getSelectedView();
14             //这里调用的getItemId得到的返回值与selection都属于同一个item的特征,其意义也就在于在选择接口的onItemSelected方法中可
15             //以直接拿到该item的id,而不需要通过获取adapter来间接实现
16             mOnItemSelectedListener.onItemSelected(this, v, selection,
17                     getAdapter().getItemId(selection));
18         } else {
19             mOnItemSelectedListener.onNothingSelected(this);
20         }
21     }
22
23     int findSyncPosition() {
24         ...
25             rowId = adapter.getItemId(seed);
26             if (rowId == idToMatch) { //从这里来看,getItemId似乎应该对于不同的item返回不同的值,保持唯一性
27                 // Found it!
28                 return seed;
29             }
30         ...
31     }

与上面分析的getItem()方法一样,getItemId()和getItemIdAtPosition()都提供了编程上面的便利。但是目前来看,由于对id没啥需求,所以大部分在重写getItemId方法时都是直接返回的position值,这样做也是对的,虽然从数据获取上没啥意义(我给你一个position,你原封不动的返回给我,啥意思)。但是我想说明的是,不要被这个做法所限制,而以为ItemId就是item在数据中的position。其实若有需求,可以利用getItemId()方法返回一些其他的值,比如每个item数据在数据库中id值,或者每个人的身份证号等。

时间: 2024-08-05 11:35:58

Android Adapter的几个方法的相关文章

[转]Android Adapter以及getView()方法的理解

Android Adapter基本理解: 我的理解是: 1.一个有许多getter的类(就是getView(),getCount()....这些方法) 2.有多少个get方法?都是什么? 这些getter是特定的,你可以复写他们,全部的方法如下 其中一般我们只用复写getCount(),getView(),getItemId(),getItem()这四个方法 3.这些被谁调用? 这些getter是被android系统自行调用的(具体如何调用,作为像我这样的新手做稍微了解就好) 4.为什么要复写这

Android Adapter详解

Android Adapter Adapter是用来帮助填充数据的中间桥梁,比如通过它将数据填充到ListView, GridView, Gallery.而android 提供了几种Adapter:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter

[项目总结]论Android Adapter notifyDataSetChanged与notifyDataSetInvalidated无效原因

最近在开发中遇到一个问题,Adapter中使用notifyDataSetChanged 与notifyDataSetInvalidated无效,经过思考和网上查找,得出如下原因. 首先看一下notifyDataSetChanged与notifyDataSetInvalidated的区别 我们可应用粮仓来解释一下,两者的区别. notifyDataSetChanged:粮仓中得粮食少了,或者多了,发送通知. notifyDataSetInvalidated:粮仓变换了,比如原来从A仓取粮食,现在换

Android模拟器设置网络代理方法

在服务器上启动模拟器的时候加了--http-proxy,但是不起作用.所以搜了下面的方法 四种方法: 一:将网络连接代理设置写入配置数据库 (适合启动模拟器无界面) 1.通过命令行或者通过双击emulatoer可执行文件,打开模拟器 2.在命令行执行adb shell 打开android的控制台 (确保环境变量设置正确,即已经把Android_SDK/tools 添加到了PATH(Linux)/path(Windows)) 3.执行 ls -l /data/data/com.android.pr

Android异步任务的使用方法

Android上面的很多操作是不能直接放在ui线程上面的.当ui线程被阻塞5秒以上的时候应用会出现未响应的对话框过.当此现象出现的时候会直接影响用户的用户体验的.所以我们需要通过方法对异步任务或者操作进行相关的处理.在这里罗列出集中相关的处理方法: 首先我们最先想到的应该是使用Thread+Handler实现非UI线程更新UI界面,即在线程执行的时候通过发送message来通过Handler来处理和更新ui. 另外一种方法就是通过异步任务:AsyncTask来进行数据的处理,通过继承AsyncT

Android获取LayoutInflater对象的方法总结

在写Android程序时,有时候会编写自定义的View,使用Inflater对象来将布局文件解析成一个View.本文主要目的是总结获取LayoutInflater对象的方法. 1.若能获取context对象,可以有以下几种方法: LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View child = inflater.inflate(R.la

调试 Android* x86 应用程序的方法以及要使用的工具

作者:Xiaodong Wang 1.简介 众所周知,Android* 开发人员头顶许多称呼:设计员.程序猿等,并且通常会不可避免地被称为故障检修工.代码中的错误无法避免,因此无论您是否一开始就造成错误,了解调试工具以及如何迅速而有效地跟踪并解决错误都很重要.鉴于此,如今的 Android 开发人员必须掌握有效的调试技巧.本文提供了 Android 应用程序调试工具的简单教学,用于帮助 Android SDK 以及相关工具的新手迅速入门,并在 Android x86 平台上更有效地解决故障. 2

MyEclipse 10 中安装Android ADT 22插件的方法

MyEclipse 10 中安装Android ADT 22插件的方法 下载ADT包:http://dl.google.com/android/ADT-22.0.0.zip 将ADT-22.0.0.zip文件放在指定的目录下,例如D:\Programs\Android,不解压. 打开MyEclipse,点击菜单Help >MyEclipse Configuration Center,如下图 在MyEclipse Configuration Center中,点击Software标签,再点击add

Android peferenceActivity 自定义标题简单方法

Android peferenceActivity 自定义标题简单方法 peferenceActivity 完全使用定义好的布局. 因此不能简单象其它好窗口进行自定,现在我们需要加 一个自定义标题,比如象其它窗口一样加一个统一topbar. 假设这个topbar的布局是 title.xml 一.标准自定义标题栏方法 Android 提供自定义标题栏方法 我们简单实现. @Override protected void onCreate(Bundle savedInstanceState) { f