day04_2

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
  1. db.beginTransaction();//开启事务

  2. try {

  3. ...
    
  4. db.setTransactionSuccessful();//如果所有SQL都执行完毕则标记成功
    
  5. } finally {

  6. db.endTransaction();//如果有成功标记则关闭事务,没有成功标记回滚数据
    
  7. }

    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 控件
  1. protected void onCreate(Bundle savedInstanceState) {

  2.    super.onCreate(savedInstanceState);
    
  3.    setContentView(R.layout.activity_main3);
    
  4.    //找到listview控件
    
  5.    lv_list = (ListView) findViewById(R.id.lv_list);
    
    
             ④ 写一个类 继承BaseAdapter 重写里面四个方法
    
  6. class MyAdapter extends BaseAdapter{

  7.  //数据集合中有多少个条目 通过这个方法判断listview会显示出多少个条目 这里传6 最终就会显示出6个条目
    
  8.  @Override
    
  9.  public int getCount() {
    
  10.  	// TODO Auto-generated method stub
    
  11.  	return 6;
    
  12.  }
    
  13.  //根据listview 当前的position 从数据集合中取出对应的数据
    
  14.  @Override
    
  15. public Object getItem(int position) {
    
  16. 	// TODO Auto-generated method stub
    
  17. 	return null;
    
  18. }
    
  19. //Get the row id associated with the specified position in the list.
    
  20. @Override
    
  21. public long getItemId(int position) {
    
  22. 	// TODO Auto-generated method stub
    
  23. 	return position;
    
  24. }
    
  25. //通过这个方法 返回条目的布局视图
    
  26. @Override
    
  27. public View getView(int position, View convertView, ViewGroup parent) {
    
  28. 	count++;
    
  29. 	TextView tv_text  = null;
    
  30. 	if(convertView == null){
    
  31. 		System.out.println("convertView == null创建了一个新的对象");
    
  32. 		tv_text = new TextView(MainActivity.this);
    
  33. 	}else{
    
  34. 		tv_text = (TextView) convertView;
    
  35. 		System.out.println("convertView不为空 复用旧的view");
    
  36. 	}
    
  37. 	//TextView tv_text = new TextView(MainActivity.this);
    
  38. 	tv_text.setText("我是第"+position+"个条目");
    
  39. 	return tv_text;
    
  40. }
    
  41. }

            ⑤创建adapter对象 调用setAdpater 给listview设置一个适配器
    
  42. //创建适配器对象

  43.    MyAdapter myAdapter = new MyAdapter();
    
  44.    //给listview设置适配器
    
  45.    lv_list.setAdapter(myAdapter);
    

9 ListView优化

思路 重用convertView 判断convertView 是否为空 如果为空则需创建新的view对象 如果不为空则直接使用convertView

10 把复杂界面(通过xml文件实现)显示到ListView上

  1.  public View getView(int position, View convertView, ViewGroup parent) {
    
  2.  	//把xml文件转化为 view对象的第一种方式 通过View的inflate方法
    
  3.  	//第一个参数 上下文
    
  4.  	//第二个参数 要转化成view对象 对应的布局id
    
  5.  	//第三个参数 viewGroup 是一个特殊的View对象 它可以加入子view 比如 LinearLayout  RelativeLayout都是ViewGroup
    
  6.  	//如果这个参数传了值 那么创建出来的view 就是这个view的子view 我们在getview方法中 主要目的是把xml文件转化成view对象 显示在listview中
    
  7.  	//不需要加入到其他viewgroup中 所以这个参数传null就可以了
    
  8.  	View view = View.inflate(MainActivity.this, R.layout.item, null);
    
  9.  	//LayoutInflater 也有 inflate方法 
    
  10. 	LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
    
  11. 	View view2 = inflater.inflate(R.layout.item, null);
    
  12. 	//ArrayAdapter源码 采用的这种方式获取的打气筒 通过打气筒把xml布局文件转化为view对象
    
  13. 	LayoutInflater inflater2 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    
  14. 	View view3 = inflater2.inflate(R.layout.item, null);
    
  15. 	return view3;
    
  16. }
    

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 用来填充数据的
8. List<Map<String, String>> data = new ArrayList<Map<String,String>>();
9. Map<String, String> map1 = new HashMap<String, String>();
10. map1.put(“title”, “中国足球又输了”);
11. map1.put(“content”, “2016冲击失败”);
12. data.add(map1);
13. Map<String, String> map2 = new HashMap<String, String>();
14. map2.put(“title”, “沪android12期高薪就业”);
15. map2.put(“content”, “平均薪水20K”);
16. data.add(map2);
17. String[] from ={“title”,“content”};
18. int[] to = {R.id.tv_title,R.id.tv_content};
19. //第二个参数 数据map的List
20. //第三个参数 用来显示数据的布局文件
21. //第四个参数 String数组 数据List中 每一条数据的 key
22. //第五个参数 数据List中 的文字内容 对应的 要显示此内容的 textView的id
23. SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item2, from, to);
24. lv_list.setAdapter(adapter);
25. }
26.}

条目的布局文件

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) 针对相对布局的 在父容器的上下左右

发布了23 篇原创文章 · 获赞 0 · 访问量 232

猜你喜欢

转载自blog.csdn.net/qq_41518179/article/details/102886342