上一节对视频模块进行了综述(可参见 10. 视频模块 进行了解),接下来将从“我”模块(一)开始详细介绍:
知识点
- 掌握SQLite数据库的使用,能够使用数据库存储用户信息。
- 掌握“我”界面开发,能够展示用户基本信息以及该界面的功能。
- 掌握“登录”“注册”界面的开发,实现用户登录注册功能。
- 掌握“个人资料”以及“修改”界面的开发,实现用户信息的展示与修改功能。
个人资料修改
任务综述:
“个人资料”修改界面主要用于修改用户昵称和签名,由于“修改昵称”界面和“修改签名”界面基本相同,因此可以使用同一个布局文件,根据“个人资料”界面传递过来的参数flag判断修改的是哪个属性。
14. 个人资料修改界面
任务分析:
个人资料修改界面主要用于修改用户的昵称和签名,界面效果如图所示。
任务实施:
(1)创建个人资料修改界面:ChangeUserInfoActivity&activity_change_user_info。
(2)导入界面图片(info_delete.png)。
(3)放置界面控件。
一个EditText控件用于输入文字。
一个ImageView控件用于显示删除图标。
activity_change_user_info.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eeeeee"
android:orientation="vertical">
<include layout="@layout/main_title_bar" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/et_content"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:singleLine="true"
android:textColor="#737373"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_delete"
android:layout_width="27dp"
android:layout_height="27dp"
android:layout_marginLeft="-40dp"
android:src="@drawable/info_delete" />
</LinearLayout>
</LinearLayout>
(4)修改main_title_bar.xml文件。由于个人资料界面的标题栏右侧有一个“保存”按钮,因此需要在2. 欢迎模块找到该文件,在其中添加一个“保存”按钮。
<TextView
android:id="@+id/tv_save"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="保存"
android:textColor="@android:color/white"
android:textSize="14sp"
android:visibility="gone" />
15. 个人资料修改界面逻辑代码
任务分析:
在个人资料修改界面中,通过传递过来的标识码判断需要加载修改昵称界面还是修改签名界面。当用户信息修改完成后,点击“保存”按钮将用户信息保存到数据库。需要注意的是,当用户输入昵称或签名时,需要对输入的文字长度进行限制,因此需要给EditText控件添加监听事件。
任务实施:
(1)获取界面控件。在ChangeUserInfoActivity中创建界面控件的初始化方法init(),用于获取个人资料修改界面所要用到的控件,同时在此方法中还需要设置保存按钮、返回键及删除图标的点击事件。
(2)监听要修改的文字。由于昵称和签名的长度是有限的,因此需要创建contentListener()方法监听输入的文字个数,使昵称不超过8个汉字,签名不超过16个汉字。
ChangeUserInfoActivity.java
public class ChangeUserInfoActivity extends AppCompatActivity {
private TextView tv_main_title, tv_save;
private RelativeLayout rl_title_bar;
private TextView tv_back;
private String title, content;
private int flag; //flag为1时表示修改昵称,为2时表示修改签名
private EditText et_content;
private ImageView iv_delete;
private SwipeBackLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = (SwipeBackLayout) LayoutInflater.from(this).inflate(
R.layout.base, null);
layout.attachToActivity(this);
setContentView(R.layout.activity_change_user_info);
//设置此界面为竖屏
init();
}
private void init() {
//从个人资料界面传递过来的标题和内容
title = getIntent().getStringExtra("title");
content = getIntent().getStringExtra("content");
flag = getIntent().getIntExtra("flag", 0);
tv_main_title = (TextView) findViewById(R.id.tv_main_title);
tv_main_title.setText(title);
rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
rl_title_bar.setBackgroundColor(getResources().getColor(R.color.
rdTextColorPress));
tv_back = (TextView) findViewById(R.id.tv_back);
tv_save = (TextView) findViewById(R.id.tv_save);
tv_back.setVisibility(View.VISIBLE);
tv_save.setVisibility(View.VISIBLE);
et_content = (EditText) findViewById(R.id.et_content);
iv_delete = (ImageView) findViewById(R.id.iv_delete);
if (!TextUtils.isEmpty(content)) {
et_content.setText(content);
et_content.setSelection(content.length());
}
contentListener();
tv_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ChangeUserInfoActivity.this.finish();
}
});
iv_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
et_content.setText("");
}
});
tv_save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent data = new Intent();
String etContent = et_content.getText().toString().trim();
switch (flag) {
case 1:
if (!TextUtils.isEmpty(etContent)) {
data.putExtra("nickName", etContent);
setResult(RESULT_OK, data);
Toast.makeText(ChangeUserInfoActivity.this, "保存成功",
Toast.LENGTH_SHORT).show();
ChangeUserInfoActivity.this.finish();
} else {
Toast.makeText(ChangeUserInfoActivity.this,
"昵称不能为空",Toast.LENGTH_SHORT).show();
}
break;
case 2:
if (!TextUtils.isEmpty(etContent)) {
data.putExtra("signature", etContent);
setResult(RESULT_OK, data);
Toast.makeText(ChangeUserInfoActivity.this, "保存成功",
Toast.LENGTH_SHORT).show();
ChangeUserInfoActivity.this.finish();
} else {
Toast.makeText(ChangeUserInfoActivity.this,
"签名不能为空", Toast.LENGTH_SHORT).show();
}
break;
}
}
});
}
/**
* 监听个人资料修改界面输入的文字
*/
private void contentListener() {
et_content.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
Editable editable = et_content.getText();
int len = editable.length();//输入的文本的长度
if (len > 0) {
iv_delete.setVisibility(View.VISIBLE);
} else {
iv_delete.setVisibility(View.GONE);
}
switch (flag) {
case 1: //昵称
//昵称限制最多8个文字,超过8个需要截取掉多余的文字
if (len > 8) {
int selEndIndex = Selection.getSelectionEnd(editable);
String str = editable.toString();
//截取新字符串
String newStr = str.substring(0, 8);
et_content.setText(newStr);
editable = et_content.getText();
//新字符串的长度
int newLen = editable.length();
//旧光标位置超过新字符串的长度
if (selEndIndex > newLen) {
selEndIndex = editable.length();
}
//设置新光标所在的位置
Selection.setSelection(editable, selEndIndex);
}
break;
case 2: //签名
//签名最多是16个文字,超过16个需要截取掉多余的文字
if (len > 16) {
int selEndIndex = Selection.getSelectionEnd(editable);
String str = editable.toString();
//截取新字符串
String newStr = str.substring(0, 16);
et_content.setText(newStr);
editable = et_content.getText();
//新字符串的长度
int newLen = editable.length();
//旧光标位置超过新字符串的长度
if (selEndIndex > newLen) {
selEndIndex = editable.length();
}
//设置新光标所在的位置
Selection.setSelection(editable, selEndIndex);
}
break;
default:
break;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
});
}
}
(3)修改“个人资料”界面逻辑代码。由于在“个人资料”界面中点击昵称或者签名会跳转到个人资料修改界面,因此需要找到"private static final int CROP_PHOTO1 = 3; //裁剪图片",语句下方添加如此代码:
private static final int CHANGE_NICKNAME = 1; //修改昵称的自定义常量
private static final int CHANGE_SIGNATURE = 2; //修改签名的自定义常量
在该文件的onClick()方法中的注释“//昵称的点击事件”下方添加如下代码:
String name = tv_nickName.getText().toString(); //获取昵称控件上的数据
Bundle bdName = new Bundle();
bdName.putString("content", name); //传递界面上的昵称数据
bdName.putString("title", "昵称");
bdName.putInt("flag", 1); //flag传递1时表示是修改昵称
//跳转到个人资料修改界面
enterActivityForResult(ChangeUserInfoActivity.class,CHANGE_NICKNAME, bdName);
在该文件的onClick()方法中的注释“//签名的点击事件”下方添加如下代码:
String signature = tv_signature.getText().toString(); //获取签名控件上的数据
Bundle bdSignature = new Bundle();
bdSignature.putString("content", signature); //传递界面上的签名数据
bdSignature.putString("title", "签名");
bdSignature.putInt("flag", 2); //flag传递2时表示是修改签名
//跳转到个人资料修改界面
enterActivityForResult(ChangeUserInfoActivity.class,CHANGE_SIGNATURE, bdSignature);
在该文件的onActivityResult()方法中的switch语句中添加如下代码:
case CHANGE_NICKNAME: //个人资料修改界面回传过来的昵称数据
if (data != null) {
new_info = data.getStringExtra("nickName");
if (TextUtils.isEmpty(new_info)) {
return;
}
tv_nickName.setText(new_info);
//更新数据库中的昵称字段
DBUtils.getInstance(UserInfoActivity.this).updateUserInfo(
"nickName", new_info, spUserName);
}
break;
case CHANGE_SIGNATURE: //个人资料修改界面回传过来的签名数据
if (data != null) {
new_info = data.getStringExtra("signature");
if (TextUtils.isEmpty(new_info)) {
return;
}
tv_signature.setText(new_info);
//更新数据库中的签名字段
DBUtils.getInstance(UserInfoActivity.this).updateUserInfo(
"signature", new_info, spUserName);
}
break;
(4)修改清单文件。由于个人资料界面向右滑动会关闭该界面,因此需要给该界面添加透明主题的样式,,在清单文件的ChangeUserInfoActivity对应的activity标签中添加如下代码:
<activity
android:name=".activity.ChangeUserInfoActivity"
android:theme="@style/AppTheme.TransparentActivity" />