Android(安卓)ListView
本文包含:
一、一般的listview(系统自定义样式)
二、自定义Listview
一、一般Listview
实例效果:
- 下方
EditText
回车则添加到ListView
中 - 点击
ListView
中某item
直接删除该Item
ListView属性
属性 | 解释 |
---|---|
android:entries=”@array/listViewNameArray” | 指定数据 |
android:divider=”@color/colorAccent” | 分隔符颜色 |
android:choiceMode=”singleChoice” | 选择模式(单选、多选) |
1、最简单实例
- 通过
android:entries="@array/listViewNameArray"
指定内容 "@array/listViewNameArray"
为value
下String
中的String-array
(string数组)
<?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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.feather.androiddemos.ListViewActivity" android:orientation="vertical"> <ListView android:entries="@array/listViewNameArray" android:divider="@color/colorAccent" android:choiceMode="singleChoice" android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content"> ListView> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10pt" android:hint="输入内容进行添加"/>LinearLayout>
2、通过ArrayAdapter设置ListView
//string 数组 String arrays[] = {"nanjing", "beijing", "nantong", "shanghai", "chongqing"}; //初始化适配器 ArrayAdapter adapter = new ArrayAdapter(this, //context android.R.layout.simple_spinner_item, //布局:使用系统自带文字布局 arrays); //string数组 //获得控件ListView listView = (ListView) findViewById(R.id.listView); //设置适配器 listView.setAdapter(adapter);
可以使用系统专门给listview提供的布局
如:
1. simple_list_item_1
2. simple_list_item_single_choice 有单选框
3、在ListActivity
中使用ListView
xml布局文件
ListView
的ID必须为@android:id/list
<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.feather.androiddemos.ListViewActivity" android:orientation="vertical"> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10pt" android:layout_alignParentBottom="true" android:hint="输入内容进行添加"/> <ListView android:id="@android:id/list" android:entries="@array/listViewNameArray" android:divider="@color/colorAccent" android:choiceMode="singleChoice" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/editText"> ListView>RelativeLayout>
Java
- 继承ListActivity
- 设置适配器
//string 数组 String arrays[] = {"nanjing", "beijing", "nantong", "shanghai"}; //初始化适配器 ArrayAdapter adapter = new ArrayAdapter(this, //context android.R.layout.simple_list_item_1, //布局:使用系统自带文字布局 arrays); //string数组 //设置适配器 this.setListAdapter(adapter);
- 获得listview方法并且进行监听
listView = getListView(); //获得ListViewlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { }});
4、通过EditText输入并添加listview的item
- 通过ListActivity实现
public class ListViewActivity extends ListActivity { ListView listView = null; ArrayList listItems = null; EditText editText = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view); editText = (EditText) findViewById(R.id.editText); listItems = new ArrayList<>(); //初始化适配器 final ArrayAdapter adapter = new ArrayAdapter(this, //context android.R.layout.simple_list_item_1, //布局:使用系统自带文字布局 listItems); //数据链表 this.setListAdapter(adapter); listView = getListView(); //获得ListView listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(ListViewActivity.this, "当前点击的Item:"+position, Toast.LENGTH_SHORT).show(); } }); //EditText监听器 editText.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { //输入Enter并且松开 if(keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { listItems.add(editText.getText().toString()); adapter.notifyDataSetChanged();//通知数据发生改变 editText.setText(null); } return false; } }); }}
观察者模式
又被称为“发布订阅模式”
自定义ListView
步骤:
- xml布局文件(包含listview)
- 适配器java代码(用于如何自定义Listview)
这里继承了
ArrayAdapter
适配器,记得构造函数中传入自定义对象ReadingItem
的链表。
public class ReadingAdapater extends ArrayAdapter<ReadingItem>{ int resource_id; ReadingQuestion readingQuestion; QuestionReadingActivity activity;//记得要有`List objects` public ReadingAdapater(Context context, int resource, List objects, ReadingQuestion readingQuestion, QuestionReadingActivity activity) { super(context, resource, objects); this.resource_id = resource; this.readingQuestion = readingQuestion; //传入的一些自定义对象 this.activity = activity; } @Override public View getView(int position, View convertView, ViewGroup parent) { //获得具体对象(构造器传入的链表:objects) readingItem = getItem(position); if(convertView == null){ convertView = LayoutInflater.from(getContext()).inflate(resource_id, null); /*---------------------*/ /* 这里进行自定义 */ /*---------------------*/ } return convertView; }
- 使用
//获得ListViewListView listView = (ListView) view.findViewById(R.id.reading_item_list);//新建适配器对象readingAdapater = new ReadingAdapater(QuestionReadingActivity.this, R.layout.question__item, lists, //传入数据的链表 readingQuestion, this);//设置适配器listView.setAdapter(readingAdapater);//这里是Listview只显示一行时的解决办法,具体见错误汇总1.fixListViewHeight(listView);
三、知识点汇总
小的知识点,记录下来,以备将来用。
如何让listview滚动到底部 ?
方法一:
msgListView
是ListView
控件
adapter
是ListView
绑定的Adapter
,如果不方便直接使用,也可以通过ListView
的getAdapter()
方法获取到,前提是你已经绑定了适配器哦
里面的参数就很熟悉了吧,其实这个方法的主要作用是选中listview
的指定列,选中了,自然就得让这个item可见,自然就滚动咯
msgListView.setSelection(adapter.getCount()-1);
方法二:
这个就比较直接了
msgListView.setSelection(msgListView.getBottom());
四、错误汇总
1.ListView只显示一行
在代码正确时,发现实际效果Listview
只有一行,这是因为Listview
嵌套在ScrollView
中,会导致无法正确计算ListView
的大小。
解决方案如下:
链接:http://www.cnblogs.com/exmyth/p/4544551.html
方案1:去除ScrollView
方案2:在代码中,根据Listview的列表子项计算列表高度
listView = (ListView) findViewById(R.id.test_listView); //适配器listView.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,adapterData)); //计算高度fixListViewHeight(listView);
public void fixListViewHeight(ListView listView) { // 如果没有设置数据适配器,则ListView没有子项,返回。 ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int index = 0, len = listAdapter.getCount(); i < len; i++) { View listViewItem = listAdapter.getView(index , null, listView); // 计算子项View 的宽高 listViewItem.measure(0, 0); // 计算所有子项的高度和 totalHeight += listViewItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); // listView.getDividerHeight()获取子项间分隔符的高度 // params.height设置ListView完全显示需要的高度 params.height = totalHeight+ (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); }
2. notifyDataSetChanged()无效
情况一:数据库查询出ListView设置后不刷新
转载:
关于ListView中notifyDataSetChanged()刷新数据不更新原因 .
使用Listview的时候: 当要动态显示更改后的数据(例如数据库改动), 很多人应该都用过notifyDataSetChanged();这个方法来刷新Listview,显示改后的数据.
这时候就要注意了:
...... private ArrayList> usersList; ...... usersList= query(......); //根据查询函数获取一个ArrayList并赋值给绑定到Adapter的数据源usersList sAdapter.notifyDataSetChanged(); ......
如果你也是: 上面这种形式去刷新ListView的数据的话, 是不可以更新的. 必须改成如下形式:
...... //usersList= query(......); usersList.clear(); usersList.addAll(query(......)); sAdapter.notifyDataSetChanged();
原因是:
sAdapter会通过usersList获取List中的内容。但是实际上可能(也应该)是,在调用super(MyActivity.this, R.layout.item, usersList)时sAdapter保存了usersList指向原List(假设为List a)的引用,在调用query函数之后,usersList指向了一个新的List(List b)。但是在调用notifyDataSetChanged()时,sAdapter会跟据保存的引用(即指向List a的引用)去更新,因此当然还是原来的结果,不会进行更新。
如果大家也出现这种情况可以使用后者去刷新ListView, 应该就没问题了
情况二:多个线程里面ListView不刷新
只需要在UI
线程执行notifyDataSetChanged()
即可
代码如下:
runOnUiThread(new Runnable() { @Override public void run() { chatItemList.add(new ChatItem("test123", R.drawable.feather, "帅猎羽", msg, dateString)); adapter.notifyDataSetChanged(); }});
更多相关文章
- 【Android】Android(安卓)联系人数据库浅析之通话记录
- 【Android】WebView设置背景色
- android 自定义对话框
- Android:控件GridView的使用
- android:configChanges属性
- Android(安卓)TextView 文字居中
- Android(安卓)Battery 分析
- 系出名门Android(8) - 控件(View)之TextSwitcher, Gallery, Imag
- TextView属性android:ellipsize实现跑马灯效果