Android学习之sqlite与listview

2018-02-27 17:26:36 浏览数 (1)

在android系统中使用的是sqlite数据库,前面的简易登录系统已经讲述了数据库的应用。本例的重点是实现数据库与listview的绑定。demo的数据是将个人的信息绑定到listview中,并存在sqlite。

1.person类

代码语言:javascript复制
 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项。

代码语言:javascript复制
 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         <TextView
13             android:layout_width="wrap_content"
14             android:layout_height="wrap_content"
15             android:text="@string/tvname" />
16 
17         <TextView
18             android:id="@ id/tv_name"
19             android:layout_width="match_parent"
20             android:layout_height="wrap_content" />
21 
22     </LinearLayout>
23 
24 <LinearLayout
25     android:layout_width="match_parent"
26     android:layout_height="wrap_content"
27     android:orientation="horizontal" >
28 
29     <TextView
30         android:layout_width="wrap_content"
31         android:layout_height="wrap_content"
32         android:text="@string/tvage" />
33 
34     <TextView
35         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

代码语言:javascript复制
 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可以添加底部或者头部的视图对象。

代码语言:javascript复制
 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   <ProgressBar
13       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信息是手动添加到数据库的,并不是在代码中自己生成的数据。

代码语言:javascript复制
 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         <TextView
14             android:layout_width="wrap_content"
15             android:layout_height="wrap_content"
16             android:text="@string/tvname" />
17 
18         <EditText
19             android:id="@ id/edname"
20             android:layout_width="match_parent"
21             android:layout_height="wrap_content" />
22 
23     </LinearLayout>
24 
25     <LinearLayout
26         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         <TextView
33             android:layout_width="wrap_content"
34             android:layout_height="wrap_content"
35             android:text="@string/tvage" />
36 
37         <EditText
38             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的使用。

代码语言:javascript复制
 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的显示方式。

代码语言:javascript复制
 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的某一项,即可弹出删除的上下文菜单。

代码语言:javascript复制
 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数据库相关。

代码语言:javascript复制
 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     @Override
10     public void onCreate(SQLiteDatabase db) {
11         // TODO Auto-generated method stub
12         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         try
23         {
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     @Override
36     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
37         // TODO Auto-generated method stub
38 
39     }

sqlhelper类用来数据库和表的创建,同时定义了添加person的方法。

代码语言:javascript复制
 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            else
18            {
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中的添加之后,会弹出添加用户的对话框,点击确定信息将会被保存。

代码语言:javascript复制
 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。

代码语言:javascript复制
 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         @Override
11         public int getCount() {
12             // TODO Auto-generated method stub
13             if(list.size()>5)
14             {
15                 return count;
16             }
17             else
18             {
19             return list.size();
20             }
21         }
22 
23         @Override
24         public Object getItem(int arg0) {
25             // TODO Auto-generated method stub
26             return null;
27         }
28 
29         @Override
30         public long getItemId(int arg0) {
31             // TODO Auto-generated method stub
32             return 0;
33         }
34 
35         @Override
36         public View getView(int arg0, View arg1, ViewGroup arg2) {
37             // TODO Auto-generated method stub
38             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条数据的时候,将全部显示。这里设置返回的数目是关键。

代码语言:javascript复制
 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                         @Override
14                         public void run() {
15                             // TODO Auto-generated method stub
16                             
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中,很多系统在用户按返回键的时候,并不是直接退出,而是弹出对话框。

代码语言:javascript复制
 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 stub
10                     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.系统实例

0 人点赞