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