android Listview是一个非常常用的控件,这里备份下它的各种使用方式。
github:
【 https://github.com/cstriker1407/android/tree/master/HelloListView 】
CONTENTS
最基本的使用
java代码:
public class Activity1 extends Activity { private List<String> dataList; private ArrayList<HashMap<String, String>> mylist; private ListView listView1; private ListView listView2; private ArrayAdapter<String> adapter2; private SimpleAdapter mSchedule; private int idx = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity1); //绑定XML中的ListView,作为Item的容器 listView1 = (ListView) findViewById(R.id.listView1); //生成动态数组,并且转载数据 mylist = new ArrayList<HashMap<String, String>>(); for(int i=0;i<20;i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put("ItemTitle", "This is Title....." + i); map.put("ItemText", "This is text....."); mylist.add(map); } //生成适配器,数组===》ListItem mSchedule = new SimpleAdapter(this, //没什么解释 mylist,//数据来源 R.layout.my_listitem,//ListItem的XML实现 //动态数组与ListItem对应的子项 new String[] {"ItemTitle", "ItemText"}, //ListItem的XML文件里面的两个TextView ID new int[] {R.id.ItemTitle,R.id.ItemText}); //添加并且显示 listView1.setAdapter(mSchedule); dataList = new ArrayList<String>(); for (int i = 0; i < 20; i++) { dataList.add("test " + idx++ ); } listView2 = (ListView)findViewById(R.id.listView2); Button headButton = new Button(this); listView2.addHeaderView(headButton); adapter2 = new ArrayAdapter<String>(this, R.layout.my_listitem, R.id.ItemTitle, dataList); listView2.setAdapter(adapter2); ((Button)findViewById(R.id.button1)).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { for(int i=20;i<25;i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put("ItemTitle", "This is Title....." + i); map.put("ItemText", "This is text....."); mylist.add(map); } mSchedule.notifyDataSetChanged(); for (int i = 0; i < 5; i++) { dataList.add("test " + idx++); } adapter2.notifyDataSetChanged(); } }); } }
my_listitem.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/MyListItem" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingBottom="3dip" android:paddingLeft="10dip" > <TextView android:id="@+id/ItemTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="30dip" > </TextView> <TextView android:id="@+id/ItemText" android:layout_width="fill_parent" android:layout_height="wrap_content" > </TextView> </LinearLayout>
备注:
代码写的比较乱,这里简单总结下:
1)简单的listview的adapter可以使用SimpleAdapter或ArrayAdapter来实现,通过传入自定义layout的id,可以方便的使用自定义layout。
2)在设置完数据之后,我们仍然可以通过修改数据源,然后调用adapter的 notifyDataSetChanged() 方法来刷新页面。
3)可以通过 addHeadView 和 addFooterView 方法来为listview添加上下的view。
使用SimpleCursorAdapter
java代码:
ListView listView1 = (ListView)findViewById(R.id.listView1); Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null); startManagingCursor(cursor); ListAdapter listAdapter = new SimpleCursorAdapter(this, R.layout.my_listitem, cursor, new String[]{People.NAME}, new int[]{R.id.ItemTitle}); listView1.setAdapter(listAdapter); listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(Activity2.this, "position:" + position, Toast.LENGTH_SHORT).show(); } });
备注:
1)cursoradapter有一些使用注意事项,后续备忘。
2)可以通过设置listview的 setOnItemClickListener 方法来实现简单的单击相应。
使用自定义的apdater:
java代码:
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); for(int i=0;i<20;i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put("ItemTitle", "This is Title....." + i); map.put("ItemText", "This is text....."); mylist.add(map); } ListView listView2 = (ListView)findViewById(R.id.listView2); listView2.setAdapter(new Activity2Adapter(this, mylist));
class Activity2Adapter extends BaseAdapter { class ViewHolder { public TextView title; public TextView info; } private LayoutInflater mInflater; private ArrayList<HashMap<String, String>> mylist; public Activity2Adapter(Context context, ArrayList<HashMap<String, String>> mylist) { this.mInflater = LayoutInflater.from(context); this.mylist = mylist; } @Override public int getCount() { return mylist.size(); } @Override public Object getItem(int arg0) { return null; } @Override public long getItemId(int arg0) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.my_listitem, null); holder.title = (TextView)convertView.findViewById(R.id.ItemTitle); holder.info = (TextView)convertView.findViewById(R.id.ItemText); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.title.setText((String)mylist.get(position).get("ItemTitle")); holder.info.setText((String)mylist.get(position).get("ItemText")); return convertView; } }
备注:
1)使用自定义的adapter有非常多的实例,而且istview的使用基本上都是使用自定义的adapter。
2)关于adapter的各个方法的实现,这里只实现了最简单的几个。其他的具体需求可以参考sdk。
分组listview:
java代码:
public class Activity3 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity3); List<Map<String, String>> mylist = new ArrayList<Map<String, String>>(); List<Map<String, String>> splitList = new ArrayList<Map<String, String>>(); // 组织数据源 Map<String, String> mp = new HashMap<String, String>(); mp.put("itemTitle", "A"); mylist.add(mp); splitList.add(mp); for (int i = 0; i < 3; i++) { Map<String, String> map = new HashMap<String, String>(); map.put("itemTitle", "文章1-" + i); mylist.add(map); } mp = new HashMap<String, String>(); mp.put("itemTitle", "B"); mylist.add(mp); splitList.add(mp); for (int i = 0; i < 6; i++) { Map<String, String> map = new HashMap<String, String>(); map.put("itemTitle", "文章2-" + i); mylist.add(map); } ListView listView1 = (ListView) findViewById(R.id.listView1); listView1.setAdapter(new Activity3Adapter(this, mylist, splitList)); } } class Activity3Adapter extends BaseAdapter { private LayoutInflater mInflater; private List<Map<String, String>> listData; private List<Map<String, String>> splitData; public Activity3Adapter(Context context, List<Map<String, String>> listData, List<Map<String, String>> splitData) { this.mInflater = LayoutInflater.from(context); this.listData = listData; this.splitData = splitData; } @Override public int getCount() { return listData.size(); } @Override public Object getItem(int position) { return listData.get(position); } @Override public long getItemId(int position) { return position; } @Override public boolean isEnabled(int position) { if (splitData.contains(listData.get(position))) { return false; } return super.isEnabled(position); } @Override public View getView(final int position, View convertView, ViewGroup parent) { if (splitData.contains(listData.get(position))) { convertView = mInflater.inflate(R.layout.my_listitem_tag, null); } else { convertView = mInflater.inflate(R.layout.my_listitem, null); } TextView textView = (TextView) convertView.findViewById(R.id.ItemTitle); textView.setText(listData.get(position).get("itemTitle")); return convertView; } }
备注:
1)通过分析代码可以发现,实现这种listview的核心在于通过重写 getView 方法,根据当前的位置ID来生成不同的view。
可伸缩扩展ListView:
java文件:
public class Activity4 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity4); ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); for(int i=0;i<20;i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put("ItemTitle", "This is Title....." + i); map.put("ItemText", "This is text....." + i); map.put("visible","1"); mylist.add(map); } ListView listView2 = (ListView)findViewById(R.id.listView1); listView2.setAdapter(new Activity4Adapter(this, mylist)); listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if( "1".equals(((Activity4Adapter)parent.getAdapter()).mylist.get(position).get("visible")) ) { ((Activity4Adapter)parent.getAdapter()).mylist.get(position).put("visible", "0"); }else { ((Activity4Adapter)parent.getAdapter()).mylist.get(position).put("visible", "1"); } ((Activity4Adapter)parent.getAdapter()).notifyDataSetChanged(); } }); } } class ViewHolder { public TextView title; public TextView info; } class Activity4Adapter extends BaseAdapter { private LayoutInflater mInflater; public ArrayList<HashMap<String, String>> mylist; public Activity4Adapter(Context context, ArrayList<HashMap<String, String>> mylist) { this.mInflater = LayoutInflater.from(context); this.mylist = mylist; } @Override public int getCount() { return mylist.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.my_listitem, null); holder.title = (TextView)convertView.findViewById(R.id.ItemTitle); holder.info = (TextView)convertView.findViewById(R.id.ItemText); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.title.setText((String)mylist.get(position).get("ItemTitle")); holder.info.setText((String)mylist.get(position).get("ItemText")); if("1".equals((String)mylist.get(position).get("visible"))) { holder.info.setVisibility(View.VISIBLE); }else { holder.info.setVisibility(View.GONE); } return convertView; } }
备注:
1)代码写的比较绕,主要是想尝试下listview的各种方法。
2)通过分析代码,该需求的实现很简单:接收到单击相应的view设置自己的子view的显示模式(VISIBLE 或者 GONE),然后通知页面刷新;在getview的实现方法中加以处理,防止上下刷新后页面混乱。
单选多选Listview
java文件:
String[] GENRES = new String[] { "Action", "Adventure", "Animation", "Children", "Comedy", "Documentary", "Drama", "Foreign", "History", "Independent", "Romance", "Sci-Fi", "Television", "Thriller" }; ListView listView1 = (ListView)findViewById(R.id.listView1); listView1.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_single_choice, GENRES)); listView1.setItemsCanFocus(false); listView1.setChoiceMode(ListView.CHOICE_MODE_SINGLE); ListView listView2 = (ListView)findViewById(R.id.listView2); listView2.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_multiple_choice, GENRES)); listView2.setItemsCanFocus(false); listView2.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
备注:
1)demo代码只是实现了最简单的单选多选,实际应用中单选多选往往很复杂,一般会用自定义的layout来实现。
ExpandableListView:
java代码:
public class Activity6 extends Activity { private static final String NAME = "NAME"; private static final String IS_EVEN = "IS_EVEN"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity6); ExpandableListView expandableListView1 = (ExpandableListView) findViewById(R.id.expandableListView1); /* 父级的数据list,每个元素是一个hashmap */ List<Map<String, String>> groupData = new ArrayList<Map<String, String>>(); /* 子类数据list,每个元素也是一个list,这个list是这个子链表的元素集合。 */ List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>(); for (int i = 0; i < 20; i++) { Map<String, String> curGroupMap = new HashMap<String, String>(); groupData.add(curGroupMap); curGroupMap.put(NAME, "Group " + i); curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd"); List<Map<String, String>> children = new ArrayList<Map<String, String>>(); for (int j = 0; j < 15; j++) { Map<String, String> curChildMap = new HashMap<String, String>(); children.add(curChildMap); curChildMap.put(NAME, "Child " + j); curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd"); } childData.add(children); } expandableListView1.setAdapter( new SimpleExpandableListAdapter( this, groupData, android.R.layout.simple_expandable_list_item_1, new String[] { NAME, IS_EVEN }, new int[] { android.R.id.text1, android.R.id.text2 }, childData, android.R.layout.simple_expandable_list_item_2, new String[] { NAME, IS_EVEN }, new int[] { android.R.id.text1, android.R.id.text2 } )); ExpandableListView expandableListView2 = (ExpandableListView) findViewById(R.id.expandableListView2); expandableListView2.setAdapter(new MyExpandableListAdapter()); expandableListView2.expandGroup(0);//设置第一组张开 expandableListView2.setGroupIndicator(null);//除去自带的箭头 } class MyExpandableListAdapter extends BaseExpandableListAdapter { // Sample data set. children[i] contains the children (String[]) for groups[i]. private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" }; private String[][] children = { { "Arnold", "Barry", "Chuck", "David" }, { "Ace", "Bandit", "Cha-Cha", "Deuce" }, { "Fluffy", "Snuggles" }, { "Goldy", "Bubbles" } }; public Object getChild(int groupPosition, int childPosition) { return children[groupPosition][childPosition]; } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public int getChildrenCount(int groupPosition) { return children[groupPosition].length; } public TextView getGenericView() { // Layout parameters for the ExpandableListView AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 64); TextView textView = new TextView(Activity6.this); textView.setLayoutParams(lp); // Center the text vertically textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); // Set the text starting position textView.setPadding(36, 0, 0, 0); return textView; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView textView = getGenericView(); textView.setText(getChild(groupPosition, childPosition).toString()); return textView; } public Object getGroup(int groupPosition) { return groups[groupPosition]; } public int getGroupCount() { return groups.length; } public long getGroupId(int groupPosition) { return groupPosition; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { TextView textView = getGenericView(); textView.setText(getGroup(groupPosition).toString()); return textView; } public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } public boolean hasStableIds() { return true; } } }
备注:
1)ExpandableListView是一个可以内嵌listview的listview。demo里面包含两种实现方式,都比较简略。如果要实际应用,需要查询SDK。
XListView-Android-master的使用:
XListView是一个非常简单好用的可以支持上拉,下拉Listview的开源库。
github:
【 https://github.com/Maxwin-z/XListView-Android 】
使用方法:
1)将开源库demo中【 me.maxwin.view 】包下的三个java文件【 XListView.java 】【 XListViewHeader.java 】【 XListViewFooter.java 】拷贝到项目工程里。
2)将开源库demo中【 res/drawable-hdpi 】文件夹下的【 xlistview_arrow.png 】拷贝到项目工程相同路径下。
3)将开源库demo中【 res/layout 】文件夹下的【 xlistview_footer.xml 】【 xlistview_header.xml 】拷贝到项目工程相同路径下。
4)将开源库demo中【 values 】文件夹下的【 strings.xml 】合并到项目工程相同文件下。
java文件:
public class Activity7 extends Activity { private XListView mListView; private ArrayAdapter<String> mAdapter; private ArrayList<String> items = new ArrayList<String>(); private int start = 0; private void geneItems() { for (int i = 0; i != 20; ++i) { items.add("refresh cnt " + (++start)); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity7); mListView = (XListView) findViewById(R.id.xListView1); mListView.setPullLoadEnable(true); mAdapter = new ArrayAdapter<String>(this, R.layout.list_item, items); mListView.setAdapter(mAdapter); // mListView.setPullLoadEnable(false); // mListView.setPullRefreshEnable(false); mListView.setXListViewListener(new IXListViewListener() { @Override public void onRefresh() { geneItems(); mAdapter.notifyDataSetChanged(); mListView.stopRefresh(); mListView.stopLoadMore(); mListView.setRefreshTime("刚刚"); } @Override public void onLoadMore() { geneItems(); mAdapter.notifyDataSetChanged(); mListView.stopRefresh(); mListView.stopLoadMore(); mListView.setRefreshTime("刚刚"); } }); } }
XML文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <me.maxwin.view.XListView android:id="@+id/xListView1" android:layout_width="match_parent" android:layout_height="match_parent" > </me.maxwin.view.XListView> </LinearLayout>
备注:
1)xlistview的代码写的非常简洁,可以非常容易进行扩充和修改,很多项目都在使用它。
Android-PullToRefresh的使用:
android-pulltorefresh是另外一个非常好用的支持上拉,下拉Listview的开源库。android-pulltorefresh的代码分为3个部分,写的比Xlistview要多多了。
github:
【 https://github.com/chrisbanes/Android-PullToRefresh 】
使用方法:
和使用其他的开源库一样,将pulltorefresh下载下来,连接到项目工程中,就可以使用了。
java文件:
public class Activity8 extends Activity { private ArrayList<String> mListItems; private ArrayAdapter<String> mAdapter; private PullToRefreshListView pullToRefreshView; private int idx = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity8); mListItems = new ArrayList<String>(); for (int i = 0; i < 10; i++) { mListItems.add("string" + idx++); } mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems); pullToRefreshView = (PullToRefreshListView) findViewById(R.id.pull_to_refresh_listview); pullToRefreshView.setOnRefreshListener(new OnRefreshListener2<ListView>() { public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { for (int i = 0; i < 5; i++) { mListItems.add("Down string" + idx++); } Toast.makeText(Activity8.this, "Pull Down!", Toast.LENGTH_SHORT).show(); new GetDataTask().execute(); } public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { for (int i = 0; i < 5; i++) { mListItems.add("Up string" + idx++); } Toast.makeText(Activity8.this, "Pull Up!", Toast.LENGTH_SHORT).show(); new GetDataTask().execute(); } }); pullToRefreshView.setMode(PullToRefreshBase.Mode.BOTH); pullToRefreshView.getRefreshableView().setAdapter(mAdapter); } private class GetDataTask extends AsyncTask<Void, Void, String[]> { @Override protected String[] doInBackground(Void... params) { // Simulates a background job. try { Thread.sleep(1000); } catch (InterruptedException e) { } return null; } @Override protected void onPostExecute(String[] result) { // Call onRefreshComplete when the list has been refreshed. pullToRefreshView.onRefreshComplete(); super.onPostExecute(result); } } }
XML文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/pull_to_refresh_listview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
备注:
1)如果要同时支持上拉,下拉操作,需要显示的调用 setMode 方法。
备注:
1)android的listview是一个使用非常广泛的控件,网上有各种使用方法。这里简单备份下一些常见的方法。
2)上述demo很多都简化了大量的业务操作,如果要实际应用,需要查询下sdk。以后补上更详细的demo。
3)参考【 http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html 】【 http://blog.csdn.net/hellogv/article/details/4542668 】【 http://iaiai.iteye.com/blog/1188668 】
发表评论