ListView 是一个View ,按照相近的格式,垂直放置的方式。在配置时,宽高尽量设置与父容器一样大(或者给一个固定的值)。
若是宽高是包裹内容,则每次都会根据内容的大小而改变View的大小,导致View可重用性差,导致getView方法调用多次,严重影响效率。
ListAdapter 适配器,是数据源与ListView的桥梁,是一个接口。
可以在MainActivity中新建一个内部类 ,实现BaseAdapter(该类实现了ListAdapter接口)
getCount();决定了展示多少条数据。
public View getView(int position, View convertView, ViewGroup parent);这个是决定了每个展示的View的样式。position指当前显示第多少个View,从0开始。
注意若是getCount();返回的数值很大,则很容易在快速下滑的过程中,卡死。
View是重复使用的,创建View的速度,若是太快,垃圾回收机制来不及回收,则容易内存溢出。
convertView 表示可以重用的View,若是此为空,则说明没有可重用的View对象,需要创建新的view。
public View getView(int position, View convertView, ViewGroup parent) {
TextView view;
if(convertView!=null)
{
view=(TextView) convertView;
Log.i("MainActivity", view.getText().toString());
}else{
view=new TextView(MainActivity.this);
Log.i("MainActivity", "新建第"+position+"个View");
}
view.setText("我是第"+position);
return view;
}
这样的话,资源就不是被回收,然后新建一个View,而是尽可能的重复利用过去被遗弃的View,然后给其新赋一些值,这样就不会卡死了。
ListView的复杂使用,
通过xml来获取View对象,View.inflate(MainActivity.this, R.layout.XXX,viewGroup);
第一个参数上下文,第二个来定位资源,第三个参数viewGroup(LinearLayout,RelativeLayout,等)若是传入了一个实体,则新创建的View对象就会作为这个ViewGroup的一个
childView,可以传入null。
不止是View可以调用inflate方法,
LayoutInflater inflater=getLayoutInflater();
inflater=(LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
//inflater=LayoutInflater.from(MainActivity.this);
//inflater.inflate(R.layout.items, null);
三种方式都可以获得LayoutInflater对象,并调用inflate方法获取View对象。
还可以使用 ArrayAdapter ,来制造稍微复杂的View , 如下所示,R.id.tv_text 是一个 Text 控件的 id ,这样可以给ListView的每一个 R.id.tv_text 设置值。
这种适配器主要适用于 ,每个条目中修改的条目十分简单,比如,只有一个TextView部件的值需要改变。
ListView list_view=(ListView) findViewById(R.id.lv_list);
String[]strs=new String[3];
strs[0]="wan";
strs[1]="hao";
strs[2]="wudi";
ArrayAdapteradapter2=new ArrayAdapter(this, R.layout.item2, R.id.tv_text, strs);
list_view.setAdapter(adapter2);
第一个参数表Context,第二个参数布局文件(注意:这个布局文件指的是构成一个条目的布局文件)的位置,第三个参数表示构成一个条目的布局文件中需要修改内容的控件的id,最后一项表示,用来修改的信息集合。
SimpleAdapter 主要用来展示稍微复杂些的条目展示,可以在一个条目中同时修改多项数据。
比如:每个栏目中的标题和内容。
构造函数,第一个参数上下文content,第二个参数为要显示的数据,是一个参数为Map
List< Map> data =new ArrayList
综合案例:用ListView展示数据库的内容。
public class MainActivity extends Activity {
private Listusers=new ArrayList();
private MyOpenHelper helper;
private ListView list_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list_view=(ListView) findViewById(R.id.lv_list);
helper=new MyOpenHelper(this);
list_view.setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return users.size();
}
@Override
public Object getItem(int position) {
return users.get(position);
}
// 返回的值是展示时,所在的位置编号,通常不用该
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//这一部分就是固定的套路
View view;
if(convertView==null){
view= View.inflate(MainActivity.this, R.layout.item2, null);
}
else{
view = convertView;
}
//view 表示一项数据,找到这一项数据中的name,phone部件
TextView name=(TextView) view.findViewById(R.id.tv_name);
TextView phone=(TextView) view.findViewById(R.id.tv_phone);
name.setText(users.get(position).name);
phone.setText(users.get(position).phone);
return view;
}
}
public void insert(View v){
SQLiteDatabase database=helper.getReadableDatabase();
database.execSQL("insert into user(name,phone) values('张三','1310');");
database.execSQL("insert into user(name,phone) values('张四','1311');");
database.execSQL("insert into user(name,phone) values('张五','1312');");
database.close();
}
public void query(View v){
SQLiteDatabase database=helper.getReadableDatabase();
Cursor cursor=database.rawQuery("select * from user;",null);
while(cursor.moveToNext())
{
User u=new User();
u.name=cursor.getString(1);
u.phone=cursor.getString(2);
users.add(u);
}
cursor.close();
database.close();
//每次查询完结果后,都必须重新设置Adapter() ,相当于局部更新页面
list_view.setAdapter(new MyAdapter());
}
}