06.实例篇:仿QQ好友列表——ExpandableListView和ListView(下篇)
来源:互联网 发布:淘宝平面设计 编辑:程序博客网 时间:2024/05/19 12:38
1.前言
本篇主要ExpandableListView和ListView一些基础知识点介绍,主要包括一些类和接口的使用介绍,主要是参照google 最新的API文档摘要总结的;
2.什么是ListView
是一种ViewGroup,用于滚动展示一组列表,这些列表项自动由Adapter从数据源读取数据产生特定的View填充到ListView;
当布局中的内容是动态的或者预先不可知的,可以使用AdapterView(ListView,GridView是其子类)运行时填充;
AdapterView(包括子类)使用Adapter绑定数据到自己,Adapter是数据源和AdapterView布局的中介;
3.ListView重要方法和属性:
用于垂直滚动列表视图,列表项来自ListAdapter;
类继承结构:具体的类
public class ListView extends AbsListView
java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.widget.AdapterView<T extends android.widget.Adapter>
↳ android.widget.AbsListView
↳ android.widget.ListView
直接子类:
ExpandableListView :用于展示两级列表;
重要的XML属性:
android:divider:两个列表项之间的分割线(可以使color或者Drawable)
android:dividerHeight:分割线的高度(厚度)
android:entries:静态引用一个数组资源,用来填充ListView的
android:footerDividersEnabled:对于footer view是否有divider
android:headerDividersEnabled:
从AbsListView继承的重要属性:
android:choiceMode:设置列表项的选择行为,是否可以选择,是否支持多选
android:listSelector :设置列表中被选中的项的Drawable
android:textFilterEnabled:是否支持过滤
重要方法:
void addFooterView(View v):添加固定的View到列表的底部,在setAdapter之前调用,可以添加多次,显示多个
void addFooterView(View v, Object data, boolean isSelectable)
void addHeaderView(View v)
ListAdapter getAdapter():返回与之绑定的Adapter
void setAdapter (ListAdapter adapter) :设置ListView的数据
long[] getCheckItemIds ():api8过期,获取选择的多个Items的id,仅当模式不是CHOICE_MODE_NONE.有效
void setSelection (int position):设置选定的列表项,从0开始
4.ListView相关的类:ListAdapter(也是接口)
public interface Adapter android.widget.Adapter间接子类:
ArrayAdapter<T>, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter,
ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter,SpinnerAdapter, WrapperListAdapter
方法:
abstract int getCount():有多少数据
abstract Object getItem(int position):获取特定位置的数据
abstract long getItemId(int position):获取特定位置的行id
abstract View getView(int position, View convertView, ViewGroup parent):获取特定位置展示的View
abstract boolean isEmpty():
public interface ListAdapter implements Adapter (添加了两个抽象方法) android.widget.ListAdapter
间接子类:
ArrayAdapter<T>, BaseAdapter(抽象类), CursorAdapter(抽象类), HeaderViewListAdapter,
ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, WrapperListAdapter
常用的Adapter:
public class ArrayAdapter extends BaseAdapter implements Filterable:android.widget.ArrayAdapter<T>
具体简单的Adapter类,数据源是数组,布局中有一个简单的TextView,如果想要其它View,可以重写getView方法
使用一般重写,或者使用:
public ArrayAdapter (Context context, int resource, T[] objects):Resource布局文件必须有特定名称的textview
public ArrayAdapter (Context context, int resource, int textViewResourceId, T[] objects)
public ArrayAdapter (Context context, int resource, List<T> objects)
public ArrayAdapter (Context context, int resource, int textViewResourceId, List<T> objects)
public class SimpleCursorAdapter extends ResourceCursorAdapter:
android.support.v4.widget.SimpleCursorAdapter
构造器:
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags)
参数:layout-定义列表项的布局文件,c-数据源cursor,可以为null(如果不可用),
from-数组定义了需要绑定的cursor数据列名,to-表明view的id,用来展示数据
flags-决定adapter的行为,FLAG_AUTO_REQUERY(过期,不建议使用,会在主线程中获取数据,阻塞) FLAG_REGISTER_CONTENT_OBSERVER(添加内容监听器,当通知到来,
调用onContentChanged方法,小心内存泄露,当使用CursorAdapter[CursorLoader]时,不需要该标志;
方法:
Cursor swapCursor(Cursor c):换入一个新的Cursor,返回旧的cursor【未关闭】,如果cursor为null或者新的和旧的一样返回null
public abstract class CursorAdapter extends BaseAdapter implements Filterable
5.ListView使用方式:【读取本地数据】
- 需要ListView;
- 需要ListAdapter及其子类;
- 如果Adpater数据发生变化,应该调用notifyDataSetChanged()方法;
定制每一项文本内容,可以重写数组中每个对象的toString方法;
定制ListView每一项的视图,可以重写getView方法;
ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray); ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
ListView+SimpleCursorAdapter方法:
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number}; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);
处理点击事件:实现AdapterView.onItemClickListener接口
<pre name="code" class="java"> // Create a message handling object as an anonymous class. private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { // Do something in response to the click } }; listView.setOnItemClickListener(mMessageClickedHandler);使用CursorLoader+ListView方法:
public class ListViewLoader extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor> { // This is the Adapter being used to display the list's data SimpleCursorAdapter mAdapter; // These are the Contacts rows that we will retrieve static final String[] PROJECTION = new String[] {ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME}; // This is the select criteria static final String SELECTION = "((" + ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Data.DISPLAY_NAME + " != '' ))"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a progress bar to display while the list loads ProgressBar progressBar = new ProgressBar(this); progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER)); progressBar.setIndeterminate(true); getListView().setEmptyView(progressBar); // Must add the progress bar to the root of the layout ViewGroup root = (ViewGroup) findViewById(android.R.id.content); root.addView(progressBar); // For the cursor adapter, specify which columns go into which views String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME}; int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1 // Create an empty adapter we will use to display the loaded data. // We pass null for the cursor, then update it in onLoadFinished() mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null, fromColumns, toViews, 0); setListAdapter(mAdapter); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this); } // Called when a new Loader needs to be created public Loader<Cursor> onCreateLoader(int id, Bundle args) { // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new CursorLoader(this, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, null); } // Called when a previously created loader has finished loading public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); } // Called when a previously created loader is reset, making the data unavailable public void onLoaderReset(Loader<Cursor> loader) { // 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); } @Override public void onListItemClick(ListView l, View v, int position, long id) { // Do something when a list item is clicked }}
5.ListView动态获取网络数据方式【见下一节文章】
6.ExpandableListView相关类和知识点
public class ExpandableListView extends ListView:ListView的子类,android.widget.ExpandableListView
两级列表,分为组和组中Items,使用ExpandableListAdapter接口提供数据;
重要的接口:
ExpandableListView.OnChildClickListener 、ExpandableListView.OnGroupClickListener
ExpandableListView.OnGroupCollapseListener 、ExpandableListView.OnGroupExpandListener
重要的XML属性:
android:childDivider:color或者Drawable资源文件,子项目的分隔符
android:childIndicator :状态列表的Drawable资源文件,用于定义子项目各种状态对应的效果
android:groupIndicator
重要方法:
ExpandableListAdapter getExpandableListAdapter():
boolean collapseGroup(int groupPos)
boolean expandGroup(int groupPos)
boolean expandGroup(int groupPos, boolean animate)
long getSelectedPosition():获取选择Group或者child的位置,该位置是打包以后的;综合的
long getSelectedId ():获取已经选择的Group或者child的id,如果没选择,则返回-1;
static int getPackedPositionChild(long packedPosition)
public boolean setSelectedChild (int groupPosition, int childPosition, boolean shouldExpandGroup)
public void setSelectedGroup (int groupPosition)
相关的类:public interface ExpandableListAdapter:按Group组织数据,为可展开类别提供数据;
间接子类:
BaseExpandableListAdapter, CursorTreeAdapter, ResourceCursorTreeAdapter,
SimpleCursorTreeAdapter, SimpleExpandableListAdapter
SimpleExpandableListAdapter:
注意groupTo和ChildTo所对应的视图都是TextView才行(ImageView不行,其它类型的视图,需要重写getGroupView和getChildView方法;);
简单的Adapter映射静态数据到group和child view。
构造器:9个参数
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int groupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo)context:AdapterView运行环境上下文
groupData:Map的列表,列表中的每一项代表一组所有属性数据,Map包含组的数据,至少包含groupFrom所有的条目,例如每个Group需要一个textView和ImageView,那么可以map1.put("text","xxxx"); map1.put("image", "ddd")作为第一组的group Item;
groupLayout:Group视图的布局文件id,至少包含groupTo中的所有组件id
groupFrom:一组keys(用于获取每个组的数据,因为一个组项view可能需要多个数据),用于从Maps获取关联的该组view的数据
groupTo:一组view id,用于对应展示groupFrom中列数据
childData:Map对象列表的列表,外围的列表代表每个组,里面的列表代表每一组里面的项所有属性数据;
其它参数类似;
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo) SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, int lastChildLayout, String[] childFrom, int[] childTo)
SimpleCursorTreeAdapter:
SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout, int expandedGroupLayout, String[] groupFrom, int[] groupTo, int childLayout, int lastChildLayout, String[] childFrom, int[] childTo) SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout, int expandedGroupLayout, String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom, int[] childTo) SimpleCursorTreeAdapter(Context context, Cursor cursor, int groupLayout, String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom, int[] childTo)
7.ExpandableListView的使用实例
参见上篇文章:http://blog.csdn.net/meplusplus/article/details/26622261
8.如何定制自己的ExpandableListAdapter
package android.widget;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.view.LayoutInflater;import java.util.List;import java.util.Map;/** * An easy adapter to map static data to group and child views defined in an XML * file. You can separately specify the data backing the group as a List of * Maps. Each entry in the ArrayList corresponds to one group in the expandable * list. The Maps contain the data for each row. You also specify an XML file * that defines the views used to display a group, and a mapping from keys in * the Map to specific views. This process is similar for a child, except it is * one-level deeper so the data backing is specified as a List<List<Map>>, * where the first List corresponds to the group of the child, the second List * corresponds to the position of the child within the group, and finally the * Map holds the data for that particular child. */public class SimpleExpandableListAdapter extends BaseExpandableListAdapter { private List<? extends Map<String, ?>> mGroupData; private int mExpandedGroupLayout; private int mCollapsedGroupLayout; private String[] mGroupFrom; private int[] mGroupTo; private List<? extends List<? extends Map<String, ?>>> mChildData; private int mChildLayout; private int mLastChildLayout; private String[] mChildFrom; private int[] mChildTo; private LayoutInflater mInflater; /** * Constructor * * @param context The context where the {@link ExpandableListView} * associated with this {@link SimpleExpandableListAdapter} is * running * @param groupData A List of Maps. Each entry in the List corresponds to * one group in the list. The Maps contain the data for each * group, and should include all the entries specified in * "groupFrom" * @param groupFrom A list of keys that will be fetched from the Map * associated with each group. * @param groupTo The group views that should display column in the * "groupFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the groupFrom parameter. * @param groupLayout resource identifier of a view layout that defines the * views for a group. The layout file should include at least * those named views defined in "groupTo" * @param childData A List of List of Maps. Each entry in the outer List * corresponds to a group (index by group position), each entry * in the inner List corresponds to a child within the group * (index by child position), and the Map corresponds to the data * for a child (index by values in the childFrom array). The Map * contains the data for each child, and should include all the * entries specified in "childFrom" * @param childFrom A list of keys that will be fetched from the Map * associated with each child. * @param childTo The child views that should display column in the * "childFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the childFrom parameter. * @param childLayout resource identifier of a view layout that defines the * views for a child. The layout file should include at least * those named views defined in "childTo" */ public SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int groupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo) { this(context, groupData, groupLayout, groupLayout, groupFrom, groupTo, childData, childLayout, childLayout, childFrom, childTo); } /** * Constructor * * @param context The context where the {@link ExpandableListView} * associated with this {@link SimpleExpandableListAdapter} is * running * @param groupData A List of Maps. Each entry in the List corresponds to * one group in the list. The Maps contain the data for each * group, and should include all the entries specified in * "groupFrom" * @param groupFrom A list of keys that will be fetched from the Map * associated with each group. * @param groupTo The group views that should display column in the * "groupFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the groupFrom parameter. * @param expandedGroupLayout resource identifier of a view layout that * defines the views for an expanded group. The layout file * should include at least those named views defined in "groupTo" * @param collapsedGroupLayout resource identifier of a view layout that * defines the views for a collapsed group. The layout file * should include at least those named views defined in "groupTo" * @param childData A List of List of Maps. Each entry in the outer List * corresponds to a group (index by group position), each entry * in the inner List corresponds to a child within the group * (index by child position), and the Map corresponds to the data * for a child (index by values in the childFrom array). The Map * contains the data for each child, and should include all the * entries specified in "childFrom" * @param childFrom A list of keys that will be fetched from the Map * associated with each child. * @param childTo The child views that should display column in the * "childFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the childFrom parameter. * @param childLayout resource identifier of a view layout that defines the * views for a child. The layout file should include at least * those named views defined in "childTo" */ public SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo) { this(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo, childData, childLayout, childLayout, childFrom, childTo); } /** * Constructor * * @param context The context where the {@link ExpandableListView} * associated with this {@link SimpleExpandableListAdapter} is * running * @param groupData A List of Maps. Each entry in the List corresponds to * one group in the list. The Maps contain the data for each * group, and should include all the entries specified in * "groupFrom" * @param groupFrom A list of keys that will be fetched from the Map * associated with each group. * @param groupTo The group views that should display column in the * "groupFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the groupFrom parameter. * @param expandedGroupLayout resource identifier of a view layout that * defines the views for an expanded group. The layout file * should include at least those named views defined in "groupTo" * @param collapsedGroupLayout resource identifier of a view layout that * defines the views for a collapsed group. The layout file * should include at least those named views defined in "groupTo" * @param childData A List of List of Maps. Each entry in the outer List * corresponds to a group (index by group position), each entry * in the inner List corresponds to a child within the group * (index by child position), and the Map corresponds to the data * for a child (index by values in the childFrom array). The Map * contains the data for each child, and should include all the * entries specified in "childFrom" * @param childFrom A list of keys that will be fetched from the Map * associated with each child. * @param childTo The child views that should display column in the * "childFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the childFrom parameter. * @param childLayout resource identifier of a view layout that defines the * views for a child (unless it is the last child within a group, * in which case the lastChildLayout is used). The layout file * should include at least those named views defined in "childTo" * @param lastChildLayout resource identifier of a view layout that defines * the views for the last child within each group. The layout * file should include at least those named views defined in * "childTo" */ public SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, int lastChildLayout, String[] childFrom, int[] childTo) { mGroupData = groupData; mExpandedGroupLayout = expandedGroupLayout; mCollapsedGroupLayout = collapsedGroupLayout; mGroupFrom = groupFrom; mGroupTo = groupTo; mChildData = childData; mChildLayout = childLayout; mLastChildLayout = lastChildLayout; mChildFrom = childFrom; mChildTo = childTo; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public Object getChild(int groupPosition, int childPosition) { return mChildData.get(groupPosition).get(childPosition); } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { View v; if (convertView == null) { v = newChildView(isLastChild, parent); } else { v = convertView; } bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo); return v; } /** * Instantiates a new View for a child. * @param isLastChild Whether the child is the last child within its group. * @param parent The eventual parent of this new View. * @return A new child View */ public View newChildView(boolean isLastChild, ViewGroup parent) { return mInflater.inflate((isLastChild) ? mLastChildLayout : mChildLayout, parent, false); } private void bindView(View view, Map<String, ?> data, String[] from, int[] to) { int len = to.length; for (int i = 0; i < len; i++) { TextView v = (TextView)view.findViewById(to[i]); if (v != null) { v.setText((String)data.get(from[i])); } } } public int getChildrenCount(int groupPosition) { return mChildData.get(groupPosition).size(); } public Object getGroup(int groupPosition) { return mGroupData.get(groupPosition); } public int getGroupCount() { return mGroupData.size(); } public long getGroupId(int groupPosition) { return groupPosition; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View v; if (convertView == null) { v = newGroupView(isExpanded, parent); } else { v = convertView; } bindView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo); return v; } /** * Instantiates a new View for a group. * @param isExpanded Whether the group is currently expanded. * @param parent The eventual parent of this new View. * @return A new group View */ public View newGroupView(boolean isExpanded, ViewGroup parent) { return mInflater.inflate((isExpanded) ? mExpandedGroupLayout : mCollapsedGroupLayout, parent, false); } public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } public boolean hasStableIds() { return true; }}
- 06.实例篇:仿QQ好友列表——ExpandableListView和ListView(下篇)
- 05.实例篇:仿QQ好友列表——ExpandableListView可扩展列表的使用(上篇)
- ExpandableListView仿QQ好友列表
- ExpandableListView仿QQ好友列表
- 仿QQ好友列表 ExpandableListView
- 完全仿QQ好友列表,自定义ExpandableListView!
- 完全仿QQ好友列表,自定义ExpandableListView!
- 完全仿QQ好友列表,自定义ExpandableListView!
- ExpandableListView实现仿QQ好友列表
- android 实现QQ好友列表(扩展listview:ExpandableListView)
- android 实现QQ好友列表(扩展listview:ExpandableListView)
- android 实现QQ好友列表(扩展listview:ExpandableListView)
- android 实现QQ好友列表(扩展listview:ExpandableListView)
- 仿QQ聊天(3)—好友列表的实现
- 在Fragment里面使用ExpandableListView实现仿qq好友列表
- Android 仿QQ好友分组列表、ExpandableListView的使用详解
- 仿QQ好友列表
- 仿QQ项目(一):好友列表
- HDU2955-Robberies
- windows开发常见问题系列--2 鼠标键盘输入相关
- Android异步HTTP客户端的特点
- linux下的C语言开发(静态库)
- clk_get函数实现,Linux内核时钟框架
- 06.实例篇:仿QQ好友列表——ExpandableListView和ListView(下篇)
- OCP 1Z0 051 90
- 我的Android进阶之旅------>Android用PopupWindow实现弹出菜单实例
- “简密”App Store处女作开发总结
- synchronized 学习(一)
- struts1自动封装用户的请求数据
- Webbrowser获取<button>标签的class的值
- SPGridView and Pagination in SharePoint SharePoint中的SPGridView和分页功能
- RMI - Java远程方法调用