ScrollView:只能用于控件比较少的界面,如果数据有上千上万条,那么使用ScrollView就不好了,因为ScrollView就把所有的控件进行初始化,这是非常消耗性能的操作,所以android就设计了一个类ListView来专门处理列表数据条目的显示。
ListView:处理条目比较多,并且每个条目都非常相似的场景。就是一个条目控件,会自动回收没有在屏幕上显示的控件,来优化性能。
对于ListView和BaseAdapter
1简单的用法
MainActivity.java
packagecom.example.listview;importandroid.os.Bundle;importandroid.app.Activity;importandroid.util.Log;importandroid.view.Menu;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.BaseAdapter;importandroid.widget.ListView;importandroid.widget.TextView;public class MainActivity extendsActivity {protected static final String TAG = "MainActivity";
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//找到ListView
ListView lv =(ListView) findViewById(R.id.lv);//给ListView设置数据(设置适配器 基本适配器)
lv.setAdapter(newBaseAdapter() {//加工ListView需要的条目 int position 条目的下标
@Overridepublic View getView(intposition, View convertView, ViewGroup parent) {
Log.i(TAG,"position:"+position);
TextView tv= new TextView(MainActivity.this);
tv.setText("人生自古谁没有年轻的时候"+position);
tv.setTextSize(20);returntv;
}
@Overridepublic long getItemId(intposition) {return 0;
}
@Overridepublic Object getItem(intposition) {return null;
}//控制条目的数量
@Overridepublic intgetCount() {return 100;
}
});
}
}
activity_main.xml
上图就是ListView控件的基本图像
2复杂ListView的用法
首先要创建一个ListView和一个条目上的内容
activity_main.xml
item.xml
布局填充器layoutinflate:可以把res/layout下面的资源加载到内存,即可以把xml布局变成Java对象。一般就是加载item.xml上的东西
MainActivity.java
packagecom.example.listiview;importjava.util.ArrayList;importjava.util.List;importandroid.app.Activity;importandroid.content.Context;importandroid.os.Bundle;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.BaseAdapter;importandroid.widget.ListView;importandroid.widget.TextView;importcn.itcast.wh08.lv.domain.Teacher;public class MainActivity extendsActivity {
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv=(ListView) findViewById(R.id.lv);//模拟对象集合的数据 一般数据都是来自于网络,或者数据库
List data = new ArrayList();for(int i = 0;i<100;i++){
data.add(new Teacher(i, "隔壁老王"+i, i+20));
}//适配器
MyAdapter adapter = new MyAdapter(data, this);//设置适配器
lv.setAdapter(adapter);
}//适配器
private class MyAdapter extendsBaseAdapter{private Listdata;privateContext context;privateLayoutInflater mInflater;public MyAdapter(Listdata, Context context) {super();this.data =data;this.context =context;//获取布局加载器
mInflater =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Overridepublic intgetCount() {returndata.size();
}//返回条目指定位置的数据
@Overridepublic Object getItem(intposition) {returndata.get(position);
}
@Overridepublic long getItemId(intposition) {return 0;
}//加工条目
@Overridepublic View getView(intposition, View convertView, ViewGroup parent) {//使用布局加载器加载布局
View view = mInflater.inflate(R.layout.item, null);//找到条目对应的控件
TextView tv_name =(TextView) view.findViewById(R.id.tv_name);
TextView tv_age=(TextView) view.findViewById(R.id.tv_age);//获取条目对应的数据
Teacher info =data.get(position);//把数据绑定给控件
tv_name.setText(info.name);
tv_age.setText(info.age+"");returnview;
}
}
}
Teacher.java
packagecom.example.listview.vo;public classTeacher {public int_id;publicString _name;public intage;public Teacher(int _id, String _name, intage) {super();this._id =_id;this._name =_name;this.age =age;
}publicTeacher() {super();
}
}
3.与数据库结合来显示
mode 数据模型(数据) :要被显示到ListView上的数据集合
view 视图(展示数据) : ListView
controller控制层(把数据展示到空间上) : 适配器Adapter
我们还是要先建立ListView控件和item控件
activity_main.xml
-
item.xml
先建立一个数据库,为了得到数据。
MySqliteOpenHelper.java
packagecom.example.lisview.db;importandroid.content.ContentValues;importandroid.content.Context;importandroid.database.sqlite.SQLiteDatabase;importandroid.database.sqlite.SQLiteDatabase.CursorFactory;importandroid.database.sqlite.SQLiteOpenHelper;public class MySqliteOpenHelper extendsSQLiteOpenHelper {private staticSQLiteOpenHelper mInstance;public static synchronizedSQLiteOpenHelper getInstance(Context context) {if (mInstance == null) {
mInstance= new MySqliteOpenHelper(context, "itcast.db", null, 1);
}returnmInstance;
}publicMySqliteOpenHelper(Context context, String name,
CursorFactory factory,intversion) {super(context, name, factory, version);//TODO Auto-generated constructor stub
}
@Overridepublic voidonCreate(SQLiteDatabase db) {//设计一个表
db.execSQL("create table friends(_id integer primary key autoincrement,"
+ "name text," + "phone text)");//初始化表数据
ContentValues values = newContentValues();for (int i = 0; i < 100; i++) {
values.clear();
values.put("name", "老师" +i);
values.put("phone", "13787990" +i);
db.insert("friends", null, values);
}
}
@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, intnewVersion) {//TODO Auto-generated method stub
}
}
Friend.java
packagecom.example.lisview.vo;public classFriend {public int_id;publicString name;publicString phone;public Friend(int_id, String name, String phone) {super();this._id =_id;this.name =name;this.phone =phone;
}publicFriend() {//TODO Auto-generated constructor stub
}
}
对数据库的增、删、查、改
FriendDao.java
packagecom.example.lisview.dao;importjava.util.ArrayList;importjava.util.List;importandroid.content.Context;importandroid.database.Cursor;importandroid.database.sqlite.SQLiteDatabase;importandroid.database.sqlite.SQLiteOpenHelper;importcom.example.lisview.db.MySqliteOpenHelper;importcom.example.lisview.vo.Friend;public classFriendDao {privateContext context;privateSQLiteOpenHelper helper;publicFriendDao(Context context) {this.context =context;
helper=MySqliteOpenHelper.getInstance(context);
}/*** 获取数据的总条目
*@return
*/
public intqueryAllSize(){int size = 0;
SQLiteDatabase db=helper.getReadableDatabase();if(db.isOpen()){
Cursor cursor= db.query("friends", new String[]{"*"}, null, null, null, null, null);
size= cursor.getCount();//获取Cursor的大小
cursor.close();
db.close();
}returnsize;
}/*** 分页查询的
*
*@paramstartIndex
* 查询的开始下标
*@paramblock
* 每次查询的数据量
*@return
*/
public List queryFriendsLimit(int startIndex, intblock) {
List infos = new ArrayList();
SQLiteDatabase db=helper.getReadableDatabase();if(db.isOpen()) {
Cursor cursor= db.query("friends", new String[] { "*" }, null,null, null, null, null, startIndex + "," +block);while(cursor.moveToNext()) {int _id = cursor.getInt(0);
String name= cursor.getString(1);
String phone= cursor.getString(2);
infos.add(newFriend(_id, name, phone));
}
cursor.close();
db.close();
}returninfos;
}
}
MyAdapter.java
packagecom.example.lisview.service;importjava.util.List;importandroid.content.Context;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.BaseAdapter;importandroid.widget.TextView;importcom.example.lisview.R;importcom.example.lisview.vo.Friend;public class MyAdapter extendsBaseAdapter {private Listinfos;privateLayoutInflater mInflater;public void setInfos(Listinfos) {this.infos =infos;
}public MyAdapter(Listinfos, Context context) {super();this.infos =infos;//布局加载器
mInflater =LayoutInflater.from(context);
}//返回条目的总数
@Overridepublic intgetCount() {returninfos.size();
}//得到item.xml代表的对象
@Overridepublic Object getItem(intposition) {returninfos.get(position);
}//得到Item的id,不过在这里貌似没有用
@Overridepublic long getItemId(intposition) {returnposition;
}//得到Item的视图
@Overridepublic View getView(intposition, View convertView, ViewGroup parent) {
View view= mInflater.inflate(R.layout.item, null);
TextView tv_name=(TextView) view.findViewById(R.id.tv_name);
TextView tv_phone=(TextView) view.findViewById(R.id.tv_phone);
Friend info=infos.get(position);
tv_name.setText(info.name);
tv_phone.setText(info.phone);returnview;
}
}
MainActivity.java
packagecom.example.lisview;importjava.util.List;importandroid.app.Activity;importandroid.app.AlertDialog;importandroid.content.DialogInterface;importandroid.content.Intent;importandroid.net.Uri;importandroid.os.Bundle;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.AdapterView;importandroid.widget.AdapterView.OnItemClickListener;importandroid.widget.Button;importandroid.widget.ListView;importcom.example.lisview.dao.FriendDao;importcom.example.lisview.service.MyAdapter;importcom.example.lisview.vo.Friend;public class MainActivity extendsActivity {privateListView lv;privateButton bt_pre;privateButton bt_next;privateFriendDao friendDao;private int block = 10;//每一页获取10条数据
private int startIndex = 0;//获取数据的下标
privateMyAdapter adapter;private intsize;
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}private voidinitView() {
lv=(ListView) findViewById(R.id.lv);
bt_pre=(Button) findViewById(R.id.bt_pre);
bt_next=(Button) findViewById(R.id.bt_next);
MyOnClickListener l= newMyOnClickListener();
bt_pre.setOnClickListener(l);
bt_next.setOnClickListener(l);
friendDao= new FriendDao(this);
size=friendDao.queryAllSize();//查询第一页数据
List infos = friendDao.queryFriendsLimit(0, block);
adapter= new MyAdapter(infos, this);
lv.setAdapter(adapter);//设置条目点击事件
lv.setOnItemClickListener(newMyOnItemClickListener());
}private class MyOnItemClickListener implementsOnItemClickListener {
@Overridepublic void onItemClick(AdapterView> parent, View view, intposition,longid) {//获取条目的数据
final Friend info =(Friend) adapter.getItem(position);//弹出对话框
new AlertDialog.Builder(MainActivity.this)
.setTitle(info.name)
.setMessage("请选择操作")
.setPositiveButton("打电话", newDialogInterface.OnClickListener() {
@Overridepublic void onClick(DialogInterface dialog, intwhich) {//打电话需要拨号权限
Intent intent = newIntent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+info.phone));
startActivity(intent);
}
})
.setNegativeButton("发短信", newDialogInterface.OnClickListener() {
@Overridepublic void onClick(DialogInterface dialog, intwhich) {//TODO:学员自己处理
}
})
.show();
}
}private class MyOnClickListener implementsOnClickListener {
@Overridepublic voidonClick(View v) {
List infos = null;switch(v.getId()) {caseR.id.bt_pre:
startIndex= startIndex -block;if (startIndex == 0) {
bt_pre.setEnabled(false);
}else{
bt_pre.setEnabled(true);
}
bt_next.setEnabled(true);
infos=friendDao.queryFriendsLimit(startIndex, block);
adapter.setInfos(infos);//把查询的数据设置给适配器//刷新界面
adapter.notifyDataSetChanged();break;caseR.id.bt_next:
startIndex= startIndex +block;//判断是否是最后页面的数据//现在页面的数据 startIndex=startIndex+block
if ((startIndex + block) >=size) {//已经是最后一页数据
bt_next.setEnabled(false);
}else{
bt_next.setEnabled(true);
}
bt_pre.setEnabled(true);
infos=friendDao.queryFriendsLimit(startIndex, block);
adapter.setInfos(infos);//把查询的数据设置给适配器//刷新界面
adapter.notifyDataSetChanged();break;default:break;
}
}
}
}