接上文,点击按钮“添加黑名单”弹出对话框可以添加黑名单号码和拦截方式:
对话框布局文件:
<?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 style="@style/title_center_text"
android:id="@+id/tv_black_number_title"
android:text="添加"/>
<View style="@style/splitter_view"/>
<EditText
android:layout_marginTop="8sp"
android:id="@+id/et_add_black_number"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:hint="请输入拦截号码"/>
<LinearLayout
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<CheckBox
android:id="@+id/cb_block_phone"
android:text="拦截电话"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<CheckBox
android:id="@+id/cb_block_sms"
android:text="拦截短信"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</LinearLayout>
</LinearLayout>
注意这里的两个checkbox居中显示,两个技巧:
1、把它们放到一个水平居中的LinearLayout里,且LinearLayout的高度和宽度为wrap_content。
2、在LinearLayout里,checkbox的layout_weight为1:1
当长按listview里的item时,弹出菜单“删除”和“修改”黑名单选项:
菜单的布局文件call_safe_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/item_delete"
android:title="删除黑名单号码">
</item>
<item
android:id="@+id/item_update"
android:title="更改黑名单号码">
</item>
</menu>
注意菜单的xml文件是放在res\menu目录下的。
完整的CallSafeActivity代码:
package com.example.mobilesafe;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.mobilesafe.db.BlackNumberDao;
import com.example.mobilesafe.engine.BlackNumber;
import java.util.List;
/**
* Created by sing on 14-1-17.
* desc:
*/
public class CallSafeActivity extends Activity {
public static final String TAG = "CallSafeActivity";
public static final int LOAD_DATA_SUCCESS = 1;
public static final int STOP_SMS = 1;
public static final int STOP_CALL = 2;
public static final int STOP_SMSCALL = 4;
private View ll_callsafe_loading;
private ListView lv_blacknumbers;
private Button bt_add_blacknumber;
//显示黑名单号码的适配器对象
private BlackNumberAdapter adapter;
private BlackNumberDao dao;
private List<BlackNumber> blackNumbers;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == LOAD_DATA_SUCCESS) {
ll_callsafe_loading.setVisibility(View.INVISIBLE);
adapter = new BlackNumberAdapter();
lv_blacknumbers.setAdapter(adapter);
}
super.handleMessage(msg);
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.callsafe_layout);
ll_callsafe_loading = findViewById(R.id.ll_callsafe_loading);
ll_callsafe_loading.setVisibility(View.VISIBLE);
lv_blacknumbers = (ListView) findViewById(R.id.lv_blacknumbers);
bt_add_blacknumber = (Button) findViewById(R.id.bt_add_blacknumber);
bt_add_blacknumber.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showBlackNumberDialog(0, 0);
}
});
dao = new BlackNumberDao(this);
// 1.为lv_call_sms_safe注册一个上下文菜单
registerForContextMenu(lv_blacknumbers);
new Thread() {
@Override
public void run() {
blackNumbers = dao.findAll();
Message msg = Message.obtain();
msg.what = LOAD_DATA_SUCCESS;
handler.sendMessage(msg);
}
}.start();
}
private class BlackNumberAdapter extends BaseAdapter {
private static final String TAG = "BlackNumberAdapter";
@Override
public int getCount() {
return blackNumbers.size();
}
@Override
public Object getItem(int i) {
return blackNumbers.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v;
ViewHolder holder;
if (view == null) {
v = View.inflate(getApplicationContext(), R.layout.callsafe_item, null);
holder = new ViewHolder();
holder.tv_number = (TextView) v.findViewById(R.id.tv_callsafe_item_name);
holder.tv_mode = (TextView) v.findViewById(R.id.tv_callsafe_item_mode);
v.setTag(holder);
} else {
v = view;
holder = (ViewHolder) view.getTag();
}
BlackNumber blackNumber = blackNumbers.get(i);
holder.tv_number.setText(blackNumber.getNumber());
int mode = blackNumber.getMode();
if (mode == STOP_SMS) {
holder.tv_mode.setText("拦截短信");
} else if (mode == STOP_CALL) {
holder.tv_mode.setText("拦截电话");
} else {
holder.tv_mode.setText("拦截全部");
}
return v;
}
}
private static class ViewHolder {
TextView tv_number;
TextView tv_mode;
}
// 2.重写创建上下文菜单的方法
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
//设置长按Item后要显示的布局
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.call_safe_menu, menu);
}
// 3.响应上下文菜单的点击事件
@Override
public boolean onContextItemSelected(MenuItem item) {
//获取到Item对应的对象
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = (int) info.id; // 当前上下文菜单对应的listview里面的哪一个条目
switch (item.getItemId()) {
case R.id.item_delete:
Log.i(TAG, "删除黑名单记录");
deleteBlackNumber(position);
return true;
case R.id.item_update:
Log.i(TAG, "更新黑名单记录");
updateBlackNumber(position);
return true;
default:
return super.onContextItemSelected(item);
}
}
/**
* 更新黑名单号码
*
* @param position
*/
private void updateBlackNumber(int position) {
showBlackNumberDialog(1, position);
}
/**
* 删除一条黑名单记录
*
* @param position
*/
private void deleteBlackNumber(int position) {
BlackNumber blackNumber = (BlackNumber) lv_blacknumbers.getItemAtPosition(position);
String number = blackNumber.getNumber();
dao.delete(number); // 删除了 数据库里面的记录
blackNumbers.remove(blackNumber);// 删除当前listview里面的数据.
adapter.notifyDataSetChanged();
}
/**
* 显示添加黑名单时的添加对话框或者修改对话框(两者共用同一个对话框)
*
* @param flag 0 代表添加, 1 代表修改
* @param position 被修改的Item在窗体中的位置。如果添加 数据,添加的数据可以为空
*/
private void showBlackNumberDialog(final int flag, final int position) {
//获得一个窗体构造器
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//将添加号码的布局文件转换成一个View
View dialogview = View.inflate(this, R.layout.add_black_number, null);
//获取输入黑名单号码的EditText
final EditText et_number = (EditText) dialogview.findViewById(R.id.et_add_black_number);
//获取到弹出的对话框中的各个组件
final CheckBox cb_phone = (CheckBox) dialogview.findViewById(R.id.cb_block_phone);
final CheckBox cb_sms = (CheckBox) dialogview.findViewById(R.id.cb_block_sms);
TextView tv_title = (TextView) dialogview.findViewById(R.id.tv_black_number_title);
if (flag == 1) {//修改黑名单数据
tv_title.setText("修改");
//将要修改的黑名单号码回显到号码输入框中
BlackNumber blackNumber = (BlackNumber) lv_blacknumbers.getItemAtPosition(position);
String oldnumber = blackNumber.getNumber();
et_number.setText(oldnumber);
int m = blackNumber.getMode();
//通过拦截模式来指定Checkbox的勾选状态
if (m == STOP_SMS) { //短信拦截
cb_sms.setChecked(true);
cb_phone.setChecked(false);
} else if (m == STOP_CALL) { //电话拦截
cb_phone.setChecked(true);
cb_sms.setChecked(false);
} else {//电话与短信拦截
cb_phone.setChecked(true);
cb_sms.setChecked(true);
}
}
//将转换的布局文件添加到窗体上
builder.setView(dialogview);
//窗体对话框中的“确定”按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//获取到输入的号码,并将号码前后的空格清除掉
String number = et_number.getText().toString().trim();
//flag=1代表的是修改,处理更改的时候 避免更改出来相同的电话号码.
if (flag == 1 && dao.find(number)) {
Toast.makeText(getApplicationContext(), "要修改的电话号码已经存在", 0).show();
return;
}
//如果输入的是空,则直接结束当前方法
if (number.isEmpty()) {
return;
} else {//输入的号码不为空
// 添加结果。如果添加成功 ,需要通知界面更新黑名单数据。默认的是添加失败
boolean result = false;
BlackNumber blacknumber = new BlackNumber();
blacknumber.setNumber(number);
//电话拦截狂和短信拦截狂都被选中的话,拦截模式应该为2
if (cb_phone.isChecked() && cb_sms.isChecked()) {
if (flag == 0) {//flag=1表示是添加黑名单号码
result = dao.add(number, STOP_SMSCALL);
blacknumber.setMode(STOP_SMSCALL);
} else {//修改黑名单号码
//获取到要修改的Item对象
BlackNumber blackNumber = (BlackNumber) lv_blacknumbers.getItemAtPosition(position);
//更新数据库中要修改的那条数据
dao.update(blackNumber.getNumber(), number, STOP_SMSCALL);
blackNumber.setMode(STOP_SMSCALL);
blackNumber.setNumber(number);
//通知适配器重新显示数据(此时,界面上的数据被刷新)
adapter.notifyDataSetChanged();
}
} else if (cb_phone.isChecked()) {//电话拦截,拦截模式为0
if (flag == 0) {//添加黑名单数据
result = dao.add(number, STOP_CALL);
blacknumber.setMode(STOP_CALL);
} else {//修改黑名单数据
//获取到要修改的Item对象
BlackNumber blackNumber = (BlackNumber) lv_blacknumbers.getItemAtPosition(position);
//更新数据库中要修改的那条数据
dao.update(blackNumber.getNumber(), number, STOP_CALL);
blackNumber.setMode(STOP_CALL);
blackNumber.setNumber(number);
//通知适配器重新显示数据(此时,界面上的数据被刷新)
adapter.notifyDataSetChanged();
}
} else if (cb_sms.isChecked()) {//拦截模式为短信拦截(对应的数字为1)
if (flag == 0) {//添加黑名单数据
result = dao.add(number, STOP_SMS);
blacknumber.setMode(STOP_SMS);
} else {//修改黑名单数据
//获取到要修改的Item对象
BlackNumber blackNumber = (BlackNumber) lv_blacknumbers.getItemAtPosition(position);
//更新数据库中要修改的那条数据
dao.update(blackNumber.getNumber(), number, STOP_SMS);
blackNumber.setMode(STOP_SMS);
blackNumber.setNumber(number);
//通知适配器重新显示数据(此时,界面上的数据被刷新)
adapter.notifyDataSetChanged();
}
} else {//没有选择任何拦截模式
Toast.makeText(getApplicationContext(), "拦截模式不能为空", 0).show();
return;
}
if (result) {//添加或修改数据成功,此时需要更新界面列表中的数据
//将新添加的数据添加到集合中,因为适配器是从集合中取数据的
blackNumbers.add(blacknumber);
//通知适配器重新显示数据(此时,界面上的数据被刷新)
adapter.notifyDataSetChanged();
}
}
}
});
//窗体对话框中的“取消按钮”对应的点击事件
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
//创建并显示出窗体对话框
builder.create().show();
}
}
修改黑名单号码和添加黑名单号码调用了同一个函数,只是用参数区别是修改还是添加黑名单。