首页 > 代码库 > 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

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>
person_item

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

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>
footer

底部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>
personinfo

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>
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的初始化以及对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       }
contextmenu

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

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     }
addperson

该段代码实现了个人信息的添加,通过调用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     }
delteperson

个人信息删除调用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     }
baseadapter

本例定义每次只能显示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.系统实例