1.首先说明一个知识点,通常我们显示布局文件xml都是如下:
setContentView(R.layout.activity_main);
其实每一个xml布局文件就好像一个气球,我们可以使用View.inflate(Context context,int resource , ViewGroup root),inflate单词的意思就是:打气筒,也就是使用打气筒方法inflate(静态方法,返回View)把xml这个气球打成View,交给系统去显示;也就是说如下:
setContentView(R.layout.activity_main);
等价于:
View view = View.inflate(MainActivity.this,R.layout.activity_main, null);
setContentView(view);
2. 学生信息管理系统案例实现过程:
(1)新建一个Android工程,如下:
(2)首先我们设置学生信息系统的UI,来到activity_main.xml,如下:
1 <LinearLayout 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 android:gravity="center_horizontal" 6 android:orientation="vertical" 7 tools:context="com.himi.studentsys.MainActivity" > 8 9 <TextView 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" 12 android:gravity="center_horizontal" 13 android:text="学生管理系统" 14 android:textColor="#66ffff" 15 android:textSize="25dp" /> 16 17 <LinearLayout 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" 20 android:orientation="horizontal" > 21 22 <EditText 23 android:inputType="text" 24 android:hint="姓名" 25 android:id="@+id/et_name" 26 android:layout_width="0dp" 27 android:layout_height="wrap_content" 28 android:layout_weight="3" /> 29 30 <EditText 31 android:inputType="phone" 32 android:hint="电话" 33 android:id="@+id/et_phone" 34 android:layout_width="0dp" 35 android:layout_height="wrap_content" 36 android:layout_weight="3" /> 37 38 <Button 39 android:onClick="add" 40 android:id="@+id/button1" 41 style="?android:attr/buttonStyleSmall" 42 android:layout_width="0dp" 43 android:layout_height="wrap_content" 44 android:layout_weight="2" 45 android:text="添加" /> 46 47 LinearLayout> 48 49 <ListView 50 android:layout_width="fill_parent" 51 android:layout_height="fill_parent" 52 android:id="@+id/lv"> 53 54 ListView> 55 56 LinearLayout>
布局效果如下:
(3)上面学生信息要存储到数据库,自然这里需要创建数据库(实现数据增删改查),如下:
新建一个包,包名为"com.himi.studentsys.db",在这个包下新建一个类StudentDBOpenHelper(数据库帮助类),让它继承自SQLiteOpenHelper,这里StudentDBOpenHelper实现 数据库 和 表 的创建。
1 package com.himi.studentsys.db; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 import android.database.sqlite.SQLiteOpenHelper; 7 8 public class StudentDBOpenHelper extends SQLiteOpenHelper { 9 10 public StudentDBOpenHelper(Context context) { 11 super(context, "student.db", null, 1); 12 } 13 14 @Override 15 public void onCreate(SQLiteDatabase db) { 16 db.execSQL("create table info (_id integer primary key autoincrement,name varchar(20),phone varchar(20))"); 17 } 18 19 @Override 20 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 21 22 } 23 24 }
下面接着实现数据库增删改查的工具类StudentDao,新建一个包"com.himi.studentsys.db.dao",如下:
1 package com.himi.studentsys.db.dao; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.content.ContentValues; 7 import android.content.Context; 8 import android.database.Cursor; 9 import android.database.sqlite.SQLiteDatabase; 10 11 import com.himi.studentsys.db.StudentDBOpenHelper; 12 13 /** 14 * 学生信息的dao代码:data access object 15 * 提供增删改查 16 */ 17 public class StudentDao { 18 19 private StudentDBOpenHelper helper; 20 /** 21 * 没有无参的构造方法,只能用下面的构造方法去初始化dao 22 * @param context 23 */ 24 public StudentDao(Context context) { 25 helper = new StudentDBOpenHelper(context); 26 } 27 /** 28 * 添加一个学生信息 29 * @param name 姓名 30 * @param phone 电话 31 * @return 添加在数据库的第几行 32 */ 33 public long add(String name,String phone){ 34 // 获取可写的数据库 35 SQLiteDatabase db = helper.getWritableDatabase(); 36 // 获取插入值对象 37 ContentValues values = new ContentValues(); 38 // 设置插入值 39 values.put("name", name); 40 values.put("phone", phone); 41 // 调用数据库插入方法 42 long rowid = db.insert("info", null, values); 43 // 关闭数据库连接 44 db.close(); 45 return rowid; 46 } 47 /** 48 * 删除一条学生信息 49 * @param id 学生id 50 * @return 影响了几行,0代表删除失败 51 */ 52 public int delete(String id){ 53 SQLiteDatabase db = helper.getWritableDatabase(); 54 int result = db.delete("info", "_id=?", new String[]{id}); 55 db.close(); 56 return result; 57 } 58 59 /** 60 * 获取所有的学生信息 61 * @return 62 */ 63 public ListfindAll(){ 64 SQLiteDatabase db = helper.getReadableDatabase(); 65 List infos = new ArrayList (); 66 Cursor cursor = db.query("info", new String[]{"_id","name","phone"}, null, null, null, null, null); 67 while(cursor.moveToNext()){ 68 StudentInfo info = new StudentInfo(); 69 String id = cursor.getString(0); 70 String name = cursor.getString(1); 71 String phone = cursor.getString(2); 72 info.setId(id); 73 info.setName(name); 74 info.setPhone(phone); 75 infos.add(info); 76 } 77 cursor.close(); 78 db.close(); 79 return infos; 80 } 81 }
上面查询数据的时候需要一个业务bean类,新建一个包"com.himi.studentsys.db.bean",创建一个学生信息的bean类StudentInfo,如下:
1 package com.himi.studentsys.db.bean; 2 3 /** 4 * 学生信息的业务bean 5 */ 6 public class StudentInfo { 7 private String id; 8 private String name; 9 private String phone; 10 public String getId() { 11 return id; 12 } 13 public void setId(String id) { 14 this.id = id; 15 } 16 public String getName() { 17 return name; 18 } 19 public void setName(String name) { 20 this.name = name; 21 } 22 public String getPhone() { 23 return phone; 24 } 25 public void setPhone(String phone) { 26 this.phone = phone; 27 } 28 @Override 29 public String toString() { 30 return "StudentInfo [id=" + id + ", name=" + name + ", phone=" + phone 31 + "]"; 32 } 33 } 34
(4)实现Button的点击事件,实现添加数据到数据库:
来到MainActivity,如下:
1 package com.himi.studentsys; 2 3 import java.util.List; 4 5 import android.app.Activity; 6 import android.graphics.Color; 7 import android.os.Bundle; 8 import android.text.TextUtils; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.view.Window; 12 import android.widget.BaseAdapter; 13 import android.widget.EditText; 14 import android.widget.ListView; 15 import android.widget.TextView; 16 import android.widget.Toast; 17 18 import com.himi.studentsys.db.bean.StudentInfo; 19 import com.himi.studentsys.db.dao.StudentDao; 20 21 public class MainActivity extends Activity { 22 private EditText et_name; 23 private EditText et_phone; 24 private ListView lv; 25 /** 26 * 学生信息的dao 27 */ 28 private StudentDao dao; 29 /** 30 * 所有的学生信息 31 */ 32 private Listinfos; 33 /** 34 * 全局的数据适配器 35 */ 36 private StudentAdapter adapter; 37 38 @Override 39 protected void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 requestWindowFeature(Window.FEATURE_NO_TITLE); 42 setContentView(R.layout.activity_main); 43 44 et_name = (EditText) findViewById(R.id.et_name); 45 et_phone = (EditText) findViewById(R.id.et_phone); 46 lv = (ListView) findViewById(R.id.lv); 47 48 dao = new StudentDao(this); 49 50 infos = dao.findAll(); 51 adapter = new StudentAdapter(); 52 lv.setAdapter(adapter); 53 } 54 55 /** 56 * 添加一个信息到数据库 57 * @param view 58 */ 59 public void add(View view){ 60 String name = et_name.getText().toString().trim(); 61 String phone = et_phone.getText().toString().trim(); 62 63 if(TextUtils.isEmpty(name)||TextUtils.isEmpty(phone)){ 64 Toast.makeText(this, "数据不能为空", 0).show(); 65 return ; 66 } 67 long result = dao.add(name, phone); 68 if(result>0){ 69 Toast.makeText(this, "添加成功", 0).show(); 70 71 infos = dao.findAll(); 72 adapter.notifyDataSetChanged();//-->从新调用getcount 调用getview 73 }else{ 74 Toast.makeText(this, "添加失败", 0).show(); 75 } 76 } 77 78 79 private class StudentAdapter extends BaseAdapter{ 80 @Override 81 public int getCount() { 82 return infos.size(); 83 } 84 85 @Override 86 public View getView(final int position, View convertView, 87 ViewGroup parent) { 88 System.out.println("position" + position); 89 TextView tv; 90 if (convertView == null) { 91 tv = new TextView(MainActivity.this); 92 } else { 93 tv = (TextView) convertView; 94 } 95 tv.setTextSize(20); 96 tv.setTextColor(Color.RED); 97 tv.setText(infos.get(position).toString()); 98 99 return tv; 100 101 } 102 @Override 103 public Object getItem(int position) { 104 return null; 105 } 106 @Override 107 public long getItemId(int position) { 108 return 0; 109 } 110 } 111 }
这时候布署程序到模拟器上,如下:
明显这个UI效果不好,要完善一下。
(5)完善优化显示的UI效果:
优化UI显示,主要是修改Adapter 中的getView()方法,来到MainActivity,如下:
1 package com.himi.studentsys; 2 3 import java.util.List; 4 5 import android.app.Activity; 6 import android.graphics.Color; 7 import android.os.Bundle; 8 import android.text.TextUtils; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.widget.BaseAdapter; 12 import android.widget.EditText; 13 import android.widget.ListView; 14 import android.widget.TextView; 15 import android.widget.Toast; 16 17 import com.himi.studentsys.db.bean.StudentInfo; 18 import com.himi.studentsys.db.dao.StudentDao; 19 20 public class MainActivity extends Activity { 21 22 private EditText et_name; 23 private EditText et_phone; 24 private ListView lv; 25 26 /** 27 * 学生信息的dao 28 */ 29 private StudentDao dao; 30 /** 31 * 所有的学生信息 32 */ 33 private Listinfos; 34 @Override 35 protected void onCreate(Bundle savedInstanceState) { 36 super.onCreate(savedInstanceState); 37 setContentView(R.layout.activity_main); 38 initViews(); 39 } 40 41 private void initViews() { 42 // TODO 自动生成的方法存根 43 et_name = (EditText) findViewById(R.id.et_name); 44 et_phone = (EditText) findViewById(R.id.et_phone); 45 lv = (ListView) findViewById(R.id.lv); 46 47 dao = new StudentDao(this); 48 refreshUI(); 49 } 50 51 /** 52 * 刷新显示 53 */ 54 public void refreshUI() { 55 //获取数据库数据 56 infos = dao.findAll(); 57 //设置数据 58 lv.setAdapter(new StudentAdapter()); 59 } 60 61 62 private class StudentAdapter extends BaseAdapter { 63 64 public int getCount() { 65 // TODO 自动生成的方法存根 66 return infos.size(); 67 } 68 69 public View getView(int position, View convertView, ViewGroup parent) { 70 /*TextView tv; 71 if(convertView == null) { 72 tv= new TextView(MainActivity.this); 73 }else { 74 tv = (TextView) convertView; 75 } 76 tv.setTextSize(20); 77 tv.setTextColor(Color.RED); 78 tv.setText(infos.get(position).toString());*/ 79 80 View view = View.inflate(MainActivity.this, R.layout.item, null); 81 TextView tv_id = (TextView) view.findViewById(R.id.tv_id); 82 TextView tv_name = (TextView) view.findViewById(R.id.tv_name); 83 TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone); 84 85 //设置数据 86 tv_id.setText(infos.get(position).getId()); 87 tv_name.setText(infos.get(position).getName()); 88 tv_phone.setText(infos.get(position).getPhone()); 89 90 return view; 91 } 92 public Object getItem(int position) { 93 // TODO 自动生成的方法存根 94 return null; 95 } 96 97 public long getItemId(int position) { 98 // TODO 自动生成的方法存根 99 return 0; 100 } 101 102 103 104 } 105 106 107 /** 108 * 添加数据到数据库 109 * @param v 110 */ 111 public void add(View v) { 112 String name = et_name.getText().toString().trim(); 113 String phone = et_phone.getText().toString().trim(); 114 115 if(TextUtils.isEmpty(name) || TextUtils.isEmpty(phone)) { 116 Toast.makeText(this, "数据不能为空", 0).show(); 117 return; 118 } 119 long result = dao.add(name, phone); 120 if(result>0) { 121 Toast.makeText(this, "添加成功", 0).show(); 122 refreshUI(); 123 }else { 124 Toast.makeText(this, "添加失败", 0).show(); 125 refreshUI(); 126 } 127 } 128 129 130 131 }
自定义的条目布局item.xml,如下:
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="wrap_content" 5 android:orientation="horizontal" > 6 <TextView 7 android:id="@+id/tv_id" 8 android:drawableLeft="@drawable/ic_menu_cc" 9 android:textColor="#bbff0000" 10 android:gravity="center_vertical" 11 android:layout_width="0dip" 12 android:layout_height="wrap_content" 13 android:layout_weight="1" 14 android:text="id"/> 15 16 <TextView 17 android:id="@+id/tv_name" 18 android:textColor="#bbffff00" 19 android:gravity="center_vertical" 20 android:layout_width="0dip" 21 android:layout_height="wrap_content" 22 android:layout_weight="1" 23 android:text="name"/> 24 25 <TextView 26 android:id="@+id/tv_phone" 27 android:textColor="#bb0000ff" 28 android:gravity="center_vertical" 29 android:layout_width="0dip" 30 android:layout_height="wrap_content" 31 android:layout_weight="1" 32 android:text="phone"/> 33 34 35 LinearLayout>
它的布局效果是:
(6)上面只有添加数据到数据库并显示的效果,这里添加删除数据库中数据的效果
修改item.xml如下:
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="wrap_content" 5 android:orientation="horizontal" > 6 <TextView 7 android:id="@+id/tv_id" 8 android:drawableLeft="@drawable/ic_menu_cc" 9 android:textColor="#bbff0000" 10 android:gravity="center_vertical" 11 android:layout_width="0dip" 12 android:layout_height="wrap_content" 13 android:layout_weight="3" 14 android:text="id"/> 15 16 <TextView 17 android:id="@+id/tv_name" 18 android:textColor="#bbffff00" 19 android:gravity="center_vertical" 20 android:layout_width="0dip" 21 android:layout_height="wrap_content" 22 android:layout_weight="3" 23 android:text="name"/> 24 25 <TextView 26 android:id="@+id/tv_phone" 27 android:textColor="#bb0000ff" 28 android:gravity="center_vertical" 29 android:layout_width="0dip" 30 android:layout_height="wrap_content" 31 android:layout_weight="3" 32 android:text="phone"/> 33 34 <ImageView 35 android:id="@+id/iv_delete" 36 android:layout_width="0dip" 37 android:layout_height="wrap_content" 38 android:layout_weight="1" 39 android:src="@drawable/ic_menu_delete"/> 40 41 42 LinearLayout>
布局效果如下:
再来到MainActivity之中,如下:
1 package com.himi.studentsys; 2 3 import java.util.List; 4 5 import android.app.Activity; 6 import android.app.AlertDialog; 7 import android.app.AlertDialog.Builder; 8 import android.content.DialogInterface; 9 import android.os.Bundle; 10 import android.text.TextUtils; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.view.ViewGroup; 14 import android.view.Window; 15 import android.widget.BaseAdapter; 16 import android.widget.EditText; 17 import android.widget.ImageView; 18 import android.widget.ListView; 19 import android.widget.TextView; 20 import android.widget.Toast; 21 22 import com.himi.studentsys.db.bean.StudentInfo; 23 import com.himi.studentsys.db.dao.StudentDao; 24 25 public class MainActivity extends Activity { 26 private EditText et_name; 27 private EditText et_phone; 28 private ListView lv; 29 /** 30 * 学生信息的dao 31 */ 32 private StudentDao dao; 33 /** 34 * 所有的学生信息 35 */ 36 private Listinfos; 37 /** 38 * 全局的数据适配器 39 */ 40 private StudentAdapter adapter; 41 42 @Override 43 protected void onCreate(Bundle savedInstanceState) { 44 super.onCreate(savedInstanceState); 45 requestWindowFeature(Window.FEATURE_NO_TITLE); 46 setContentView(R.layout.activity_main); 47 48 et_name = (EditText) findViewById(R.id.et_name); 49 et_phone = (EditText) findViewById(R.id.et_phone); 50 lv = (ListView) findViewById(R.id.lv); 51 52 dao = new StudentDao(this); 53 54 infos = dao.findAll(); 55 adapter = new StudentAdapter(); 56 lv.setAdapter(adapter); 57 } 58 59 /** 60 * 添加一个信息到数据库 61 * @param view 62 */ 63 public void add(View view){ 64 String name = et_name.getText().toString().trim(); 65 String phone = et_phone.getText().toString().trim(); 66 67 if(TextUtils.isEmpty(name)||TextUtils.isEmpty(phone)){ 68 Toast.makeText(this, "数据不能为空", 0).show(); 69 return ; 70 } 71 long result = dao.add(name, phone); 72 if(result>0){ 73 Toast.makeText(this, "添加成功", 0).show(); 74 75 infos = dao.findAll(); 76 adapter.notifyDataSetChanged();//-->从新调用getcount 调用getview 77 }else{ 78 Toast.makeText(this, "添加失败", 0).show(); 79 } 80 } 81 82 83 private class StudentAdapter extends BaseAdapter{ 84 @Override 85 public int getCount() { 86 return infos.size(); 87 } 88 89 @Override 90 public View getView(final int position, View convertView, ViewGroup parent) { 91 System.out.println("position"+position); 92 View view = View.inflate(MainActivity.this, R.layout.item, null); 93 94 TextView tv_id = (TextView) view.findViewById(R.id.tv_id); 95 TextView tv_name = (TextView) view.findViewById(R.id.tv_name); 96 TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone); 97 ImageView iv_delete = (ImageView) view.findViewById(R.id.iv_delete); 98 99 iv_delete.setOnClickListener(new OnClickListener() { 100 @Override 101 public void onClick(View v) { 102 AlertDialog.Builder builder = new Builder(MainActivity.this); 103 builder.setTitle("提醒"); 104 builder.setMessage("是否确定删除?"); 105 builder.setPositiveButton("确定删除", new DialogInterface.OnClickListener() { 106 @Override 107 public void onClick(DialogInterface dialog, int which) { 108 // 获取该位置组件id,并删除 109 int result = dao.delete(infos.get(position).getId()); 110 Toast.makeText(MainActivity.this, "删除了"+result+"个记录", 0).show(); 111 // 重新查询 112 infos = dao.findAll(); 113 adapter.notifyDataSetChanged(); 114 } 115 }); 116 builder.setNegativeButton("取消", null); 117 builder.create().show(); 118 } 119 }); 120 // 修改对应值 121 tv_id.setText(infos.get(position).getId()); 122 tv_name.setText(infos.get(position).getName()); 123 tv_phone.setText(infos.get(position).getPhone()); 124 return view; 125 } 126 @Override 127 public Object getItem(int position) { 128 return null; 129 } 130 @Override 131 public long getItemId(int position) { 132 return 0; 133 } 134 } 135 }
(7)最终代码已经完成,布署程序到模拟器上:
工程项目一览图: