1 SQLite简介
亮点:
① 轻 轻量级数据库 SQLite和C/S模式的数据库软件不同 体积小 没有服务端客户端 只要一个动态库就可以工作 (Linux下300多K)
② 绿 核心引擎本身不依赖第三方的软件,不需要安装 拷贝即可使用
③ 单一文件 一个数据库只有一个文件
④ 跨平台 支持多个嵌入式设备
槽点:
① 多线程性能差
② 不支持全部的SQL
何时使用数据库保存数据: 当有大量结构相似的数据需要保存 比如 短信 电话本 聊天记录
2 Android下创建SQLite数据库的正确姿势
2.1 核心类
① SQLiteOpenHelper
② SQLiteDataBase
2.2 使用方法
第一步: 创建一个类继承 SQLiteOpenHelper 并实现父类的构造
1.public class MySQLOpenHelper extends SQLiteOpenHelper {
2.
3. public MySQLOpenHelper(Context context) {
4. /**第一个参数 上下文
5. 第二个参数 创建的数据库文件名字
6. 第三个参数 游标工厂 通过游标工厂可以获得执行查询语句的返回值 Curor
7. 可以传 null 采用默认的游标工厂
8. 第四个参数 数据库的版本号 从1开始
9. **/
10. super(context, “itheima.db”, null, 1);
11. }
第二步 从写onCreate 方法 和onUpgrade 方法
第三步 在Activity中 创建MySQLOpenHelper对象( 注意 !!!! 至此并没有创建数据库)
第四部 调用 MySQLOpenHelper的getReadableDatabase或getWriteableDatabase方法获取SQLiteDataBase对象
1.public class MainActivity extends Activity {
2.
3. private SQLiteDatabase db;
4.
5. @Override
6. protected void onCreate(Bundle savedInstanceState) {
7. super.onCreate(savedInstanceState);
8. setContentView(R.layout.activity_main);
9. MySQLOpenHelper openHelper = new MySQLOpenHelper(this);
10. //获取SQLiteDatabase对象 如果数据库不存在则创建 如果存在则打开 如果磁盘空间满则出错
11. db = openHelper.getWritableDatabase();
12. //与getWritableDatabase功能类似 但如果磁盘空间满则会返回一个只读的数据库
13. db = openHelper.getReadableDatabase();
14. }
3 SQLiteOpenHelper的oncreate方法 和 onUpgrade方法
3.1onCreate方法(必须实现的方法)
当调用getReadableDatabase或getWriteableDatabase方法 第一次创建数据库的时候会执行这个方法
作用: 在这个方法中做创建表 和初始化数据的操作
1.@Override
2. public void onCreate(SQLiteDatabase db) {
3. //适合做创建表 初始化数据的操作
4. db.execSQL(“create table info (_id integer primary key autoincrement, name varchar(20),phone varchar(20))”);
5. }
3.2onUpgrade方法(必须实现的方法)
当调用getReadableDatabase或getWriteableDatabase方法时 如果数据库版本号变大 则会调用这个方法
作用: 在这个方法中做数据库或表结构修改的操作 比如给表添加字段 或给数据库增加新的表
1.@Override
2. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
3. //通过oldVersion 和newVersion 可以判断当前版本号和最新的版本号
4. //真实开发环境可能会针对不同的数据库版本做不同的操作
5. db.execSQL(“alter table info add age integer”);
6. }
3.3onDowngrade方法(可选)
当调用getReadableDatabase或getWriteableDatabase方法时 如果数据库版本号变小 则会调用这个方法
作用: 处理数据库版本降级的操作 如果不重写这个方法 则默认数据库降级会抛异常
1.@SuppressLint(“NewApi”) @Override
2. public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
3. //处理数据库降级的需求 注意 super.onDowngrade 一定要删掉 否则如果数据库降级依然会抛异常
4. //super.onDowngrade(db, oldVersion, newVersion);
5. //一般很少做数据库降级的操作 不一定要实现
6. }
注意 : onCreate onUpgrade 由系统调用 不需要手动调用
4 Android下数据库操作表的简单粗暴方法(通过sql语句)
4.1相关API
①插入删除修改相关操作 sqlitedatabase的 execSQL方法
②查询操作 sqlitedatabase的 rawQuery方法
③ 查询结果返回 Curor(游标 类似JDBC中的ResultSet)
curor相关方法 moveToNext() 移动到下一行
getCount() 返回查询到的结果一共有多少行
getColumnCount()返回一条结果中有多少列
getString(index), getInt(index) 根据列序号返回相应记录(序号从0开始)
4.2代码
1.public void insert(View v) {
2. SQLiteDatabase db = openHelper.getReadableDatabase();
3. db.execSQL(“insert into info(name,phone) values(‘赵四’,‘13888888888’)”);
4. db.execSQL(“insert into info(name,phone) values(‘王五’,‘13888888888’)”);
5. db.close();
6. }
7. public void update(View v) {
8. SQLiteDatabase db = openHelper.getReadableDatabase();
9. db.execSQL("update info set phone = ‘12345678’ where name=‘赵四’ ");
10. db.close();
11. }
12. public void delete(View v) {
13. SQLiteDatabase db = openHelper.getReadableDatabase();
14. db.execSQL(“delete from info where name = ‘赵四’”);
15. db.close();
16. }
17. public void query(View v) {
18. SQLiteDatabase db = openHelper.getReadableDatabase();
19. Cursor cursor = db.rawQuery(“select * from info where name = ? ; “, new String[]{“王五”});
20. while(cursor.moveToNext()){
21. for (int i = 0; i < cursor.getColumnCount(); i++) {
22. String result = cursor.getString(i);
23.
24. Log.d(“MainActivity”, result+””);
25. }
26. }
27. db.close();
28. }
5 Android下数据库操作表的优雅方法(通过谷歌提供的api)
5.1相关api
①insert方法
②delete方法
③update方法
④query方法
5.2代码
1.public void insert1(View v) {
2. SQLiteDatabase sqLiteDatabase = openHelper.getReadableDatabase();
3. //–insert into info(name,phone) values(‘赵四’,‘13777777’);
4. //–insert into info() values();
5. //sqLiteDatabase.execSQL(“insert into info(name,phone) values(?,?)”, new Object[]{“赵四”,“1388888888”});
6. //第一个参数 表名字
7. String table = “info”;
8. //第二个参数 避免产生插入空列的sql 如果第三个参数为空 sql会变成insert into info() values();
9. //如果传了nullColumnHack 并且第三个参数没有传 是空的情况 sql 会拼接成如下情况: insert into info(name) values(NULL)
10. String nullColumnHack = null;
11. //第三个参数 通过map的形式 保存要插入的列名 和对应的值
12. ContentValues values = new ContentValues();
13. values.put(“name”, “赵四”);
14. values.put(“phone”, “188888888888”);
15.
16. //最终是通过字符串拼接的形式 帮助生成sql 避免写错
17. //result 返回值是插入行的行号 如果返回-1说明插入失败
18. long result = sqLiteDatabase.insert(table, nullColumnHack, values);
19. if(result>=0){
20. Toast.makeText(this, “插入到第”+result+“行”, Toast.LENGTH_SHORT).show();
21. }else{
22. Toast.makeText(this, “插入失败”, Toast.LENGTH_SHORT).show();
23. }
24. sqLiteDatabase.close();
25. }
26.
27. public void delete1(View v) {
28. SQLiteDatabase sqLiteDatabase = openHelper.getReadableDatabase();
29. //–delete from info where name=‘王五’;
30. //sqLiteDatabase.execSQL(“delete from info where name=?;”, new Object[]{“赵四”});
31. //第二个参数 where条件 where后面的内容 具体删除的值用?代替
32. String whereClause = “name = ? and phone = ?”;
33. //第三个参数 在where条件中 用?代替的具体的值
34. String[] whereArgs = new String[]{“赵四”,“13888888888”};
35. int num = sqLiteDatabase.delete(“info”, whereClause, whereArgs);
36. if(num>0){
37. Toast.makeText(this, “删除了”+num+“行”, Toast.LENGTH_SHORT).show();
38. }else{
39. Toast.makeText(this, “没删,失败”, Toast.LENGTH_SHORT).show();
40. }
41. sqLiteDatabase.close();
42.
43. }
44.
45. public void update1(View v) {
46. SQLiteDatabase sqLiteDatabase = openHelper.getReadableDatabase();
47. //–update info set phone='139999999’where name=‘王五’;;
48. //sqLiteDatabase.execSQL(“update info set phone=? where name=?”, new Object[]{“1399999999”,“赵四”});
49. ContentValues values = new ContentValues();
50. values.put(“phone”, “13999999999”);
51. String whereClause = “name = ?”;
52. String[] whereArgs = new String[]{“赵四”};
53. int num = sqLiteDatabase.update(“info”, values, whereClause, whereArgs);
54. if(num>0){
55. Toast.makeText(this, “更新了”+num+“行”, Toast.LENGTH_SHORT).show();
56. }else{
57. Toast.makeText(this, “没更新,失败”, Toast.LENGTH_SHORT).show();
58. }
59. sqLiteDatabase.close();
60.
61. }
62.
63. public void query1(View v) {
64. SQLiteDatabase sqLiteDatabase = openHelper.getReadableDatabase();
65. //–select name,phone from info;;
66. //Cursor cursor = sqLiteDatabase.rawQuery(“select * from info”, null);
67. String[] columns = null;//要查询的列名字 如果传null 相当于select * from info;
68. String selection = null; //查询的条件 其中又变化的部分要用? 替换
69. String[] selectionArgs = null; //查询条件中 ? 所对应的值
70. String groupBy = null;//分组
71. String having = null;//分组接的条件
72. String orderBy = null;//排序
73. Cursor cursor = sqLiteDatabase.query(“info”, columns, selection, selectionArgs, groupBy, having, orderBy);
74. if(cursor!=null && cursor.getCount()>0){
75. while(cursor.moveToNext()){
76. String name = cursor.getString(1);
77. String phone = cursor.getString(cursor.getColumnIndex(“phone”));
78. Log.e(“sqlite”, “name===”+name+“phone===”+phone);
79. }
80. }
81. cursor.close();
82. sqLiteDatabase.close();
83.
84. }
6 简单粗暴 VS 优雅方法 PK
大量数据效率 SQL语句灵活性 方法是否有返回值 SQL出错概率
通过sql执行CRUD 效率高
灵活性强任意发挥
除查询外无
有可能出错
通过api执行CRUD 需要拼语句效率低
受api限制
都有返回值
不会出错
7 Android中数据库事务介绍
7.1事务概念
在事务中包含的sql,要么同时执行成功 要么同时执行失败, 不能出现 部分成功部分失败的情况 典型案例 银行转账
7.2 相关api
-
db.beginTransaction();//开启事务
-
try {
-
...
-
db.setTransactionSuccessful();//如果所有SQL都执行完毕则标记成功
-
} finally {
-
db.endTransaction();//如果有成功标记则关闭事务,没有成功标记回滚数据
-
}
7.3 具体代码
MyOpenHelper类
1.public class MyOpenHelper extends SQLiteOpenHelper {
2. public MyOpenHelper(Context context) {
3. super(context, “Account.db”, null, 1);
4. }
5. @Override
6. public void onCreate(SQLiteDatabase db) {
7. db.execSQL(“create table info (_id integer primary key autoincrement,name varchar(20),phone varchar(20),money varchar(20))”);
8. db.execSQL(“insert into info (‘name’,‘phone’,‘money’) values (‘张三’,‘138888’,‘2000’)”);
9. db.execSQL(“insert into info (‘name’,‘phone’,‘money’) values (‘李四’,‘139999’,‘5000’)”);
10. }
11. @Override
12. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
13. }
14.}
MainActivity类
1.public class MainActivity extends Activity {
2. private MyOpenHelper openHelper;
3. @Override
4. protected void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.activity_main);
7. //获取MyOpenHelper 用它可以获取SQLiteDatabase
8. openHelper = new MyOpenHelper(this);
9. }
10. public void transaction(View v){
11. SQLiteDatabase database = openHelper.getWritableDatabase();
12. //开启事务
13. database.beginTransaction();
14. try {
15. database.execSQL(“update info set money= money-200 where name=?”,new String[]{“张三”});
16. //int i = 100/0;
17. database.execSQL(“update info set money= money+200 where name=?”,new String[]{“李四”});
18. //事务所有的sql执行成功之后 调用 setTransactionSuccessful 会加上一个标记说明事务成功执行了
19. database.setTransactionSuccessful();
20. } catch (Exception e) {
21. Toast.makeText(getApplicationContext(), “服务器忙,请稍后再试”, 0).show();
22. }finally {
23. //事务结束 会检查标记 如果没有成功标记则回滚 如果有成功标记则提交生效
24. database.endTransaction();
25. }
26. }
27.}
8 ListView入门
8.1ListView核心类
①ListView
setAdapter 设置一个适配器
②BaseAdapter
getcount
getItem
getId
getView
8.2代码编写步骤
① 布局中声明listview节点(注意listview的高度不要使用包裹内容)
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. android:paddingTop="@dimen/activity_vertical_margin"
6. tools:context=".MainActivity" >
7. <ListView
8. android:id="@+id/lv_list"
9. android:layout_width=“match_parent”
10. android:layout_height=“match_parent”
11. android:fastScrollEnabled=“true”
12. android:text="@string/hello_world" />
13.
② 条目布局创建出来
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. <ImageView
7. android:id="@+id/iv_icon"
8. android:layout_width=“wrap_content”
9. android:layout_height=“wrap_content”
10. android:src="@drawable/ic_launcher"
11. android:layout_margin=“5dp”/>
12. <TextView
13. android:id="@+id/tv_title"
14. android:layout_toRightOf="@id/iv_icon"
15. android:layout_height=“wrap_content”
16. android:layout_width=“wrap_content”
17. android:layout_margin=“7dp”
18. android:text=“北京今年装修要多少钱”
19. android:textSize=“18sp”
20. />
21. <TextView
22. android:id="@+id/tv_content"
23. android:layout_toRightOf="@id/iv_icon"
24. android:layout_below="@id/tv_title"
25. android:layout_height=“wrap_content”
26. android:layout_width=“wrap_content”
27. android:text=“获得报价”
28. android:textColor="#999999"
29. android:layout_marginLeft=“8dp”
30. android:textSize=“16sp”
31. />
32.
③ 在Activity的oncreate方法中findviewbyid 找到 listView 控件
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main3);
-
//找到listview控件
-
lv_list = (ListView) findViewById(R.id.lv_list); ④ 写一个类 继承BaseAdapter 重写里面四个方法
-
class MyAdapter extends BaseAdapter{
-
//数据集合中有多少个条目 通过这个方法判断listview会显示出多少个条目 这里传6 最终就会显示出6个条目
-
@Override
-
public int getCount() {
-
// TODO Auto-generated method stub
-
return 6;
-
}
-
//根据listview 当前的position 从数据集合中取出对应的数据
-
@Override
-
public Object getItem(int position) {
-
// TODO Auto-generated method stub
-
return null;
-
}
-
//Get the row id associated with the specified position in the list.
-
@Override
-
public long getItemId(int position) {
-
// TODO Auto-generated method stub
-
return position;
-
}
-
//通过这个方法 返回条目的布局视图
-
@Override
-
public View getView(int position, View convertView, ViewGroup parent) {
-
count++;
-
TextView tv_text = null;
-
if(convertView == null){
-
System.out.println("convertView == null创建了一个新的对象");
-
tv_text = new TextView(MainActivity.this);
-
}else{
-
tv_text = (TextView) convertView;
-
System.out.println("convertView不为空 复用旧的view");
-
}
-
//TextView tv_text = new TextView(MainActivity.this);
-
tv_text.setText("我是第"+position+"个条目");
-
return tv_text;
-
}
-
}
⑤创建adapter对象 调用setAdpater 给listview设置一个适配器
-
//创建适配器对象
-
MyAdapter myAdapter = new MyAdapter();
-
//给listview设置适配器
-
lv_list.setAdapter(myAdapter);
9 ListView优化
思路 重用convertView 判断convertView 是否为空 如果为空则需创建新的view对象 如果不为空则直接使用convertView
10 把复杂界面(通过xml文件实现)显示到ListView上
-
public View getView(int position, View convertView, ViewGroup parent) {
-
//把xml文件转化为 view对象的第一种方式 通过View的inflate方法
-
//第一个参数 上下文
-
//第二个参数 要转化成view对象 对应的布局id
-
//第三个参数 viewGroup 是一个特殊的View对象 它可以加入子view 比如 LinearLayout RelativeLayout都是ViewGroup
-
//如果这个参数传了值 那么创建出来的view 就是这个view的子view 我们在getview方法中 主要目的是把xml文件转化成view对象 显示在listview中
-
//不需要加入到其他viewgroup中 所以这个参数传null就可以了
-
View view = View.inflate(MainActivity.this, R.layout.item, null);
-
//LayoutInflater 也有 inflate方法
-
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
-
View view2 = inflater.inflate(R.layout.item, null);
-
//ArrayAdapter源码 采用的这种方式获取的打气筒 通过打气筒把xml布局文件转化为view对象
-
LayoutInflater inflater2 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
-
View view3 = inflater2.inflate(R.layout.item, null);
-
return view3;
-
}
11把一个xml文件转化为View对象的几种写法
① View的静态方法 View.inflate (这种方式比较方便)
② 获取LayoutInflater对象 通过LayoutInflater的inflate方法实现
获取LayoutInflater对象方式一 LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
获取LayoutInflater对象方式二 LayoutInflater inflater2 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
(谷歌源码中采用的这种方式)
12 SimpleAdapter & ArrayAdapter的使用
12.1 ArrayAdapter
1.public class MainActivity2 extends Activity {
2.private String datas[] = new String[]{“张小军”,“张欣”,“张丹丹”};
3. @Override
4. protected void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.activity_main);
7. ListView lv_list = (ListView) findViewById(R.id.lv_list);
8. //第二个参数 用来显示数据的布局文件ID
9. //第三个参数 布局文件中用来展示数据的具体的textview的id
10. //第三个参数 String数组 用来显示的数据源
11. ArrayAdapter adapter = new ArrayAdapter(this, R.layout.item,R.id.tv_test, datas);
12. lv_list.setAdapter(adapter);
13. }
14.}
条目布局文件
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. <TextView
8. android:id="@+id/tv_test"
9. android:layout_width=“match_parent”
10. android:layout_height=“match_parent”
11. android:text="@string/hello_world" />
12.
13.
12.2 SimpleAdapter
1.public class MainActivity extends Activity {
2. @Override
3. protected void onCreate(Bundle savedInstanceState) {
4. super.onCreate(savedInstanceState);
5. setContentView(R.layout.activity_main);
6. ListView lv_list = (ListView) findViewById(R.id.lv_list);
7. //List
条目的布局文件
1.<?xml version="1.0" encoding="utf-8"?>
2.<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
3. xmlns:tools=“http://schemas.android.com/tools”
4. android:layout_width=“match_parent”
5. android:layout_height=“match_parent”
6. tools:context=".MainActivity" >
7.
8. <ImageView
9. android:id="@+id/iv_icon"
10. android:layout_width=“wrap_content”
11. android:layout_height=“wrap_content”
12. android:src="@drawable/ic_launcher"
13. android:layout_margin=“5dp”/>
14. <TextView
15. android:id="@+id/tv_title"
16. android:layout_toRightOf="@id/iv_icon"
17. android:layout_height=“wrap_content”
18. android:layout_width=“wrap_content”
19. android:layout_margin=“7dp”
20. android:text=“北京今年装修要多少钱”
21. android:textSize=“18sp”
22. />
23.
24. <TextView
25. android:id="@+id/tv_content"
26. android:layout_toRightOf="@id/iv_icon"
27. android:layout_below="@id/tv_title"
28. android:layout_height=“wrap_content”
29. android:layout_width=“wrap_content”
30. android:text=“获得报价”
31. android:textColor="#999999"
32. android:layout_marginLeft=“8dp”
33. android:textSize=“16sp”
34. />
35.
36.
13 ListView显示数据原理(MVC)
14 listview展示数据库数据
14.1ListView相关代码书写流程
① 在布局文件中 声明一个listview节点
② 在activity中 通过findViewByid 找到listview控件
③ 写一个类继承BaseAdapter 实现四个方法
④ getView方法
4.1把xml文件转化成View对象(三种方式)
通过View.inflate 或者拿到LayoutInflator对象 调用inflate方法
需要判断convertView是否为空 为空 创建对象 不为空复用convertView
4.2 找到要操作的控件 注意 要调用 打气筒打出来的这个对象 通过这个对象去findviewbyid (view.findviewbyid)
4.3 在数据集合中取出要显示的数据 persons.get(position);
4.4 把数据显示到找到的控件上
⑤ 创建BaseAdapter对象 调用listview 的setAdapter方法 将适配器和listview关联起来
(需要注意 如果对应的数据集合没有数据 则不会看到界面)
14.2 具体代码
SQLiteOpenHelper
public class MyOpenHelper extends SQLiteOpenHelper {
public MyOpenHelper(Context context) {
super(context, "itheima.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table info(_id integer primary key,name varchar(20),phone varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Person
public class Person {
public String phone;
public String name;
@Override
public String toString() {
return “Person [phone=” + phone + “, name=” + name + “]”;
}
}
MainActivity
public class MainActivity extends Activity {
private SQLiteDatabase database;
private ArrayList<Person> persons = new ArrayList<Person>();
private MyAdapter adapter;
private ListView lv_list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到关心的控件
Button btn_insert = (Button) findViewById(R.id.btn_insert);
Button btn_query = (Button) findViewById(R.id.btn_query);
lv_list = (ListView) findViewById(R.id.lv_list);
//给按钮添加点击事件
MyOnclickListener listner = new MyOnclickListener();
btn_insert.setOnClickListener(listner);
btn_query.setOnClickListener(listner);
//创建数据库助手对象
MyOpenHelper openHelper = new MyOpenHelper(this);
//获取数据库对象
database = openHelper.getReadableDatabase();
adapter = new MyAdapter();
}
private class MyOnclickListener implements OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_insert:
ContentValues values = new ContentValues();
values.put("name", "罗陈建");
values.put("phone", "18888888888");
database.insert("info", null, values);
ContentValues values2 = new ContentValues();
values2.put("name", "王含含");
values2.put("phone", "13999999999");
database.insert("info", null, values2);
ContentValues values3 = new ContentValues();
values3.put("name", "任永伟");
values3.put("phone", "13777777777");
database.insert("info", null, values3);
break;
case R.id.btn_query:
//通过谷歌api查询
Cursor curor = database.query("info", null, null, null, null, null, null);
//遍历查询到的结果
while(curor.moveToNext()){
//创建person对象
Person person = new Person();
//根据列名 name 获取数据库中对应的值
String name = curor.getString(curor.getColumnIndex("name"));
//根据列名 phone 获取数据库中对应的值
String phone = curor.getString(curor.getColumnIndex("phone"));
//设置相应数据
person.name = name;
person.phone = phone;
//把数据添加到集合
persons.add(person);
}
// for(Person person :persons){
// System.out.println(person);
// }
//通知listview显示数据
//或者把数据适配器和listview绑定起来
lv_list.setAdapter(adapter);
//关闭游标
curor.close();
break;
}
}
}
private class MyAdapter extends BaseAdapter{
//返回要展示的数据集合的条目数
@Override
public int getCount() {
// TODO Auto-generated method stub
return persons.size();
}
//通过adapter传进来的posion(listview中条目的position)
//把它对应的数据集合中的对象返回来
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return persons.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//①把布局文件转换为View对象 需要判断convertView是否为空
View view= null;
if(convertView == null){
//创建view对象
view = View.inflate(MainActivity.this, R.layout.item, null);
}else{
//复用旧的convertView
view = convertView;
}
//②找到要修改的控件的对象 注意要调用view.findViewById
TextView tv_name = (TextView)view.findViewById(R.id.tv_name);
TextView tv_phone = (TextView)view.findViewById(R.id.tv_phone);
//③ 设置数据
//3.1通过position 到数据集合中把要显示的数据找到
Person person = persons.get(position);
//3.2把要显示的内容展示到对应的View对象上
tv_name.setText(person.name);
tv_phone.setText(person.phone);
return view;
}
}
//页面销毁时会调用这个方法 一般在这个方法中做关闭释放资源的操作
@Override
protected void onDestroy() {
super.onDestroy();
//关闭数据库
database.close();
}
}
整个应用的布局
<Button
android:id="@+id/btn_insert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="插入数据" />
<Button
android:id="@+id/btn_query"
android:layout_toRightOf="@id/btn_insert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询数据" />
<ListView
android:id="@+id/lv_list"
android:layout_below="@id/btn_insert"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
条目的布局
<?xml version="1.0" encoding="utf-8"?><ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iv_icon"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:text="姓名:王含含" />
<TextView
android:id="@+id/tv_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_name"
android:layout_toRightOf="@id/iv_icon"
android:layout_marginTop="5dp"
android:textColor="#88000000"
android:text="电话:13888888888" />
xml 布局小技巧
画线
颜色
android下 在xml中表示颜色 ARGB 8888 Alpha 透明度 R red 红色 G green 绿色 B blue 蓝色
8888 就是每种颜色用一个8位的二进制数来表示 也可以用 2位的16进制来表示
在xml中就是用的16进制来表示颜色 每两位 代表一种颜色
可以用RGB形式 #000000
也可以用ARGB #88000000 前两位表示透明度
gravity 父容器针对子空间或者内容设置位置的 如果设置了right 里面的内容都会跑到最右边
layout_gravity 当前的控件针对父容器的位置 如果传了 center_horizontal 就会跑到父容器的水平居中的位置
布局常用的属性
① marging(外边距) padding(内边距) (right left bottom top)
相对布局 layout_toleftof layout_toRightof layout_ablow layout_below 控件的id 在某个空间的上下左右
layout_alignParent(right left bottom top) 针对相对布局的 在父容器的上下左右