安卓数据存储方式
数据存储:File(本地),网络,ContentProvider(内容提供者),SharePreferences,数据库。
下面讲的是SharePreferences,本地,和数据库
SharedPreferences的使用方法
内部存储器和外部存储器的使用
SQliteDataBase与SQLiteOpenHelper的使用
序列化对象的存储以及读取
Shared Preferences:以键值对的方式存储私有的基本数据类型
Internal Storage 保存私有的数据到设备内存储
External Storage保存公共数据到共享外部存储如SD卡
SQLite Databases保存结构化数据到私有的数据库(ANDROID内置数据库)
sharePreferences
以xml方式存储在本地
//获取
SharedPreferences sp = getSharedPreferences(“isFirst”, MODE_PRIVATE);
存储操作模式有:
MODE_PRIVATE
MODE_APPEND
MODE_WORLD_READABLE
MODE_WORLD_WRITEABLE
//获取值
getXXX(“key”,defValue);
//存放值
putXXX(”key”,基础数据);
//编辑需要调用editor
Editor et = sp.editor();
et.commit();
//清空
et.clear();
//文件存放地址
//data/data/包名/shared_pres
下面一个示例
这个样式Module中需要添加
dependencies {
compile 'com.android.support:design:24.2.1'
}
MainActivity
public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
EditText et_username, et_password;
TextView tv_login;
CheckBox cb_remebr, cb_auto;
SPHelper spHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spHelper = new SPHelper(this, "login");
et_username = (EditText) findViewById(R.id.et_username);
et_password = (EditText) findViewById(R.id.et_password);
tv_login = (TextView) findViewById(R.id.tv_login);
cb_remebr = (CheckBox) findViewById(R.id.cb_remem);
cb_auto = (CheckBox) findViewById(R.id.cb_auto);
cb_auto.setOnCheckedChangeListener(this);
cb_remebr.setOnCheckedChangeListener(this);
tv_login.setOnClickListener(this);
//用户打开界面,我需要读取所有的信息
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);\
// spHelper.getBoolean("isRemebr");
boolean b = sp.getBoolean("isRemebr", false);
if (b) {
cb_remebr.setChecked(true);
String username = sp.getString("username", "");
String password = sp.getString("password ", "");
et_username.setText(username);
et_password.setText(password);
cb_auto.setChecked(sp.getBoolean("isAuto", false));
}
// //xml文件
// SharedPreferences sp = getSharedPreferences("Setting", MODE_PRIVATE);
// //存储一些数据
// boolean b = sp.getBoolean("isFirst", true);
// Log.e("TAG", "------------------" + b);
// if (b) {
// //启动引导页
// //启动后 , 写入false
// //开始编辑
// Toast.makeText(this, "第一次登陆", Toast.LENGTH_SHORT).show();
// SharedPreferences.Editor et = sp.edit();
// et.putBoolean("isFirst", false);
// et.commit();
// } else {
// Toast.makeText(this, "不是第一次登陆", Toast.LENGTH_SHORT).show();
// }
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//勾选状态
if (buttonView == cb_remebr) {
if (!isChecked) {
cb_auto.setChecked(false);
}
} else {
if (isChecked) {
cb_remebr.setChecked(true);
}
}
}
String[] user = {"zhangsan", "lisi", "wangwu", "tianqi", "zhaoliu"};
@Override
public void onClick(View v) {
String password = et_password.getText().toString();
String username = et_username.getText().toString();
for (String s : user) {
if (username.equals(s) && password.equals("123456")) {
if (cb_remebr.isChecked()) {
//保存用户的资料
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);
SharedPreferences.Editor et = sp.edit();
et.putBoolean("isRemebr", true);
et.putString("username", username);
et.putString("password", password);
et.putBoolean("isAuto", cb_auto.isChecked());
et.commit();
// spHelper.putValue(new SPHelper.ContentValue("",""),new SPHelper.ContentValue(),new SPHelper.ContentValue());
} else {
//清空账户
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);
sp.edit().clear().commit();
}
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
return;
}
}
Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
}
}
自己封装的SharedPreferences
public class SPHelper {
SharedPreferences sp;
public SPHelper(Context context, String name) {
sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
}
//存
public void putValue(ContentValue... contentValues) {
SharedPreferences.Editor et = sp.edit();
for (ContentValue contentValue : contentValues) {
//判断类型
if (contentValue.value instanceof String) {
et.putString(contentValue.key, contentValue.value.toString());
} else if (contentValue.value instanceof Integer) {
et.putInt(contentValue.key, Integer.parseInt(contentValue.value.toString()));
} else if (contentValue.value instanceof Long) {
et.putLong(contentValue.key, Long.parseLong(contentValue.value.toString()));
} else if (contentValue.value instanceof Boolean) {
et.putBoolean(contentValue.key, Boolean.parseBoolean(contentValue.value.toString()));
}
}
et.commit();
}
public String getString(String key) {
return sp.getString(key, null);
}
public boolean getBoolean(String key) {
return sp.getBoolean(key, false);
}
public int getInt(String key) {
return sp.getInt(key, -1);
}
public long getLong(String key) {
return sp.getLong(key, -1);
}
public void clear() {
sp.edit().clear().commit();
}
public static class ContentValue {
String key;
Object value;
public ContentValue(String key, Object value) {
this.key = key;
this.value = value;
}
public ContentValue() {
}
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="50dp"
tools:context="com.example.sharedpreferences_11_1.MainActivity">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入账户名:">
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码:">
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_remember"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="记住密码" />
<CheckBox
android:id="@+id/cb_auto"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="自动登录" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#336699"
android:gravity="center"
android:padding="10dp"
android:text="登录"
android:id="@+id/tv_login"
android:textColor="@android:color/white" />
</LinearLayout>
内部存储器 外部存储器
内部存储器
Context.openFileInput(String name);//打开文件流
Context.openFileOutput(String name,int mode //private,append);
内部存储器一般在 没有外部存储器时使用
//检测有没有存储器
String state = Environment.getExternalStorageState();
MEDIA_MOUNTED:媒体就绪
外部存储器
根目录 Environment.getExternalStorageDirectory()//少一个”/”
遍历必须在子线程,防止阻塞UI线程。
下面一个示例
MainActivity
public class MainActivity extends AppCompatActivity {
EditText et_content;
/**
* 在没有外部存储器的情况下 使用他
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_content = (EditText) findViewById(R.id.et_contnet);
}
public void save(View v) {
try {
FileOutputStream fos = openFileOutput("file", MODE_APPEND);
fos.write(et_content.getText().toString().getBytes());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void read(View v) {
FileInputStream fis = null;
try {
fis = openFileInput("file");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] buf = new byte[1024];
int len;
try {
while ((len = fis.read(buf)) != -1) {
et_content.append(new String(buf, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void check(View v) {
//获取存储器状态
String state = Environment.getExternalStorageState();
//sd卡就绪状态
if (state.equals(Environment.MEDIA_MOUNTED)) {
//外部存储器
Toast.makeText(this, "可以使用外部存储器", Toast.LENGTH_SHORT).show();
} else {
//只能使用内部存储器
Toast.makeText(this, "只能使用内部存储器", Toast.LENGTH_SHORT).show();
}
}
}
SDCardActivity
public class SDCardActivity extends AppCompatActivity {
ArrayList<File> fileList = new ArrayList();
//权限
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
setContentView(btn);
btn.setText("读SD");
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
getAllFiles(Environment.getExternalStorageDirectory(), fileList);
System.out.println(fileList.toString());
}
}.start();
}
});
try {
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/aaa.txt");
fos.write("你好,外部存储器".getBytes());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getAllFiles(File dir, List<File> fileList) {
File[] files = dir.listFiles();
if (files == null)
return;
for (File file : files) {
if (file.isDirectory())
getAllFiles(file, fileList);
fileList.add(file);
}
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.lesson13_sdcared.MainActivity">
<EditText
android:id="@+id/et_contnet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="save"
android:text="save" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="read"
android:text="read" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="check"
android:text="检测存储器" />
</LinearLayout>
注以上是两个存储方式 一个内部,一个外部
数据 SQL语句
5个语句
1. 建表
CREATE TABLE TABLE_NAME(字段 类型 限制符号…) primary key autoincrement not null
2. 插入
INSERT INTO TABLE_NAME (字段…) values (值…)
3. 删除
DELETE FROM TABLE_NAME WHERE 删除条件
4. 修改
UPDATE TABLE_NAME SET 字段=值,,, WHERE 修改条件
5. 查询
SELECT 字段* FROM TABLE_NAME WHERE 查询条件
SQliteDataBase
创建 SqliteOpenHelper的子类 重写3个方法
构造方法 : 建立数据库
context
name 数据库名称
CursorFactory 游标工厂 null
varsion 版本号 1
onCreate 建立表,可以有多个
在调用getWritableDatabase,getReadableDatabase的时候才会去判断,是否建立了数据
库,如果没有建立,则建立数据库并且调用onCreate,如果已经有了,不会再调用onCreate,
升级数据库
onUpgrade
用来更新数据库
drop table if exists TableNamegetWritableDatabase
getReadableDatabase
只有在磁盘满的时候,writable会报错,readable不会再执行
增删改查
1. insert(TableName,ContentValues); ContentValues 键为String的HashMap
1. delete(TableName , “条件=?” , new String[]{?对应的值…};
2. update(TableName,ContentValues,”条件=?”,new String[]{?对应值…});
3. query(TableName,null,null,null,null,null);
查询返回Cursor游标.默认指向结果表的头部
调用cursor.moveToNext判断下一个还有没有数据,有的话就取出来
while(cursor.moveToNext())
{ 调
用getXXX的方法来获取值(索引号)
调用getColunmIndex(“键名”)来获取索引号
user.info =
cursor.getString(cursor.getColumnIndex(MySqliteOpenHelper.USER_INFO));
} //
结合ContentProvider,会给应用程序内部和外部统一的访问方式
//数据库框架
下面一个示例
MainActivity
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
SQLiteDatabase db;
ListView lv;
List<User> list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this);
db = helper.getReadableDatabase();
lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
lv.setOnItemLongClickListener(this);
}
public void insert(View v) {
ContentValues values = new ContentValues();
values.put(MySQLiteOpenHelper.USER_USERNAME, "张三");
values.put(MySQLiteOpenHelper.USER_SEX, "男");
values.put(MySQLiteOpenHelper.USER_AGE, 20);
values.put(MySQLiteOpenHelper.USER_INFO, "网络工程师");
//中间的null的位置是插入的列 null代表所有
db.insert(MySQLiteOpenHelper.TABLE_NAME, null, values);
select();
}
public void select(View v) {
select();
}
private void select() {
//显示
list.clear();
Cursor cursor = db.query(MySQLiteOpenHelper.TABLE_NAME, null, null, null, null, null, null);
while (cursor.moveToNext()) {
User user = new User();
user.id = cursor.getInt(cursor.getColumnIndex(MySQLiteOpenHelper.ID));
user.username = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.USER_USERNAME));
user.sex = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.USER_SEX));
user.age = cursor.getInt(cursor.getColumnIndex(MySQLiteOpenHelper.USER_AGE));
user.info = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.USER_INFO));
list.add(user);
}
//查询完了 刷新适配器
adapter.notifyDataSetChanged();
}
@Override
protected void onDestroy() {
super.onDestroy();
db.close();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// //修改
// final User user = list.get(position);
// user.sex = "女";
// user.age = 25;
// user.info = "java工程师";
//
// //修改
// ContentValues values = new ContentValues();
// values.put(MySQLiteOpenHelper.USER_INFO, user.info);
// values.put(MySQLiteOpenHelper.USER_AGE, user.age);
// values.put(MySQLiteOpenHelper.USER_SEX, user.sex);
// db.update(MySQLiteOpenHelper.TABLE_NAME, values, MySQLiteOpenHelper.ID + "=?", new String[]{user.id + ""});
// adapter.notifyDataSetChanged();
View layout = getLayoutInflater().inflate(R.layout.update_layout,null);
final EditText et_id = (EditText) layout.findViewById(R.id.et_id);
final EditText et_username = (EditText) layout.findViewById(R.id.et_username);
final EditText et_sex = (EditText) layout.findViewById(R.id.et_sex);
final EditText et_age = (EditText) layout.findViewById(R.id.et_age);
final EditText et_info = (EditText) layout.findViewById(R.id.et_info);
Button finish = (Button) layout.findViewById(R.id.finsih);
final AlertDialog dialog = new AlertDialog.Builder(this).setTitle("修改用户信息").setView(layout).create();
finish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
User user1 =new User();
user1.id =Integer.parseInt(et_id.getText().toString()) ;
user1.username = et_username.getText().toString();
user1.sex = et_sex.getText().toString();
user1.age = Integer.parseInt(et_age.getText().toString());
user1.info = et_info.getText().toString();
//修改
ContentValues values = new ContentValues();
values.put(MySQLiteOpenHelper.USER_INFO, user1.info);
values.put(MySQLiteOpenHelper.USER_AGE, user1.age);
values.put(MySQLiteOpenHelper.USER_SEX, user1.sex);
values.put(MySQLiteOpenHelper.USER_USERNAME, user1.username);
db.update(MySQLiteOpenHelper.TABLE_NAME, values, MySQLiteOpenHelper.ID + "=?", new String[]{user1.id + ""});
adapter.notifyDataSetChanged();
select();
dialog.dismiss();
}
});
dialog.show();
select();
adapter.notifyDataSetChanged();
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
//删除
new AlertDialog.Builder(this).setTitle("警告").
setMessage("是否删除该数据").
setNegativeButton("取消", null).
setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
User user = list.get(position);
// db.delete(MySQLiteOpenHelper.TABLE_NAME, "id=?", new String[]{user.id + ""});
db.delete(MySQLiteOpenHelper.TABLE_NAME, MySQLiteOpenHelper.ID + "=?", new String[]{user.id + ""});
//刷新可以再调一次select()方法 或用下面的方法
list.remove(user);
adapter.notifyDataSetChanged();
}
}).show();
return true;
}
class User {
int id;
String username;
String sex;
int age;
String info;
}
BaseAdapter adapter = new BaseAdapter() {
@Override
public int getCount() {
return list.size();
}
@Override
public User getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(getBaseContext(), R.layout.item_layout, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
User user = list.get(position);
holder.id.setText(user.id + "");
holder.username.setText(user.username + "");
holder.sex.setText(user.sex + "");
holder.age.setText(user.age + "");
holder.info.setText(user.info + "");
return convertView;
}
class ViewHolder {
TextView id, username, sex, age, info;
public ViewHolder(View convertView) {
id = (TextView) convertView.findViewById(R.id.tv_id);
username = (TextView) convertView.findViewById(R.id.tv_name);
sex = (TextView) convertView.findViewById(R.id.tv_sex);
age = (TextView) convertView.findViewById(R.id.tv_age);
info = (TextView) convertView.findViewById(R.id.tv_info);
}
}
};
}
MySQLiteOpenHelper
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "Test.db";
public static final String TABLE_NAME = "userInfo";
public static final String ID = "_id";
public static final String USER_USERNAME = "username";
public static final String USER_SEX = "sex";
public static final String USER_AGE = "age";
public static final String USER_INFO = "info";
public static final String CREATE_TABLE = "create table " + TABLE_NAME + " (" + ID + " integer primary key autoincrement," + USER_USERNAME + " text not null," + USER_AGE + " integer," + USER_SEX + " varchar(1)," + USER_INFO + " text" + ")";
public static final String DELETE_TABLE = "drop table if exists " + TABLE_NAME;
//用户资料 id 用户名 性别 年龄 info
public MySQLiteOpenHelper(Context context) {
//上下文 数据库名称 游标工厂,版本号
super(context, DB_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
//没有数据库的时候 会回调该方法
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//升级 取数据 删除表 新建表 或是修改列
db.execSQL(DELETE_TABLE);
onCreate(db);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.sqlitedatabase.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="插入"
android:onClick="insert"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"
android:onClick="select"/>
<ListView
android:layout_width="match_parent"
android:id="@+id/lv"
android:layout_height="match_parent"/>
</LinearLayout>
item_layout.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:layout_weight="1"
android:layout_margin="5dp"
android:id="@+id/tv_id"
android:text="id"
android:gravity="center"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:id="@+id/tv_name"
android:text="username"
android:gravity="center"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:id="@+id/tv_sex"
android:text="sex"
android:gravity="center"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:id="@+id/tv_age"
android:text="age"
android:gravity="center"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:id="@+id/tv_info"
android:text="info"
android:gravity="center"
/>
</LinearLayout>
update_layout
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:padding="50dp"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"
android:text="需要修改的用户类容"
android:textColor="@android:color/holo_red_dark"/>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="id:"/>
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/et_id"
android:layout_weight="1"/>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:"/>
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/et_username"
android:layout_weight="1"/>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="性别:"/>
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/et_sex"
android:layout_weight="1"/>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="年龄:"/>
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/et_age"
android:layout_weight="1"/>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="信息:"/>
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/et_info"
android:layout_weight="1"/>
</TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/finsih"
android:text="确定"/>
</TableLayout>