- 数据库介绍(sqlite):有大量相似结构的数据需要储存的时候
- 数据库的创建:定义一个类继承sqliteOpenHelper
package com.example.a3_sql1;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyOpenHelper extends SQLiteOpenHelper {
/**
*
* @param context 上下问
* factory 目的创建cursor对象
*
* version 数据库版本从一开始
*/
public MyOpenHelper(Context context) {
super(context,"ithema.db",null,1);
}
/**
* @param sqLiteDatabase
* 当数据库第一次创建的时候调用
* 特别适合做表结构的初始化 创建表就是写sql语句
*/
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//id一般以_id
//手机里的数据库底层不区分类型,都是string
sqLiteDatabase.execSQL("create table info(" +
"_id integer primary key autoincrement," +
"name varchar(20)," +
"phone varchar(20))");
}
/**
* 当数据库升级的时候调用
* @param sqLiteDatabase
* @param i
* @param i1
*/
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
-
数据的oncreate 方法和 onupgrade 方法
-
使用数据库可视化工具查看数据库
-
使用sql语句对数据库进行增删查改
a) 缺点:sql语句容易写错;执行sql 语句没有返回值,不容易进行判断
b) 优点:多表查询
c) 使用命令行工具sqlite3可以打开数据库
d) 该表dos 编码方式chcp 936 变成jbk、chcp 65001 变成utf8
public class MainActivity extends AppCompatActivity {
private MyOpenHelper myOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myOpenHelper = new MyOpenHelper(getApplicationContext());
//打开或者创建数据库 如果是第一次就是创建
SQLiteDatabase sqLiteDataBase = myOpenHelper.getWritableDatabase();
//打开或者创建数据库 如果是第一次就是创建 如果磁盘满了返回只读
// SQLiteDatabase readableDatabase = myOpenHelper.getReadableDatabase();
}
//点击按钮增加一条记录
public void onclick5(View v) {
//<1>获取数据库对象
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//<2>执行增加一条数据的sql语句
/**
* table 表名
* nullColumnHack 占位 如果contentValues为空的话,执行 Insert into info(null) values(NULL);
* contentValues 内部封装了map key:列名;value 对应值
*/
ContentValues va = new ContentValues();
va.put("name", "王五");
va.put("phone", "110");
//返回值代表新行的id
long insert = db.insert("info", null, va);
//<3>数据库用完关闭
db.close();
if (insert > 0) {
Toast.makeText(getApplicationContext(), "添加成功", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "添加失败", Toast.LENGTH_LONG).show();
}
}
//删除
public void onclick6(View v) {
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
/**
* table 表明
* whereClause 删除的条件
* whereArgs 内容
*/
int delete = db.delete("info", "name=?", new String[]{"王五"});
db.close();
Toast.makeText(getApplicationContext(), "删除了" + delete + "行", Toast.LENGTH_LONG).show();
}
//更新
public void onclick7(View v) {
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
ContentValues va = new ContentValues();
va.put("phone", "114");
//代表更新了多少行
int update = db.update("info", va, "name=?", new String[]{"王五"});
db.close();
Toast.makeText(getApplicationContext(), "更新了" + update + "行", Toast.LENGTH_LONG).show();
}
//查找
public void onclick8(View v) {
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
/**
* columns 代表查询的列 null是查询所有
* selection 查询的条件
*/
Cursor cursor = db.query("info", null, "name=?", new String[]{"王五"}, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
//columnIndex 代表列的索引,从0开始
String name = cursor.getString(1);
String phone = cursor.getString(2);
System.out.println("name" +
name +
"phone" +
phone);
}
}
}
}
- Andriod 中数据库事务介绍
a) 事务,执行一段逻辑,要么同时成功要么同时失败
public class MainActivity extends AppCompatActivity {
private MyOpenHelper myOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myOpenHelper = new MyOpenHelper(getApplicationContext());
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
}
public void click(View view) {
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
//使用事物进行转账
db.beginTransaction();
try {
//实现转账的逻辑 写sql语句
db.execSQL("update info set money = money - 100 where name = '王五'");
db.execSQL("update info set money = money - 100 where name = '张三'");
//给当前事物设置一个成功的标记,如果程序在这之前挂掉的话回滚
db.setTransactionSuccessful();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),"服务器正忙,请稍后再试。",Toast.LENGTH_SHORT).show();
} finally {
db.endTransaction();
}
}
}
- Listview入门
a) 定义listview在布局中
<ListView
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="@+id/lv"
android:fastScrollEnabled="true"></ListView>
b) 定义listview 数据适配器
c) 实现BaseAdapter 的getCount方法和 getView方法
//<3>定义listview的数据适配器
private class MyListAdapter extends BaseAdapter{
//一共有多少条数据需要展示
@Override
public int getCount() {
return 100000000;
}
//返回指定 i位置的对象
@Override
public Object getItem(int i) {
return null;
}
//返回 i位置对应的id
@Override
public long getItemId(int i) {
return 0;
}
/**
* 获取一个view 用来显示listview的数据 会作为listview的一个条目出现
* @param i 位置
* @param view
* @param viewGroup
* @return
*/
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
TextView tv = null;
if (view == null) {
tv = new TextView(getApplicationContext());
System.out.println("创建新的view对象---" + i);
}else{
System.out.println("复用历史view对象---" + i);
tv = (TextView)view;
}
tv.setText("哈哈"+i);
return tv;
}
}
- Listview 优化
a) 高度使用match_parent,否则会出现多次执行getView 的情况影响效率
b) 出现异常out of the memory
public View getView(int i, View view, ViewGroup viewGroup) {
TextView tv = null;
//优化,if else语句
if (view == null) {
tv = new TextView(getApplicationContext());
System.out.println("创建新的view对象---" + i);
}else{
System.out.println("复用历史view对象---" + i);
tv = (TextView)view;
}
tv.setText("哈哈"+i);
return tv;
}
- Listview 显示数据的原理
a) mvc:mode 数据;view listview; adapter 适配器
b) 不管什么adapter作用都是把数据展示到listview上的 - Listview 显示复杂的页面
a) 线性布局、相对布局都继承自ViewGroup,可以有自己的孩子
item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/iv_icon"></ImageView>
<TextView android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/tv_title"
android:text="谢霆锋王菲旧情复燃的开发建设的开发建设的咖啡机"
android:layout_toRightOf="@id/iv_icon"
android:singleLine="true"
android:ellipsize="end"
android:textColor="#000000"
android:layout_marginTop="2dp"
android:textSize="20sp"></TextView>
<TextView android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/tv_content"
android:text="谢霆锋王菲旧情复燃的开发建设的开发建设的咖啡机"
android:layout_toRightOf="@id/iv_icon"
android:layout_below="@id/tv_title"
android:singleLine="true"
android:ellipsize="end"
android:textColor="#999999"
android:textSize="15sp"></TextView>
</RelativeLayout>
b) 通过一个打气筒inflate,可以把一个布局转换成view对象
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//<1>找到控件
ListView lv = findViewById(R.id.lv);
lv.setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return 6;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View view1;
//<1>把自定义的布局换成view对象
if (view == null) {
//方法一、通过打气筒把xml文件转换成view对象
view1 = View.inflate(getApplicationContext(), R.layout.item, null);
// 方法二
View view2 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
// 方法三、也是谷歌工程师使用的方法
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view3 = inflater.inflate(R.layout.item, null);
} else {
view1 = view;
}
return view1;
}
}
}
- 获取打气筒的常用api
a) view1 = View.inflate(getApplicationContext(), R.layout.item, null);
b) View view2 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
c) LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view3 = inflater.inflate(R.layout.item, null); - 权重
- ArrayAdapter
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/textView"/>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
String objects[] = {"老张", "老方", "老李", "老毕", "老金", "老刘"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//<1>找到控件
ListView lv = findViewById(R.id.lv);
//<2>创建一个arrayAdapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.item,R.id.textView, objects);
//<3>设置数据适配器
lv.setAdapter(adapter);
}
}
- simpleAdapter
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="0dp" android:layout_height="wrap_content"
android:id="@+id/tv_name"
android:layout_weight="1"
android:textSize="20sp"
android:text="ergerfreg1"/>
<TextView android:layout_width="0dp" android:layout_height="wrap_content"
android:id="@+id/tv_phone"
android:layout_weight="1"
android:textSize="20sp"
android:text="1fregregge"/>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//<1>找到控件
ListView lv = findViewById(R.id.lv);
//<1.1>准备listview要显示的数据
ArrayList<Map<String, String>> data = new ArrayList<>();
Map<String, String> map1 = new HashMap<>();
map1.put("name", "炸飞");
map1.put("phone", "13888888");
Map<String, String> map2 = new HashMap<>();
map2.put("name", "赵云");
map2.put("phone", "110");
Map<String, String> map3 = new HashMap<>();
map3.put("name", "貂蝉");
map3.put("phone", "139999");
Map<String, String> map4 = new HashMap<>();
map4.put("name", "关羽");
map4.put("phone", "1546549");
//<1.2>把map加集合中
data.add(map1);
data.add(map2);
data.add(map3);
data.add(map4);
//<2>设置数据适配器
//from map集合的键
SimpleAdapter simpleAdapter = new SimpleAdapter(getApplicationContext(), data, R.layout.item, new String[]{"name","phone"}, new int[]{R.id.tv_name, R.id.tv_phone});
//<3>设置数据适配器
lv.setAdapter(simpleAdapter);
}
}