首页 > 代码库 > Android学习之sqlite与listview
Android学习之sqlite与listview
在android系统中使用的是sqlite数据库,前面的简易登录系统已经讲述了数据库的应用。本例的重点是实现数据库与listview的绑定。demo的数据是将个人的信息绑定到listview中,并存在sqlite。
1.person类
1 public class PersonInfo 2 { 3 public PersonInfo() 4 { 5 6 } 7 private String name; 8 private int age; 9 public void setNmae(String name)10 {11 this.name=name;12 }13 public String getName()14 {15 return name;16 }17 public int getAge()18 {19 return age;20 }21 public void setAge(int age)22 {23 this.age=age;24 }25 }
person类定义了name和age两个属性字段
2.list_item.xml
本例是将person信息绑定到listview中,有必要定义自己的listview项。
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <LinearLayout 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content"10 android:orientation="horizontal" >11 12 <TextView13 android:layout_width="wrap_content"14 android:layout_height="wrap_content"15 android:text="@string/tvname" />16 17 <TextView18 android:id="@+id/tv_name"19 android:layout_width="match_parent"20 android:layout_height="wrap_content" />21 22 </LinearLayout>23 24 <LinearLayout25 android:layout_width="match_parent"26 android:layout_height="wrap_content"27 android:orientation="horizontal" >28 29 <TextView30 android:layout_width="wrap_content"31 android:layout_height="wrap_content"32 android:text="@string/tvage" />33 34 <TextView35 android:id="@+id/tv_age"36 android:layout_width="match_parent"37 android:layout_height="wrap_content" />38 39 </LinearLayout>40 </LinearLayout>
xml文档中定义了几个textview分别用来显示name和age。
3.main.xml
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context=".MainActivity" > 6 7 <ListView 8 android:id="@+id/listView1" 9 android:layout_width="match_parent"10 android:layout_height="match_parent" >11 </ListView>12 13 </RelativeLayout>
main,xml只有一个listview,用来显示person
4.list_footer
listview可以添加底部或者头部的视图对象。
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <Button 8 android:id="@+id/bt_load" 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:text="加载更多数据" /> 12 <ProgressBar13 android:id="@+id/pg"14 android:layout_width="wrap_content"15 android:layout_height="wrap_content"16 android:layout_gravity="center_horizontal"17 android:visibility="gone"18 />19 </LinearLayout>
底部xml只有button,用来加载更多的数据。
5.personinfo.xml
本例的person信息是手动添加到数据库的,并不是在代码中自己生成的数据。
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" > 6 7 <LinearLayout 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content"10 android:layout_gravity="center"11 android:orientation="horizontal" >12 13 <TextView14 android:layout_width="wrap_content"15 android:layout_height="wrap_content"16 android:text="@string/tvname" />17 18 <EditText19 android:id="@+id/edname"20 android:layout_width="match_parent"21 android:layout_height="wrap_content" />22 23 </LinearLayout>24 25 <LinearLayout26 android:layout_width="fill_parent"27 android:layout_height="wrap_content"28 android:layout_gravity="center"29 android:layout_weight="0"30 android:orientation="horizontal" >31 32 <TextView33 android:layout_width="wrap_content"34 android:layout_height="wrap_content"35 android:text="@string/tvage" />36 37 <EditText38 android:id="@+id/edage"39 android:layout_width="match_parent"40 android:layout_height="wrap_content"41 android:inputType="number" />42 43 </LinearLayout>44 45 </LinearLayout>
xml定义了edittext,写入nanme和age
6.menu.xml
menu是本例的重点,本来是研究menu的使用。
1 <menu xmlns:android="http://schemas.android.com/apk/res/android" > 2 3 <item android:showAsAction="ifRoom|withText" android:id="@+id/action_add" android:title="@string/action_add"></item> 4 <item android:showAsAction="ifRoom|withText" android:id="@+id/action_delete" android:title="@string/action_delete"></item> 5 <item 6 android:id="@+id/action_settings" 7 android:orderInCategory="100" 8 android:showAsAction="never" 9 android:title="@string/action_settings"/>10 11 </menu>
本文档定义了几个菜单项,如果运行在3.0以上的android系统中,ui显示方式有很大不同。showasaction用来设置menu的显示方式。
1 @Override 2 public boolean onCreateOptionsMenu(Menu menu) { 3 // Inflate the menu; this adds items to the action bar if it is present. 4 getMenuInflater().inflate(R.menu.main, menu); 5 return true; 6 } 7 public boolean onOptionsItemSelected(MenuItem menu) 8 { 9 switch(menu.getItemId())10 {11 case R.id.action_add:12 addUser();13 return true;14 case R.id.action_delete:15 //deleteUser();16 return true;17 default:18 super.onOptionsItemSelected(menu);19 }20 return true;21 }
这段代码是menu的初始化以及对menu菜单项选中事件的监听。
7.contextmenu
本例个人信息的删除是用contextmenu实现的,用户长按lsitview的某一项,即可弹出删除的上下文菜单。
1 public void onCreateContextMenu(ContextMenu menu,View view,ContextMenuInfo menuInof) 2 3 { 4 super.onCreateContextMenu(menu, view, menuInof); 5 menu.add(0,1,Menu.NONE,"删除"); 6 } 7 public boolean onContextItemSelected(MenuItem item) 8 { 9 switch(item.getItemId())10 {11 case 1:12 deleteUser(delname);13 return true;14 default:15 return false;16 }17 }
registerForContextMenu(listview);菜单注册到某视图。
8.addperson和deleteperson
添加和删除个人信息都与sqlite数据库相关。
1 private static final String DATABASE_NAME="test"; 2 public SQLiteHelper(Context context, String name, CursorFactory factory, 3 int version) { 4 super(context, name, factory, version); 5 this.getWritableDatabase(); 6 // TODO Auto-generated constructor stub 7 } 8 9 @Override10 public void onCreate(SQLiteDatabase db) {11 // TODO Auto-generated method stub12 db.execSQL("CREATE TABLE IF NOT EXISTS person"+"(id INTEGER PRIMARY KEY,name VARCHAR,age INTEGER)");13 14 }15 //关闭数据库16 public void close()17 {18 this.getWritableDatabase().close();19 }20 public boolean Addperson(int age,String name)21 {22 try23 {24 ContentValues cv=new ContentValues();25 cv.put("name", name);26 cv.put("age", age);27 this.getWritableDatabase().insert("person", null, cv);28 return true;29 }30 catch(Exception ex)31 {32 return false;33 }34 }35 @Override36 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {37 // TODO Auto-generated method stub38 39 }
sqlhelper类用来数据库和表的创建,同时定义了添加person的方法。
1 private void addUser() { 2 // TODO Auto-generated method stub 3 final LinearLayout layout=(LinearLayout)getLayoutInflater().inflate(R.layout.personinfo, null); 4 new AlertDialog.Builder(this).setTitle("添加联系人").setView(layout).setPositiveButton("确定",new OnClickListener() { 5 6 @Override 7 public void onClick(DialogInterface dialog, int which) { 8 // TODO Auto-generated method stub 9 EditText edname=(EditText)layout.findViewById(R.id.edname);10 EditText edage=(EditText)layout.findViewById(R.id.edage);11 String sql="select * from person where name=?";12 Cursor cursor=sqlhelper.getWritableDatabase().rawQuery(sql, new String[]{edname.getText().toString()});13 if(cursor.moveToFirst())14 {15 Toast.makeText(MainActivity.this, "已经存在", Toast.LENGTH_LONG).show();16 }17 else18 {19 if(sqlhelper.Addperson(Integer.parseInt(edage.getText().toString()), edname.getText().toString()))20 {21 PersonInfo person=new PersonInfo();22 person.setNmae(edname.getText().toString());23 person.setAge(Integer.parseInt(edage.getText().toString()));24 list.add(person);25 adapter.notifyDataSetChanged();26 Toast.makeText(MainActivity.this, "信息添加成功", Toast.LENGTH_LONG).show();27 }28 }29 }30 }).setNegativeButton("取消", null).show();31 }
该段代码实现了个人信息的添加,通过调用AlertDialog实现。点击menu中的添加之后,会弹出添加用户的对话框,点击确定信息将会被保存。
1 private void deleteUser(String str) { 2 // TODO Auto-generated method stub 3 try 4 { 5 sqlhelper.getWritableDatabase().delete("person", "name=?", new String[]{str}); 6 for(int i=0;i<list.size();i++) 7 { 8 PersonInfo person=list.get(i); 9 if(person.getName()==str)10 {11 list.remove(i);12 }13 }14 adapter.notifyDataSetChanged();15 }16 catch(Exception ex)17 {18 Toast.makeText(this, "删除失败", Toast.LENGTH_LONG).show();19 }20 }
个人信息删除调用sqlite的delete方法实现,需要传入表的名称,删除的条件。同时在完成数据的删除后,通知listview数据已经发生变化。本例将读取到的数据存在list中,所以移除了list中的数据。
9.Mybaseadapter
mybaseadapter是listview的适配器,继承与baseadapter。
1 public class MyAdapter extends BaseAdapter 2 { 3 4 int count=5; 5 Context mcontext; 6 public MyAdapter(Context context) 7 { 8 mcontext=context; 9 }10 @Override11 public int getCount() {12 // TODO Auto-generated method stub13 if(list.size()>5)14 {15 return count;16 }17 else18 {19 return list.size();20 }21 }22 23 @Override24 public Object getItem(int arg0) {25 // TODO Auto-generated method stub26 return null;27 }28 29 @Override30 public long getItemId(int arg0) {31 // TODO Auto-generated method stub32 return 0;33 }34 35 @Override36 public View getView(int arg0, View arg1, ViewGroup arg2) {37 // TODO Auto-generated method stub38 PersonInfo person=new PersonInfo();39 if(arg1==null)40 {41 arg1=LayoutInflater.from(mcontext).inflate(R.layout.person_item, null);42 }43 44 person=(PersonInfo)list.get(arg0);45 46 TextView edname=(TextView)arg1.findViewById(R.id.tv_name);47 TextView edage=(TextView)arg1.findViewById(R.id.tv_age);48 edname.setText(person.name);49 edage.setText(String.valueOf(person.age));50 return arg1;51 }52 53 }
本例定义每次只能显示5条数据。当小于5条数据的时候,将全部显示。这里设置返回的数目是关键。
1 btnpro=(Button)moreview.findViewById(R.id.bt_load); 2 pg=(ProgressBar)moreview.findViewById(R.id.pg); 3 btnpro.setOnClickListener(new View.OnClickListener() { 4 5 @Override 6 public void onClick(View v) { 7 // TODO Auto-generated method stub 8 pg.setVisibility(View.VISIBLE);// 将进度条可见 9 btnpro.setVisibility(View.GONE);// 按钮不可见10 Handler hanldre=new Handler();11 hanldre.postDelayed(new Runnable(){12 13 @Override14 public void run() {15 // TODO Auto-generated method stub16 17 adapter.count+=5;18 19 btnpro.setVisibility(View.VISIBLE);20 pg.setVisibility(View.GONE);21 if(adapter.count>list.size())22 23 {24 adapter. count=list.size();25 btnpro.setVisibility(View.INVISIBLE);26 }27 adapter.notifyDataSetChanged();28 }}, 2000);29 }30 });
这是加载更多数据按钮的监听事件。代码中新建了hanlder实例,用来加载更多的数据。其中当count大于list.size,count等于list.size.
10.系统退出
在android中,很多系统在用户按返回键的时候,并不是直接退出,而是弹出对话框。
1 public boolean onKeyDown(int keyCode, KeyEvent event) 2 { 3 if(keyCode==KeyEvent.KEYCODE_BACK && event.getRepeatCount()==0) 4 { 5 new AlertDialog.Builder(this).setTitle("系统提示").setMessage("确定退出系统吗").setPositiveButton("确定", new OnClickListener() { 6 7 @Override 8 public void onClick(DialogInterface dialog, int which) { 9 // TODO Auto-generated method stub10 android.os.Process.killProcess(android.os.Process.myPid()); 11 }12 }).setNegativeButton("取消", null).show();13 return true;14 }15 else if(keyCode==KeyEvent.KEYCODE_MENU && event.getRepeatCount()==0)16 {17 openOptionsMenu();18 return true;19 }20 return true;21 }
这个功能通过重写onkeydown方法实现。但是实现过程中发现menu菜单不能显示了,所以在这里加了一个判断,并调用了 openOptionsMenu()。
11.系统实例