ListView就是列表组件,一般通过继承ListActivity使用系统提供的ListView.

所有的AdapterView组件都需要有一个对应的Adapter作为适配器来显示列表中元素的布局方式

见思维导图

AbsListView的常用XML属性:

android:choiceMode

设置ListView的选择行为 none:不显示任何选中项 singleChoice:允许单选  multipleChoice:允许多选

android:drawSelectorOnTop

设置为true,则选中的列表项会显示在上面

android:fastScrollEnabled

是否允许快速滚动

android:listSelector

指定被选中的列表项上绘制的Drawable

android:scrollingCache

是否使用绘制缓存

android:smoothScrollBar

如果设置为false,则不在header View之后绘制分隔条

android:stackFromBottom

设置是否从底端开始排列列表项

android:textFilterEnabled

设置是否对列表项进行过滤.当对应的Adapter实现了Filter接口时该属性才会起作用

android:transcriptMode

设置该组件的滚动模式。disable:关闭滚动,这是默认值   normal:当listView收到数据改变通知,且最后一个列表项可见时,将会自动滚动到底端。 alwaysScoll:该listView总会自动滚动到底端

android:divider

设置List列表项的分隔条(既可用颜色分隔,也可用Drawable分隔)

android:dividerHeight

分隔条高度

android:entries

指定一个数组资源,生成一个ListView

android:footerDividersEnabled

设置为false,则不在footer View之前绘制分隔条

android:headerDividersEnabled

设置为false,则不在header View之后绘制分隔条

ArrayAdapter: 数组或集合的适配器。

例:
private final String[] mous = {
        "郭嘉",
        "荀攸",
        "荀彧",
        "程昱",
        "戏志才",
        "徐庶"
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mous);

也可以在XML文件中用android:entries属性指定绑定的数组资源文件
资源文件存放在value文件夹下
如:
android:entries="@array/book"

<string-array name="book" >
        <item >1</item>
        <item >2</item>
        <item >3</item>
        <item >3</item>
</string-array>

例子

<?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="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal" ><ListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>
package com.light.android.study;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;public class MainActivity extends Activity {private final String[] mous = {"郭嘉","荀攸","荀彧","程昱","戏志才","徐庶"};private ListView lv;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();initAdapter();}private void init(){lv = (ListView) findViewById(R.id.lv);}private void initAdapter(){ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mous);lv.setAdapter(adapter);}}

效果:

SimpleAdapter:简单的Adapter实现

SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
第一个参数是Context对象
第二个参数是保存有每一行数据的Map构成的List对象,也就是说,每一行数据里的每一个属性都由它的名字和它的值构成一个键值对,多个属性有多个键值对,每一行的多个键值对构成这一行的一个Map对象,这一行的Map对象对应到这个List中.
第三个参数布局文件Id
第四个参数Map对象中的多个键值对的key值
第五个参数布局文件中用来显示内容的组件ID

SimpleAdapter绑定数据到视图分两个阶段
1.首先,如果设置了SimpleAdapter.ViewBinder,那么这个设置的ViewBinder的setViewValue(android.view.View, Object, String)将被调用.如果setViewValue的返回值是true,则表示绑定已经完成,将不再调用系统默认的绑定实现.
2.如果返回值为false,视图将按以下顺序绑定数据:
•如果View实现了Checkable(例如CheckBox),期望绑定值是一个布尔类型.
•TextView.期望绑定值是一个字符串类型,通过调用setViewText(TextView, String)绑定.
•ImageView,期望绑定值是一个资源id或者一个字符串,通过调用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)绑定数据.
如果没有一个合适的绑定发生将会抛出IllegalStateException.

例子:

布局文件:

<?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="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><!-- 定义一个List --><ListViewandroid:id="@+id/mylist"android:layout_width="fill_parent"android:layout_height="wrap_content" /></LinearLayout>
<?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"android:orientation="vertical" ><!-- 定义一个ImageView,用于作为列表项的一部分。 --><ImageViewandroid:id="@+id/header"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="10dp"tools:ignore="ContentDescription" /><!-- 定义一个TextView,用于作为列表项的一部分。 --><TextViewandroid:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical"android:paddingLeft="10dp"android:textSize="16sp" /></LinearLayout>
package com.light.android.study;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;public class MainActivity extends Activity {private String[] names = new String[] { "杜甫", "弄玉", "清照", "李白" };private int[] imageIds = new int[] { R.drawable.tiger, R.drawable.nongyu,R.drawable.qingzhao, R.drawable.libai };@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();for (int i = 0; i < names.length; i++) {Map<String, Object> map = new HashMap<String, Object>();map.put("header", imageIds[i]);map.put("personName", names[i]);listItems.add(map);}//創建SimpleAdapterSimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems,R.layout.list_item_layout, new String[] { "personName", "header" },new int[] { R.id.name, R.id.header });ListView list = (ListView) findViewById(R.id.mylist);list.setAdapter(simpleAdapter);}
}

效果:

CursorAdapter:

Cursor型集合的适配器,与数据库连接的桥梁
其中游标携带的结果集中必须有列名为“_id”的列,否则这个类无法工作.
getView()
每一项显示的设置
bindView()
把数据和已经生成的View绑定在一起
newView()
新建一个View
CursorAdapter中源码 getView的实现
public View getView(int position, View convertView, ViewGroup parent) {
 View v;
 if (convertView == null) {
   v = newView(mContext, mCursor, parent);
 } else {
   v = convertView;
 }
 bindView(v, mContext, mCursor);
 return v;
}
getView首先使用已经存在的View,如果没有就调用newView 产生一个,然后把数据bind上去

我们一般使用其子类SimpleCursorAdapter来实现查询出来的数据List的Adapter

SimpleCursorAdapter(Context context,int layout,Cursor c,String[] from,int[] to,int flags)
context:当前Context对象
layout:布局文件Id
c:集合
from:需要绑定的集合中的列的名字
to:显示项目的View的id集合,在layout布局文件中定义
flags:用来判断适配器的行为标志
建议使用CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
适配器会在游标上注册一个内容观测器,当通知到达时会调用 onContentChanged() 方法.使用该标志位时要注意:在注册观察器时需要先解除当前游标与适配器的关联,防止发生泄漏.
Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题。所以一般先将SimpleCursorAdapter中的Cursor对象放空,然后用CursorLoader对象加载数据,再放入适配器。
例子:

布局文件:

<?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="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal" ><ListViewandroid:id="@android:id/list"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

Item布局文件:

<?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="64dip" android:orientation="horizontal" android:gravity="center_vertical" android:paddingLeft="8dip"><TextView android:id="@android:id/text1" android:layout_width="match_parent"android:layout_height="wrap_content" android:textSize="18sp" android:gravity="center_vertical" android:singleLine="true" android:fadingEdge="horizontal" android:fadingEdgeLength="3dip" android:ellipsize="marquee" />
</LinearLayout>
package com.light.android.study;import android.app.ListActivity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.SimpleCursorAdapter;//實現接口作為CursorLoader
public class MainActivity extends ListActivity implements LoaderCallbacks<Cursor> {private SimpleCursorAdapter mAdapter;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// Create an empty adapter we will use to display the loaded data. mAdapter = new SimpleCursorAdapter(MainActivity.this,R.layout.contacts_list_item, null,new String[] { ContactsContract.Contacts.DISPLAY_NAME },new int[] { android.R.id.text1 },0);getListView().setAdapter(mAdapter);//初始化Loader//第一個參數 為這個Loader對象指定唯一的标识ID,第二个可选参数,用来支持Loader的构造方法,//第三个参数是LoaderCallbacks接口类型getLoaderManager().initLoader(0, null, this);}public Loader<Cursor> onCreateLoader(int id, Bundle args) {// 去数据库读取数据等要消耗大量时间的操作放在 // 自定义 CursorLoader 的 onLoadInBackgroundreturn new MyCursorLoader(getApplicationContext());}public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {// Swap the new cursor in.  (The framework will take care of closing the         // old cursor once we return.) mAdapter.swapCursor(cursor); }public void onLoaderReset(Loader<Cursor> arg0) {// This is called when the last Cursor provided to onLoadFinished()        // above is about to be closed.  We need to make sure we are no         // longer using it. mAdapter.swapCursor(null);}public static class MyCursorLoader extends CursorLoader {String[] mContactProjection = { ContactsContract.Contacts._ID,ContactsContract.Contacts.DISPLAY_NAME };private Context mContext;public MyCursorLoader(Context context) {super(context);mContext = context;}/*** 4.自定义 CursorLoader 的 onLoadInBackground* 会返回一个Cursor,这里给SimpleCursorAdapter用 * 来填充数据。查询数据等操作放在这里执行*/@Overrideprotected Cursor onLoadInBackground() {Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, mContactProjection,null, null, null);return cursor;}}
}

效果:

最后看下BaseAdapter

经常需要覆写的方法

boolean isEnabled (int position):

如果列表的一项item是separator(充当分隔项目,跟其他item项一样,也可以不一样,但是无法进行点击),返回true,也就是可以点击,并接收响应事件。如果此时position处的item是separator的话,返回false,也就无法响应点击或触摸事件,此项目是不可以点击的,表现形式为点了没任何反应,可以充当一个列表中的分隔,当然可以自定义这个分隔项的布局。

abstract Object getItem(int position)
得到位于position位置的项

public int getViewTypeCount() 

返回共有多少个不同的布局

abstract int getCount()
得到项目总数
abstract long getItemId(int position)
得到位于position位置的项的Id
public int getItemViewType(int position)
以int数值型返回itemView的类型。一般普通列表的item都是一样的布局,也就是说这个列表只有一种类型,但是很多时候我们需要列表显示不同的item,比如有的列表有普通item和separator两种类型,item用于响应用户点击事件,separator用于分隔item,不可以点击,这样这个列表就有了两种类型,重载这个方法,如果当前位置是item,我们可以返回1,如果是separator我们可以返回2,以此类推。
abstract View getView(int position,View convertVeiw,ViewGroup parent)
每一项显示的设置
在getView方法中需要缓存加载View优化ListView

官方建议使用ViewHolder,其实就是单例
例:

@Override
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) {final LayoutInflater inflater = (LayoutInflater)                        mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.list_item_icon_text, null); holder = new ViewHolder();  holder.icon = (ImageView) convertView.findViewById(R.id.icon); holder.text = (TextView) convertView.findViewById(R.id.text); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.icon.setImageResource(R.drawable.icon); holder.text.setText(mData[position]); return convertView;
}
static class ViewHolder { ImageView icon; TextView text;
} 

知识点

①解决ListView滑动过程中背景颜色变黑的问题

android:cacheColorHint="#00000000"// setting transparent color

http://stackoverflow.com/questions/2833057/background-listview-becomes-black-when-scrolling/2833103#2833103

②ListView变圆角显示

定义一个shape:res/drawable/customshape.xml

<?xml version="1.0" encoding="UTF-8"?><shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><gradientandroid:startColor="#SomeGradientBeginColor"android:endColor="#SomeGradientEndColor"android:angle="270"/><cornersandroid:bottomRightRadius="7dp"android:bottomLeftRadius="7dp"android:topLeftRadius="7dp"android:topRightRadius="7dp"/></shape>

然后在XML中

android:background="@drawable/customshape"

http://stackoverflow.com/questions/1683185/how-do-i-create-a-listview-with-rounded-corners-in-android/1683195#1683195

③保留ListView上次滑动的位置

// save index and top positionint index = mList.getFirstVisiblePosition();View v = mList.getChildAt(0);int top =(v ==null)?0: v.getTop();// ...// restore index and position
mList.setSelectionFromTop(index, top);

说明:

ListView.getFirstVisiblePosition() returns the top visible list item. But this item may be partially scrolled out of view, and if you want to restore the exact scroll position of the list you need to get this offset. So ListView.getChildAt(0) returns the View for the top list item, and then View.getTop() returns its relative offset from the top of the ListView. Then, to restore the ListView's scroll position, we call ListView.setSelectionFromTop() with the index of the item we want and an offset to position its top edge from the top of the ListView.

http://stackoverflow.com/questions/3014089/maintain-save-restore-scroll-position-when-returning-to-a-listview

转载于:https://www.cnblogs.com/krislight1105/p/3748370.html

Android用户界面 UI组件--AdapterView及其子类(一) ListView及各种Adapter详解相关推荐

  1. Android用户界面 UI组件--TextView及其子类(二) Button,selector选择器,sharp属性

    1.XML文件中的OnClick 属性可以指定在Activity中处理点击事件的方法,Activity中必须定义该属性指定的值作为方法的名字且有一个View类型的参数,表示此物件被点击. 2.使用se ...

  2. 2.5 UI组件-AdapterView及子类(疯狂android学习笔记)

    列表视图(ListView)和ListActivity ①直接使用ListView创建 ②让Activity继承ListActivity(相当于该activity显示的组件为ListView) 提示: ...

  3. Android用户界面的设计方法心得,(8 Android) 用户界面UI设计

    (8 Android) 用户界面UI设计 3.1.1 Android界面视图类 Android 图形化的用户界面(Graphical User Interface , GUI) 采用了结构清晰的MVC ...

  4. 【Android语音合成TTS】百度语音接入方法,和使用技巧详解

    请尊重他人的劳动成果,转载请注明出处:[Android语音合成TTS]百度语音接入方法,和使用技巧详解 Ps. 依托于百度开放云,百度语音为合作伙伴提供了业界领先.永久免费的语音技术服务,目前已上线的 ...

  5. Android初级,实现网易云音乐歌曲列表界面效果,播放界面效果,ListView,ViewPager方法详解

    初学Android初级,第一篇博客文章,如有错误,还望批评指正! 本文主要内容以网易云音乐歌曲列表界面效果代码,播放音乐界面效果代码为主,并将ListView和ViewPager作为实现界面滑动功能的 ...

  6. Android基础入门教程——8.3.1 三个绘图工具类详解

    Android基础入门教程--8.3.1 三个绘图工具类详解 标签(空格分隔): Android基础入门教程 本节引言: 上两小节我们学习了Drawable以及Bitmap,都是加载好图片的,而本节我 ...

  7. android 设置listview滚动条,Android ListView 滚动条的设置详解及实例代码

    Android ListView 滚动条的设置详解 1.滚动条的属性 android:scrollbarAlwaysDrawHorizontalTrack 设置是否始终显示水平滚动条.这里用Scrol ...

  8. 【Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!

     李华明Himi 原创,转载务必在明显处注明: 转载自 [黑米GameDev街区] 原文链接:  http://www.himigame.com/android-game/327.html 很多童鞋说 ...

  9. android 6.0 存储卡,Android 6.0区别U盘和SD卡设备的方法详解

    如下所示: public static boolean isSdcardExists(Context context) { StorageManager storageManager = Storag ...

  10. Android开发自学笔记(Android Studio)—4.4 AdapterView及其子类

    一.引言 AdapterView本身是一个抽象类,而它派生的子类在用法上也基本相似,只是在显示上有一定区别,因此把他们也归为一类. AdapterView具有如下特征: AdapterView继承自V ...

最新文章

  1. ios玩全民奇迹不显示服务器,全民奇迹关于IOS充值游戏物品不到账公告
  2. dpkg安装软件流程_ubuntu安装搜狗输入法linux版
  3. 上传问题分析2--文件重名
  4. 设置跳转到新的actvity之后不可返回
  5. Linux文件读写改权限详解
  6. 1038. 统计同成绩学生(20)
  7. python数据结构之队列(一)
  8. Activity之间传递bitmap,Observer观察者模式
  9. ai皮肤检测分数_德国猫咪皮肤检测仪,为什么这么火?| 云美来
  10. 我的QQ群,欢迎入坑!
  11. FastSocket学习笔记~再说客户端与服务端的组成
  12. Realtek RTL87xx 学习资源
  13. Visual Attention Network(VAN)
  14. gnuradio3.8.2的安装步骤
  15. 常用软件的 Linux 版本
  16. 学习大数据必须掌握哪些核心技术?
  17. android 小鸡走动动画,使用Matter.js实现的小鸡掉落动画
  18. Team Foundation Power Tools 1.2发布
  19. STM32F10x_模拟I2C读写EEPROM(2)(切换SDA方向 + 读ACK位 + 完整代码)
  20. 企业破产重整网_最高法开通全国企业破产重整案件信息网

热门文章

  1. 发现三个很赞的英语学习网站
  2. Android自定义View之刻度尺
  3. java addmonth_JAVA:int month = n.get(Calendar.MONTH)+1;为何要加1?
  4. dump文件_windows程序崩溃时生成dump文件方法
  5. Emscripten 单词_人教版英语八年级上册听力(单词+课文) 朗读录音听力mp3音频电子课本(完整版)...
  6. java真实面试题(2)
  7. 雷林鹏分享:C# 事件(Event)
  8. [原创]IPV4分组的格式
  9. iOS -[JYBDScanCardManage configIDScan] in JYBDScanCardManage.o等静态库问题
  10. 微服务实战(六):选择微服务部署策略 - DockOne.io