AndroidStudio移动应用开发第七次实验:开发手机电话号码簿 ...

打印 上一主题 下一主题

主题 853|帖子 853|积分 2559

《移动应用开发》课程

第七次实验

1、在Android Studio中,完成以下功能。
 


图-1 联系人列表          图-2 添加联系人        图-3 联系人详情

请开发手机电话号码簿。在默认页面中,按照图-1方式展示页面内容,要求所有的信息均是从SQLite中进行获取,详细包括:
(1)联系人数量;
(2)联系人的姓名。
联系人姓名可以使用全英文方式(本项目支持中文),要求按照首字母进行分组。联系人数量在20人以上,联系人分组要求在4组以上。
联系人图标采用预先设置的图片库进行加载,并答应用户进行选取更换其他图标(参见课件中干系Demo)。
点击联系人列表上方的搜索栏后,表现搜索页面(请自行设计页面布局效果),在输入检索关键字后,查询联系人信息,并以列表方式表现。
点击联系人列表条目(包括经过检索返回的联系人列表),对应跳转到联系人详情页面(参见图-3),当用户对应点击号码条目对应的“拨打电话”、“视频电话”、“发送信息”按钮,采用Toast方式表现对应的功能,即Dial number,Video call,Send message(本项目跳转到相应的活动页面)。
点击图-1中的“+”(添加)按钮,跳转到添加联系人信息页面(参见图-2),为用户提供添加联系人信息(包括姓名、电话号码、电子信箱、备注、单位信息)和头像信息。保存后,将信息存储到数据库中,并相应更新联系人列表的表现内容。
运行效果:

搜索功能

文件目次 :

AddContactActivity.java
  1. package com.example.theseventhexperiment;
  2. // 导入必要的包
  3. import android.os.Bundle;
  4. import android.text.TextUtils;
  5. import android.view.View;
  6. import android.widget.*;
  7. import androidx.appcompat.app.AppCompatActivity;
  8. import java.util.*;
  9. public class AddContactActivity extends AppCompatActivity implements View.OnClickListener {
  10.     // 声明UI组件
  11.     private ImageButton ib_back;
  12.     private Button btn_tianjia;
  13.     private EditText et_xingming, et_dianhuahaoma, et_dianziyoujian, et_beizhu, et_danweixinxi;
  14.     private Spinner spinner;
  15.     // 声明数据变量
  16.     private String name, e_mail, remark, unit_information, number, avatar, from;
  17.     private int id;
  18.     private Integer selectedImageResource;
  19.     private UserDBHelper mHelper;
  20.     private List<Map<String, Integer>> data; // 使用Integer类型,因为资源ID是整数
  21.     @Override
  22.     protected void onCreate(Bundle savedInstanceState) {
  23.         super.onCreate(savedInstanceState);
  24.         setContentView(R.layout.activity_add_contact);
  25.         // 初始化视图组件
  26.         initView();
  27.         // 设置监听器
  28.         setListener();
  29.         // 获取传递过来的数据
  30.         getValue();
  31.         // 设置视图内容
  32.         setView();
  33.         // 初始化并设置Spinner适配器
  34.         setupSpinner();
  35.     }
  36.     // 初始化视图组件
  37.     private void initView() {
  38.         ib_back = findViewById(R.id.ib_back);
  39.         btn_tianjia = findViewById(R.id.btn_tianjia);
  40.         et_xingming = findViewById(R.id.et_xingming);
  41.         et_dianhuahaoma = findViewById(R.id.et_dianhuahaoma);
  42.         et_dianziyoujian = findViewById(R.id.et_dianziyoujian);
  43.         et_beizhu = findViewById(R.id.et_beizhu);
  44.         et_danweixinxi = findViewById(R.id.et_danweixinxi);
  45.         spinner = findViewById(R.id.spinner_contact_icon);
  46.     }
  47.     // 设置监听器
  48.     private void setListener() {
  49.         ib_back.setOnClickListener(this);
  50.         btn_tianjia.setOnClickListener(this);
  51.     }
  52.     // 获取传递过来的数据
  53.     private void getValue() {
  54.         from = getIntent().getStringExtra("from");
  55.         if ("edit".equals(from)) {
  56.             id = getIntent().getIntExtra("id", 0);
  57.             name = getIntent().getStringExtra("name");
  58.             number = getIntent().getStringExtra("number");
  59.             avatar = getIntent().getStringExtra("avatar");
  60.             e_mail = getIntent().getStringExtra("e-mail");
  61.             remark = getIntent().getStringExtra("remark");
  62.             unit_information = getIntent().getStringExtra("unit_information");
  63.             // 对可能为null的字符串进行默认值处理
  64.             if (e_mail == null) e_mail = "无";
  65.             if (remark == null) remark = "无";
  66.             if (unit_information == null) unit_information = "无";
  67.         }
  68.     }
  69.     // 设置视图内容
  70.     private void setView() {
  71.         if ("edit".equals(from)) {
  72.             et_xingming.setText(name);
  73.             et_dianhuahaoma.setText(number);
  74.             et_dianziyoujian.setText(e_mail);
  75.             et_beizhu.setText(remark);
  76.             et_danweixinxi.setText(unit_information);
  77.         }
  78.     }
  79.     // 初始化并设置Spinner适配器
  80.     private void setupSpinner() {
  81.         // 准备数据
  82.         data = getListData();
  83.         // 创建SimpleAdapter并设置给Spinner
  84.         SimpleAdapter simpleAdapter = new SimpleAdapter(
  85.                 this,
  86.                 data,
  87.                 R.layout.spinner_item, // 自定义布局
  88.                 new String[]{"touxiang"}, // 数据源中的键
  89.                 new int[]{R.id.imageView} // 布局中的ID
  90.         );
  91.         spinner.setAdapter(simpleAdapter);
  92.         // 设置Spinner选择监听器
  93.         spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
  94.             @Override
  95.             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
  96.                 // 获取选中的项并设置给selectedImageResource
  97.                 Map<String, Integer> selectedItem = (Map<String, Integer>) parent.getItemAtPosition(position);
  98.                 selectedImageResource = selectedItem.get("touxiang");
  99.             }
  100.             @Override
  101.             public void onNothingSelected(AdapterView<?> parent) {
  102.                 // 不执行任何操作
  103.             }
  104.         });
  105.     }
  106.     // 获取Spinner列表数据
  107.     private List<Map<String, Integer>> getListData() {
  108.         List<Map<String, Integer>> list = new ArrayList<>();
  109.         int[] touxiangResources = {
  110.                 R.drawable.touxiang1, R.drawable.touxiang2, R.drawable.touxiang3,
  111.                 R.drawable.touxiang4, R.drawable.touxiang5, R.drawable.touxiang6
  112.         };
  113.         for (int resource : touxiangResources) {
  114.             Map<String, Integer> item = new HashMap<>();
  115.             item.put("touxiang", resource);
  116.             // 如果是编辑模式且当前资源是选中的头像,则将其添加到列表的开头
  117.             if ("edit".equals(from) && resource == Integer.parseInt(avatar)) {
  118.                 list.add(0, item);
  119.             } else {
  120.                 list.add(item);
  121.             }
  122.         }
  123.         return list;
  124.     }
  125.     // 数据库帮助器的初始化与关闭
  126.     @Override
  127.     protected void onStart() {
  128.         super.onStart();
  129.         mHelper = UserDBHelper.getInstance(this);
  130.         mHelper.getReadableDatabase(); // 通常不需要显式调用,除非需要立即访问
  131.         mHelper.getWritableDatabase(); // 同上
  132.     }
  133.     @Override
  134.     protected void onStop() {
  135.         super.onStop();
  136.         if (mHelper != null) {
  137.             mHelper.close();
  138.         }
  139.     }
  140.     // 点击事件处理
  141.     @Override
  142.     public void onClick(View v) {
  143.         switch (v.getId()) {
  144.             case R.id.ib_back:
  145.                 finish();
  146.                 break;
  147.             case R.id.btn_tianjia:
  148.                 // 获取输入框内容并进行校验
  149.                 String et_name = et_xingming.getText().toString().trim();
  150.                 String et_phone = et_dianhuahaoma.getText().toString().trim();
  151.                 String et_email = et_dianziyoujian.getText().toString().trim();
  152.                 String et_remark = et_beizhu.getText().toString().trim();
  153.                 String et_unitInfo = et_danweixinxi.getText().toString().trim();
  154.                 // 对空值或无效输入进行处理
  155.                 if (TextUtils.isEmpty(et_name)) {
  156.                     Toast.makeText(this, "请输入姓名", Toast.LENGTH_SHORT).show();
  157.                 } else if (TextUtils.isEmpty(et_phone) || !et_phone.matches("\\d+")) {
  158.                     Toast.makeText(this, "请输入有效的电话号码", Toast.LENGTH_SHORT).show();
  159.                 } else {
  160.                     // 创建联系人对象并保存
  161.                     Contacter contacter = new Contacter(
  162.                             et_name, et_phone, et_email, et_remark, et_unitInfo,
  163.                             selectedImageResource != null ? selectedImageResource.toString() : null
  164.                     );
  165.                     if ("edit".equals(from)) {
  166.                         // 更新联系人
  167.                         if (mHelper.updateContact(id, contacter) > 0) {
  168.                             Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();
  169.                             finish();
  170.                         } else {
  171.                             Toast.makeText(this, "修改失败", Toast.LENGTH_SHORT).show();
  172.                         }
  173.                     } else if ("add".equals(from)) {
  174.                         // 添加联系人
  175.                         if (mHelper.insert(contacter) > 0) {
  176.                             Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
  177.                             finish();
  178.                         } else {
  179.                             Toast.makeText(this, "添加失败", Toast.LENGTH_SHORT).show();
  180.                         }
  181.                     }
  182.                 }
  183.                 break;
  184.             default:
  185.                 break;
  186.         }
  187.     }
  188. }
复制代码
 Contacter.java
  1. package com.example.theseventhexperiment;
  2. public class Contacter {
  3.     public int id;
  4.     public String name;
  5.     public String phonenumber;//存储电话号码
  6.     public String e_mail;
  7.     public String remark;
  8.     public String unit_information;
  9.     public String avatar;//存储头像资源id
  10.     public String beginZ;//第一个字母
  11.     public Contacter(int id, String name, String phonenumber, String e_mail, String remark, String unit_information, String avatar, String beginZ) {
  12.         this.id = id;
  13.         this.name = name;
  14.         this.phonenumber = phonenumber;
  15.         this.e_mail = e_mail;
  16.         this.remark = remark;
  17.         this.unit_information = unit_information;
  18.         this.avatar = avatar;
  19.         this.beginZ = beginZ;
  20.     }
  21.     public Contacter(String name, String phonenumber, String e_mail, String remark, String unit_information, String avatar) {
  22.         this.name = name;
  23.         this.phonenumber = phonenumber;
  24.         this.e_mail = e_mail;
  25.         this.remark = remark;
  26.         this.unit_information = unit_information;
  27.         this.beginZ = beginZ;
  28.         this.avatar = avatar;
  29.     }
  30.     public String getAvatar() {
  31.         return avatar;
  32.     }
  33.     public void setAvatar(String avatar) {
  34.         this.avatar = avatar;
  35.     }
  36.     public int getId() {
  37.         return id;
  38.     }
  39.     public void setId(int id) {
  40.         this.id = id;
  41.     }
  42.     public String getName() {
  43.         return name;
  44.     }
  45.     public void setName(String name) {
  46.         this.name = name;
  47.     }
  48.     public String getPhonenumber() {
  49.         return phonenumber;
  50.     }
  51.     public void setPhonenumber(String phonenumber) {
  52.         this.phonenumber = phonenumber;
  53.     }
  54.     public String getE_mail() {
  55.         return e_mail;
  56.     }
  57.     public void setE_mail(String e_mail) {
  58.         this.e_mail = e_mail;
  59.     }
  60.     public String getRemark() {
  61.         return remark;
  62.     }
  63.     public void setRemark(String remark) {
  64.         this.remark = remark;
  65.     }
  66.     public String getUnit_information() {
  67.         return unit_information;
  68.     }
  69.     public void setUnit_information(String unit_information) {
  70.         this.unit_information = unit_information;
  71.     }
  72.     public String getBeginZ() {
  73.         return beginZ;
  74.     }
  75.     public void setBeginZ(String beginZ) {
  76.         this.beginZ = beginZ;
  77.     }
  78.     @Override
  79.     public String toString() {
  80.         return "Contacter{" +
  81.                 "id=" + id +
  82.                 ", name='" + name + '\'' +
  83.                 ", phonenumber=" + phonenumber +
  84.                 ", e_mail='" + e_mail + '\'' +
  85.                 ", remark='" + remark + '\'' +
  86.                 ", unit_information='" + unit_information + '\'' +
  87.                 ", beginZ='" + beginZ + '\'' +
  88.                 '}';
  89.     }
  90. }
复制代码
ContacterAdpter.java
  1. package com.example.theseventhexperiment;
  2. import android.content.Context;
  3. import android.os.Build;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import android.widget.ArrayAdapter;
  8. import android.widget.ImageView;
  9. import android.widget.TextView;
  10. import androidx.annotation.NonNull;
  11. import androidx.annotation.Nullable;
  12. import androidx.annotation.RequiresApi;
  13. import java.util.List;
  14. // 自定义的适配器类,用于显示联系人列表
  15. public class ContacterAdpter extends ArrayAdapter<Contacter> {
  16.     List<Contacter> items;
  17.     public ContacterAdpter(Context context, List<Contacter> items) {
  18.         super(context, R.layout.lian_xi_ren_bu_ju, items);
  19.         this.items = items;
  20.     }
  21.     // 重写getView方法,用于根据位置获取视图
  22.     @RequiresApi(api = Build.VERSION_CODES.N)
  23.     @NonNull
  24.     @Override
  25.     public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
  26.         // ViewHolder模式,用于优化性能,减少findViewById的调用
  27.         ViewHolder holder;
  28.         // 如果convertView为空,说明需要创建新的视图
  29.         if (convertView == null) {
  30.             LayoutInflater layoutInflater = LayoutInflater.from(getContext());
  31.             convertView = layoutInflater.inflate(R.layout.lian_xi_ren_bu_ju, parent, false);
  32.             holder = new ViewHolder();
  33.             holder.iv_touxiang = convertView.findViewById(R.id.iv_touxiang); // 头像ImageView
  34.             holder.tv_xingming = convertView.findViewById(R.id.tv_xingming); // 姓名TextView
  35.             holder.tv_zimu = convertView.findViewById(R.id.tv_zimu); // 首字母TextView
  36.             // 将ViewHolder对象保存在convertView的tag中,以便复用
  37.             convertView.setTag(holder);
  38.         } else {
  39.             // 如果convertView不为空,则直接获取ViewHolder对象
  40.             holder = (ViewHolder) convertView.getTag();
  41.         }
  42.         // 获取当前位置的联系人对象
  43.         Contacter contacter = items.get(position);
  44.         // 设置姓名
  45.         holder.tv_xingming.setText(contacter.getName());
  46.         // 设置头像,这里假设头像资源是以字符串形式存储的整数ID
  47.         holder.iv_touxiang.setImageResource(Integer.parseInt(contacter.getAvatar()));
  48.         // 判断是否需要显示首字母
  49.         // 如果当前位置是第一个或者当前联系人的首字母与前一个不同,则显示首字母
  50.         if (position == 0 || !items.get(position - 1).getBeginZ().equals(contacter.getBeginZ())) {
  51.             holder.tv_zimu.setText(contacter.getBeginZ());
  52.             holder.tv_zimu.setVisibility(View.VISIBLE);
  53.         } else {
  54.             // 否则隐藏首字母
  55.             holder.tv_zimu.setVisibility(View.GONE);
  56.         }
  57.         // 返回当前位置的视图
  58.         return convertView;
  59.     }
  60.     // ViewHolder类,用于缓存视图引用,提高性能
  61.     private static class ViewHolder {
  62.         ImageView iv_touxiang; // 头像ImageView
  63.         TextView tv_xingming; // 姓名TextView
  64.         TextView tv_zimu; // 首字母TextView
  65.     }
  66. }
复制代码
ContactInformationActivity.java
  1. package com.example.theseventhexperiment;
  2. import android.app.AlertDialog;
  3. import android.content.DialogInterface;
  4. import android.content.Intent;
  5. import android.net.Uri;
  6. import android.os.Bundle;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.ImageButton;
  10. import android.widget.ImageView;
  11. import android.widget.TextView;
  12. import android.widget.Toast;
  13. import androidx.appcompat.app.AppCompatActivity;
  14. // ContactInformationActivity 类用于显示联系人详细信息并提供相关操作
  15. public class ContactInformationActivity extends AppCompatActivity implements View.OnClickListener {
  16.     // 视图元素
  17.     private ImageButton btn_back;
  18.     private TextView tv_xingming, tv_number, tv_dianziyoujian, tv_beizhu, tv_danweixinxi;
  19.     private ImageView iv_touxiang;
  20.     private Button btn_shanchu, btn_dadianhua, btn_faxinxi, btn_bianji;
  21.     // 数据库帮助类实例
  22.     private UserDBHelper dbHelper;
  23.     // 联系人信息变量
  24.     private String name, e_mail, remark, unit_information, number, avatar;
  25.     private int id;
  26.     @Override
  27.     protected void onCreate(Bundle savedInstanceState) {
  28.         super.onCreate(savedInstanceState);
  29.         setContentView(R.layout.activity_contact_information);
  30.         // 初始化视图元素
  31.         initView();
  32.         // 设置点击事件监听器
  33.         setListener();
  34.         // 从 Intent 中获取联系人信息
  35.         getValueFromIntent();
  36.         // 设置视图显示内容
  37.         setView();
  38.     }
  39.     // 从 Intent 中获取联系人信息的方法
  40.     private void getValueFromIntent() {
  41.         id = getIntent().getIntExtra("id", 0);
  42.         name = getIntent().getStringExtra("name");
  43.         number = getIntent().getStringExtra("number");
  44.         avatar = getIntent().getStringExtra("avatar");
  45.         e_mail = getIntent().getStringExtra("e-mail");
  46.         if (e_mail == null) {
  47.             e_mail = "无";
  48.         }
  49.         remark = getIntent().getStringExtra("remark");
  50.         if (remark == null) {
  51.             remark = "无";
  52.         }
  53.         unit_information = getIntent().getStringExtra("unit_information");
  54.         if (unit_information == null) {
  55.             unit_information = "无";
  56.         }
  57.     }
  58.     // 设置点击事件监听器的方法
  59.     private void setListener() {
  60.         btn_back.setOnClickListener(this);
  61.         btn_shanchu.setOnClickListener(this);
  62.         btn_dadianhua.setOnClickListener(this);
  63.         btn_faxinxi.setOnClickListener(this);
  64.         btn_bianji.setOnClickListener(this);
  65.     }
  66.     // 设置视图显示内容的方法
  67.     private void setView() {
  68.         tv_xingming.setText("姓名:" + name);
  69.         tv_number.setText("电话号码:" + number);
  70.         // 注意:这里假设 avatar 是一个资源 ID,如果 avatar 是 URL 或文件路径,需要相应处理
  71.         iv_touxiang.setImageResource(Integer.parseInt(avatar));
  72.         tv_beizhu.setText("备注:" + remark);
  73.         tv_danweixinxi.setText("单位信息:" + unit_information);
  74.         tv_dianziyoujian.setText("电子邮件:" + e_mail);
  75.     }
  76.     // 初始化视图元素的方法
  77.     private void initView() {
  78.         tv_xingming = findViewById(R.id.tv_datail_xingming);
  79.         tv_number = findViewById(R.id.tv_detail_dianhuahaoma);
  80.         tv_dianziyoujian = findViewById(R.id.tv_detail_dianziyoujian);
  81.         tv_beizhu = findViewById(R.id.tv_detail_beizhu);
  82.         tv_danweixinxi = findViewById(R.id.tv_detail_danweixinxi);
  83.         btn_back = findViewById(R.id.ib_detail_back);
  84.         btn_dadianhua = findViewById(R.id.btn_dadianhua);
  85.         btn_faxinxi = findViewById(R.id.btn_faxiaoxi);
  86.         btn_bianji = findViewById(R.id.btn_bianji);
  87.         iv_touxiang = findViewById(R.id.iv_detail_touxiang);
  88.         btn_shanchu = findViewById(R.id.btn_shanchu);
  89.         // 初始化数据库帮助类实例
  90.         dbHelper = UserDBHelper.getInstance(this);
  91.     }
  92.     // 点击事件处理方法
  93.     @Override
  94.     public void onClick(View v) {
  95.         Intent intent = new Intent();
  96.         switch (v.getId()) {
  97.             case R.id.ib_detail_back:
  98.                 // 返回上一个界面
  99.                 intent.putExtra("from","detail");
  100.                 finish();
  101.                 break;
  102.             case R.id.btn_shanchu:
  103.                 // 显示删除确认对话框
  104.                 showDeleteConfirmDialog();
  105.                 break;
  106.             case R.id.btn_dadianhua:
  107.                 // 拨打电话
  108.                 intent.setAction(Intent.ACTION_DIAL);
  109.                 intent.setData(Uri.parse("tel:" + number));
  110.                 startActivity(intent);
  111.                 break;
  112.             case R.id.btn_faxiaoxi:
  113.                 // 发送短信
  114.                 intent.setAction(Intent.ACTION_SENDTO);
  115.                 intent.setData(Uri.parse("smsto:" + number));
  116.                 startActivity(intent);
  117.                 break;
  118.             case R.id.btn_bianji:
  119.                 // 编辑联系人信息
  120.                 intent = new Intent(ContactInformationActivity.this, AddContactActivity.class);
  121.                 intent.putExtra("id", id);
  122.                 intent.putExtra("name", name);
  123.                 intent.putExtra("e-mail", e_mail);
  124.                 intent.putExtra("remark", remark);
  125.                 intent.putExtra("unit_information", unit_information);
  126.                 intent.putExtra("number", number);
  127.                 intent.putExtra("avatar", avatar);
  128.                 intent.putExtra("from", "edit");
  129.                 startActivity(intent);
  130.                 finish();
  131.                 break;
  132.             default:
  133.                 break;
  134.         }
  135.     }
  136.     // 显示删除确认对话框的方法
  137.     private void showDeleteConfirmDialog() {
  138.         if (id != 0) { // 假设 0 是一个无效或未设置的 ID 值
  139.             AlertDialog.Builder builder = new AlertDialog.Builder(this);
  140.             builder.setTitle("确认删除")
  141.                     .setMessage("您确定要删除该联系人吗?")
  142.                     .setCancelable(false)
  143.                     .setPositiveButton("确定", new DialogInterface.OnClickListener() {
  144.                         @Override
  145.                         public void onClick(DialogInterface dialog, int which) {
  146.                             int numberOfContactsBefore = dbHelper.numberOfContacts();
  147.                             dbHelper.deleteContactById(id);
  148.                             int numberOfContactsAfter = dbHelper.numberOfContacts();
  149.                             if (numberOfContactsBefore - 1 == numberOfContactsAfter) {
  150.                                 Toast.makeText(ContactInformationActivity.this, "删除成功", Toast.LENGTH_SHORT).show();
  151.                                 finish();
  152.                             } else {
  153.                                 Toast.makeText(ContactInformationActivity.this, "删除失败,可能是 ID 错误或数据库问题", Toast.LENGTH_SHORT).show();
  154.                             }
  155.                         }
  156.                     })
  157.                     .setNegativeButton("取消", new DialogInterface.OnClickListener() {
  158.                         @Override
  159.                         public void onClick(DialogInterface dialog, int id) {
  160.                             dialog.cancel();
  161.                         }
  162.                     });
  163.             AlertDialog alert = builder.create();
  164.             alert.show();
  165.         } else {
  166.             Toast.makeText(this, "无效的 ID", Toast.LENGTH_SHORT).show();
  167.         }
  168.     }
  169. }
复制代码
GteDataFromDatabase.java
  1. package com.example.theseventhexperiment;
  2. import android.content.Context;
  3. import android.database.Cursor;
  4. import android.database.sqlite.SQLiteDatabase;
  5. import com.hankcs.hanlp.HanLP;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10. public class GteDataFromDatabase {
  11.     // 声明数据库实例和数据库帮助类实例
  12.     private static SQLiteDatabase db;
  13.     private static UserDBHelper userDBHelper;
  14.     /**
  15.      * 从数据库中获取所有联系人信息的方法
  16.      *
  17.      * @param context 上下文对象,用于访问数据库
  18.      * @return 包含所有联系人信息的列表
  19.      */
  20.     public static List<Contacter> getAllContacts(Context context) {
  21.         List<Contacter> list = new ArrayList<>(); // 创建联系人列表
  22.         // 初始化数据库帮助类并获取可读数据库
  23.         userDBHelper = new UserDBHelper(context);
  24.         db = userDBHelper.getReadableDatabase();
  25.         // 定义正则表达式用于匹配中文字符
  26.         String regex = "[\\u4e00-\\u9fa5]+";
  27.         // 执行SQL查询,获取所有联系人信息
  28.         Cursor res = db.rawQuery("SELECT * FROM contacter_info", null);
  29.         try {
  30.             while (res.moveToNext()) { // 遍历查询结果
  31.                 // 从Cursor中提取联系人信息
  32.                 String id = res.getString(res.getColumnIndexOrThrow("_id")); // 联系人ID
  33.                 String name = res.getString(res.getColumnIndexOrThrow("name")); // 联系人姓名
  34.                 String phonenumber = res.getString(res.getColumnIndexOrThrow("phonenumber")); // 联系人电话
  35.                 String e_mail = res.getString(res.getColumnIndexOrThrow("e_mail")); // 联系人邮箱
  36.                 String remark = res.getString(res.getColumnIndexOrThrow("remark")); // 联系人备注
  37.                 String unit_information = res.getString(res.getColumnIndexOrThrow("unit_information")); // 联系人单位信息
  38.                 // 注意:原代码中avater可能是拼写错误,这里保留原样,但建议检查数据库表结构
  39.                 String avatar = res.getString(res.getColumnIndexOrThrow("avater")); // 联系人头像
  40.                 // 创建Contacter对象并设置属性
  41.                 Contacter contacter = new Contacter(
  42.                         Integer.parseInt(id),
  43.                         name,
  44.                         phonenumber,
  45.                         e_mail,
  46.                         remark,
  47.                         unit_information,
  48.                         avatar,
  49.                         ""
  50.                 );
  51.                 // 设置联系人姓名的首字母或拼音首字母
  52.                 String firstNameChar = name.substring(0, 1); // 获取姓名的第一个字符
  53.                 boolean isAlphabetic = firstNameChar.matches("^[a-zA-Z]*"); // 判断是否为英文字母
  54.                 if (isAlphabetic) {
  55.                     // 如果是英文字母,则直接设置为大写
  56.                     contacter.setBeginZ(firstNameChar.toUpperCase());
  57.                 } else {
  58.                     // 如果不是英文字母,则检查是否为中文字符
  59.                     Pattern pattern = Pattern.compile(regex);
  60.                     Matcher matcher = pattern.matcher(firstNameChar);
  61.                     if (matcher.find()) {
  62.                         // 如果是中文字符,则转换为拼音并设置首字母大写
  63.                         String pinyin = HanLP.convertToPinyinString(firstNameChar, "", false);
  64.                         contacter.setBeginZ(pinyin.substring(0, 1).toUpperCase());
  65.                     } else {
  66.                         // 如果既不是英文字母也不是中文字符,则设置为"#"
  67.                         contacter.setBeginZ("#");
  68.                     }
  69.                 }
  70.                 // 将Contacter对象添加到列表中
  71.                 list.add(contacter);
  72.             }
  73.         } finally {
  74.             // 关闭Cursor以释放资源
  75.             if (res != null) {
  76.                 res.close();
  77.             }
  78.         }
  79.         // 返回联系人列表
  80.         return list;
  81.     }
  82. }
复制代码
MainActivity.java
  1. package com.example.theseventhexperiment;
  2. import android.content.Intent;
  3. import android.database.sqlite.SQLiteDatabase;
  4. import android.os.Build;
  5. import android.os.Bundle;
  6. import android.text.Editable;
  7. import android.text.TextWatcher;
  8. import android.view.MotionEvent;
  9. import android.view.View;
  10. import android.widget.AdapterView;
  11. import android.widget.EditText;
  12. import android.widget.ImageButton;
  13. import android.widget.ListView;
  14. import androidx.annotation.RequiresApi;
  15. import androidx.appcompat.app.AppCompatActivity;
  16. import java.util.ArrayList;
  17. import java.util.Comparator;
  18. import java.util.List;
  19. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  20.     // 数据库相关变量
  21.     SQLiteDatabase db;
  22.     UserDBHelper userDBHelper;
  23.     // 适配器和视图组件
  24.     ContacterAdpter contacterAdpter;
  25.     EditText ed_sousuo; // 搜索框
  26.     ListView listView; // 联系人列表
  27.     ImageButton ib_tianjialianxiren; // 添加联系人按钮
  28.     @RequiresApi(api = Build.VERSION_CODES.N)
  29.     @Override
  30.     protected void onCreate(Bundle savedInstanceState) {
  31.         super.onCreate(savedInstanceState);
  32.         setContentView(R.layout.activity_main);
  33.         // 初始化视图组件
  34.         initView();
  35.         // 设置事件监听器
  36.         setListener();
  37.         // 加载联系人列表
  38.         loadViewlist();
  39.     }
  40.     @RequiresApi(api = Build.VERSION_CODES.N)
  41.     @Override
  42.     protected void onResume() {
  43.         super.onResume();
  44.         // 当活动恢复时重新加载联系人列表
  45.         ed_sousuo.setText("");//把搜索栏内容清空
  46.         loadViewlist();
  47.     }
  48.     /**
  49.      * 从数据库加载联系人列表并更新UI
  50.      */
  51.     @RequiresApi(api = Build.VERSION_CODES.N)
  52.     private void loadViewlist() {
  53.         int number = userDBHelper.numberOfContacts();
  54.         String hind = "在" + number + "位联系人中搜索";
  55.         ed_sousuo.setHint(hind);
  56.         List<Contacter> result = GteDataFromDatabase.getAllContacts(this);
  57.         // 如果联系人列表为空,则创建一个空适配器
  58.         if (result.isEmpty()) {
  59.             contacterAdpter = new ContacterAdpter(this, new ArrayList<>());
  60.         } else {
  61.             // 否则,对联系人列表进行排序并设置适配器
  62.             sort(result);
  63.             contacterAdpter = new ContacterAdpter(this, result);
  64.         }
  65.         // 为listView设置适配器
  66.         listView.setAdapter(contacterAdpter);
  67.     }
  68.     /**
  69.      * 设置事件监听器
  70.      */
  71.     private void setListener() {
  72.         // 添加联系人按钮点击事件
  73.         ib_tianjialianxiren.setOnClickListener(this);
  74.         // 联系人列表点击事件
  75.         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  76.             @Override
  77.             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  78.                 Contacter clickedContacter = contacterAdpter.getItem(position);
  79.                 Intent intent = new Intent(MainActivity.this, ContactInformationActivity.class);
  80.                 intent.putExtra("id", clickedContacter.getId());
  81.                 intent.putExtra("name", clickedContacter.getName());
  82.                 intent.putExtra("e-mail", clickedContacter.getE_mail());
  83.                 intent.putExtra("remark", clickedContacter.getRemark());
  84.                 intent.putExtra("unit_information", clickedContacter.getUnit_information());
  85.                 intent.putExtra("number", clickedContacter.getPhonenumber());
  86.                 intent.putExtra("avatar", clickedContacter.getAvatar());
  87.                 startActivity(intent);
  88.             }
  89.         });
  90.         // 搜索框触摸事件(用于搜索功能)
  91.         ed_sousuo.setOnTouchListener(new View.OnTouchListener() {
  92.             @RequiresApi(api = Build.VERSION_CODES.N)
  93.             @Override
  94.             public boolean onTouch(View v, MotionEvent event) {
  95.                 // 这里逻辑已经被下面的TextWatcher替代,可以移除
  96.                 return false;
  97.             }
  98.         });
  99.         // 搜索框文本变化监听器(用于实时搜索)
  100.         ed_sousuo.addTextChangedListener(new TextWatcher() {
  101.             @Override
  102.             public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  103.             @Override
  104.             public void onTextChanged(CharSequence s, int start, int before, int count) {}
  105.             @RequiresApi(api = Build.VERSION_CODES.N)
  106.             @Override
  107.             public void afterTextChanged(Editable s) {
  108.                 String searchText = s.toString();
  109.                 List<Contacter> searchResult = UserDBHelper.Search(MainActivity.this, searchText);
  110.                 // 更新适配器并设置到listView
  111.                 if (searchResult == null || searchResult.isEmpty()) {
  112.                     contacterAdpter = new ContacterAdpter(MainActivity.this, new ArrayList<>());
  113.                 } else {
  114.                     sort(searchResult);
  115.                     contacterAdpter = new ContacterAdpter(MainActivity.this, searchResult);
  116.                 }
  117.                 listView.setAdapter(contacterAdpter);
  118.             }
  119.         });
  120.     }
  121.     /**
  122.      * 初始化视图组件
  123.      */
  124.     private void initView() {
  125.         ib_tianjialianxiren = findViewById(R.id.ib_tianjialianxiren);
  126.         userDBHelper = new UserDBHelper(this);
  127.         db = userDBHelper.getReadableDatabase();
  128.         ed_sousuo = findViewById(R.id.et_sousuo);
  129.         listView = findViewById(R.id.lv_lianxiren);
  130.     }
  131.     @Override
  132.     public void onClick(View v) {
  133.         Intent intent = new Intent(this, AddContactActivity.class);
  134.         intent.putExtra("from", "add");
  135.         startActivity(intent);
  136.     }
  137.     /**
  138.      * 对联系人列表按拼音首字母排序
  139.      */
  140.     @RequiresApi(api = Build.VERSION_CODES.N)
  141.     public void sort(List<Contacter> contacterList) {
  142.         contacterList.sort(new Comparator<Contacter>() {
  143.             @Override
  144.             public int compare(Contacter c1, Contacter c2) {
  145.                 String beginZ1 = c1.getBeginZ();
  146.                 String beginZ2 = c2.getBeginZ();
  147.                 // 特殊处理"#"开头的联系人,通常表示未设置拼音首字母
  148.                 if ("#".equals(beginZ1) && "#".equals(beginZ2)) {
  149.                     return 0;
  150.                 }
  151.                 if ("#".equals(beginZ1)) {
  152.                     return 1;
  153.                 }
  154.                 if ("#".equals(beginZ2)) {
  155.                     return -1;
  156.                 }
  157.                 return beginZ1.compareTo(beginZ2);
  158.             }
  159.         });
  160.     }
  161. }
复制代码
UserDBHelper.java
  1. package com.example.theseventhexperiment;
  2. import android.content.ContentValues;
  3. import android.content.Context;
  4. import android.database.Cursor;
  5. import android.database.sqlite.SQLiteDatabase;
  6. import android.database.sqlite.SQLiteOpenHelper;
  7. import com.hankcs.hanlp.HanLP;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.regex.Matcher;
  11. import java.util.regex.Pattern;
  12. public class UserDBHelper extends SQLiteOpenHelper {
  13.     private static final String DB_NAME = "contact_db.db";
  14.     private static final String TABLE_NAME = "contacter_info";
  15.     private static final int VERSION = 1;
  16.     public static SQLiteDatabase db = null;
  17.     private static UserDBHelper mHelper = null;
  18.     public UserDBHelper(Context context) {
  19.         super(context, DB_NAME, null, VERSION);
  20.     }
  21.     public static UserDBHelper getInstance(Context context) {
  22.         if (mHelper == null) {
  23.             mHelper = new UserDBHelper(context);
  24.         }
  25.         return mHelper;
  26.     }
  27.     public static List<Contacter> Search(Context context, String what) {
  28.         List<Contacter> list = new ArrayList<>();
  29.         mHelper = new UserDBHelper(context);
  30.         String sql = "SELECT * FROM " + TABLE_NAME + " WHERE name LIKE '%" + what + "%' OR phonenumber LIKE '%" + what + "%'";
  31.         db = mHelper.getReadableDatabase();
  32.         String regex = "[\\u4e00-\\u9fa5]+";
  33.         Cursor res = null;
  34.         res = db.rawQuery(sql, null);
  35.         while (res.moveToNext()) {
  36.             String id = res.getString(res.getColumnIndexOrThrow("_id")); // 使用列名更安全
  37.             String name = res.getString(res.getColumnIndexOrThrow("name"));
  38.             String phonenumber = res.getString(res.getColumnIndexOrThrow("phonenumber")); // 注意这里应该是字符串
  39.             String e_mail = res.getString(res.getColumnIndexOrThrow("e_mail"));
  40.             String remark = res.getString(res.getColumnIndexOrThrow("remark"));
  41.             String unit_information = res.getString(res.getColumnIndexOrThrow("unit_information"));
  42.             String avatar = res.getString(res.getColumnIndexOrThrow("avater"));
  43.             Contacter contacter = new Contacter(
  44.                     Integer.parseInt(id),
  45.                     name,
  46.                     phonenumber,
  47.                     e_mail,
  48.                     remark,
  49.                     unit_information,
  50.                     avatar,
  51.                     ""
  52.             );
  53.             String first = name.substring(0, 1);
  54.             boolean re = first.matches("^[a-zA-Z]*");
  55.             if (re) {
  56.                 contacter.setBeginZ(first.toUpperCase());
  57.             } else {
  58.                 Pattern pattern = Pattern.compile(regex);
  59.                 Matcher matcher = pattern.matcher(first);
  60.                 if (matcher.find()) {
  61.                     String pinyin = HanLP.convertToPinyinString(first, "", false);
  62.                     contacter.setBeginZ(pinyin.substring(0, 1).toUpperCase());
  63.                 } else {
  64.                     contacter.setBeginZ("#");
  65.                 }
  66.             }
  67.             list.add(contacter);
  68.         }
  69.         return list;
  70.     }
  71.     @Override
  72.     public void onCreate(SQLiteDatabase db) {
  73.         String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
  74.                 "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
  75.                 "name VARCHAR NOT NULL," +
  76.                 "phonenumber VARCHAR NOT NULL," +
  77.                 "e_mail VARCHAR," +
  78.                 "remark VARCHAR," +
  79.                 "unit_information VARCHAR," +
  80.                 "avater VARCHAR NOT NULL);";
  81.         db.execSQL(sql);
  82.     }
  83.     public void deleteContactById(long id) {
  84.         SQLiteDatabase db = getWritableDatabase(); // 获取可写的数据库连接
  85.         String selection = "_id = ?"; // 删除条件
  86.         String[] selectionArgs = {String.valueOf(id)}; // 删除条件参数
  87.         db.delete(TABLE_NAME, selection, selectionArgs); // 执行删除操作
  88.     }
  89.     public void closeLink() {
  90.         if (db != null && db.isOpen()) {
  91.             db.close();
  92.             db = null;
  93.         }
  94.     }
  95.     public long insert(Contacter contacter) {
  96.         ContentValues values = new ContentValues();
  97.         SQLiteDatabase db = this.getWritableDatabase();
  98.         values.put("name", contacter.name);
  99.         values.put("phonenumber", contacter.phonenumber);
  100.         values.put("e_mail", contacter.e_mail);
  101.         values.put("remark", contacter.remark);
  102.         values.put("unit_information", contacter.unit_information);
  103.         values.put("avater", contacter.avatar);
  104.         return db.insert(TABLE_NAME, null, values);
  105.     }
  106.     public int numberOfContacts() {
  107.         SQLiteDatabase db = this.getReadableDatabase();
  108.         String countQuery = "SELECT COUNT(*) FROM " + TABLE_NAME;
  109.         Cursor cursor = db.rawQuery(countQuery, null);
  110.         int count = 0;
  111.         if (cursor.moveToFirst()) {
  112.             count = cursor.getInt(0);
  113.         }
  114.         cursor.close();
  115.         return count;
  116.     }
  117.     public int updateContact(int id, Contacter contacter) {
  118.         SQLiteDatabase db = getWritableDatabase();
  119.         String selection = "_id = ?";
  120.         String[] selectionArgs = {String.valueOf(id)};
  121.         ContentValues values = new ContentValues();
  122.         values.put("name", contacter.name);
  123.         values.put("phonenumber", contacter.phonenumber); // 这里可能需要类型转换,但因为我们假设它是 int,所以不需要
  124.         values.put("e_mail", contacter.e_mail);
  125.         values.put("remark", contacter.remark);
  126.         values.put("unit_information", contacter.unit_information);
  127.         values.put("avater", contacter.avatar);
  128.         int rowsAffected = db.update(TABLE_NAME, values, selection, selectionArgs);
  129.         return rowsAffected;
  130.     }
  131.     @Override
  132.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  133.         onCreate(db);
  134.     }
  135. }
复制代码
add.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <vector xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:width="80dp"
  4.     android:height="80dp"
  5.     android:alpha="0.8"
  6.     android:tint="#337AE5"
  7.     android:viewportWidth="24"
  8.     android:viewportHeight="24">
  9.     <group
  10.         android:scaleX="1.1111112"
  11.         android:scaleY="1.1111112"
  12.         android:translateX="-1.3333334"
  13.         android:translateY="-1.3333334">
  14.         <path
  15.             android:fillColor="#000000"
  16.             android:pathData="M13,7h-2v4L7,11v2h4v4h2v-4h4v-2h-4L13,7zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />
  17.     </group>
  18. </vector>
复制代码
back.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <vector xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:width="50dp"
  4.     android:height="50dp"
  5.     android:viewportWidth="24"
  6.     android:viewportHeight="24"
  7.     android:tint="#3374E5"
  8.     android:alpha="0.8">
  9.     <path
  10.         android:fillColor="@android:color/white"
  11.         android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
  12. </vector>
复制代码
sou_suo_kuang.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item>
  4.     <shape>
  5.         <solid android:color="#EFEDED"></solid>
  6.         <corners android:radius="10dp"></corners>
  7.     </shape>
  8. </item>
  9. </selector>
复制代码
stype.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  3.     <item>
  4.         <shape>
  5.             <stroke
  6.                 android:width="0dp"
  7.                 android:color="#00FF0000" />
  8.             <padding
  9.                 android:bottom="0dp"
  10.                 android:left="0dp"
  11.                 android:right="0dp"
  12.                 android:top="0dp" />
  13.         </shape>
  14.     </item>
  15. </layer-list>
复制代码
activity_add_contact.xml
  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.     android:orientation="vertical"
  7.     android:padding="10dp"
  8.     tools:context=".AddContactActivity">
  9.     <Spinner
  10.         android:id="@+id/spinner_contact_icon"
  11.         android:layout_width="120dp"
  12.         android:layout_height="120dp"
  13.         android:layout_centerHorizontal="true"
  14.         android:layout_marginTop="16dp"
  15.         android:background="@drawable/stype"
  16.         android:overlapAnchor="false"
  17.         android:spinnerMode="dropdown" />
  18.     <LinearLayout
  19.         android:id="@+id/ll_xingming"
  20.         android:layout_width="match_parent"
  21.         android:layout_height="wrap_content"
  22.         android:layout_marginTop="180dp"
  23.         android:orientation="horizontal">
  24.         <TextView
  25.             android:layout_width="wrap_content"
  26.             android:layout_height="wrap_content"
  27.             android:text="姓名:"
  28.             android:textSize="20sp" />
  29.         <EditText
  30.             android:id="@+id/et_xingming"
  31.             android:layout_width="match_parent"
  32.             android:layout_height="wrap_content"
  33.             android:hint="必填"
  34.             android:inputType="text" />
  35.     </LinearLayout>
  36.     <LinearLayout
  37.         android:id="@+id/ll_dianziyoujian"
  38.         android:layout_width="match_parent"
  39.         android:layout_height="wrap_content"
  40.         android:layout_below="@+id/ll_dianhuahaoma"
  41.         android:orientation="horizontal">
  42.         <TextView
  43.             android:layout_width="wrap_content"
  44.             android:layout_height="wrap_content"
  45.             android:text="电子邮件:"
  46.             android:textSize="20sp" />
  47.         <EditText
  48.             android:id="@+id/et_dianziyoujian"
  49.             android:layout_width="match_parent"
  50.             android:layout_height="wrap_content"
  51.             android:inputType="text" />
  52.     </LinearLayout>
  53.     <LinearLayout
  54.         android:id="@+id/ll_beizhu"
  55.         android:layout_width="match_parent"
  56.         android:layout_height="wrap_content"
  57.         android:layout_below="@+id/ll_dianziyoujian"
  58.         android:orientation="horizontal">
  59.         <TextView
  60.             android:layout_width="wrap_content"
  61.             android:layout_height="wrap_content"
  62.             android:text="备注:"
  63.             android:textSize="20sp" />
  64.         <EditText
  65.             android:id="@+id/et_beizhu"
  66.             android:layout_width="match_parent"
  67.             android:layout_height="wrap_content"
  68.             android:inputType="text" />
  69.     </LinearLayout>
  70.     <LinearLayout
  71.         android:id="@+id/ll_dianhuahaoma"
  72.         android:layout_width="match_parent"
  73.         android:layout_height="wrap_content"
  74.         android:layout_below="@+id/ll_xingming"
  75.         android:orientation="horizontal">
  76.         <TextView
  77.             android:layout_width="wrap_content"
  78.             android:layout_height="wrap_content"
  79.             android:text="电话号码:"
  80.             android:textSize="20sp" />
  81.         <EditText
  82.             android:id="@+id/et_dianhuahaoma"
  83.             android:layout_width="match_parent"
  84.             android:layout_height="wrap_content"
  85.             android:hint="必填"
  86.             android:inputType="text" />
  87.     </LinearLayout>
  88.     <LinearLayout
  89.         android:id="@+id/ll_danweixinxi"
  90.         android:layout_width="match_parent"
  91.         android:layout_height="wrap_content"
  92.         android:layout_below="@+id/ll_beizhu"
  93.         android:orientation="horizontal">
  94.         <TextView
  95.             android:layout_width="wrap_content"
  96.             android:layout_height="wrap_content"
  97.             android:text="单位信息:"
  98.             android:textSize="20sp" />
  99.         <EditText
  100.             android:id="@+id/et_danweixinxi"
  101.             android:layout_width="match_parent"
  102.             android:layout_height="wrap_content"
  103.             android:inputType="text" />
  104.     </LinearLayout>
  105.     <ImageButton
  106.         android:id="@+id/ib_back"
  107.         android:layout_width="wrap_content"
  108.         android:layout_height="wrap_content"
  109.         android:background="#00FF0000"
  110.         android:src="@drawable/back" />
  111.     <Button
  112.         android:id="@+id/btn_tianjia"
  113.         android:layout_width="wrap_content"
  114.         android:layout_height="wrap_content"
  115.         android:layout_below="@+id/ll_danweixinxi"
  116.         android:layout_centerInParent="true"
  117.         android:text="保存" />
  118. </RelativeLayout>
复制代码
activity_contact_information.xml
  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.     android:gravity="center"
  7.     tools:context=".ContactInformationActivity">
  8.     <ImageButton
  9.         android:id="@+id/ib_detail_back"
  10.         android:layout_width="wrap_content"
  11.         android:layout_height="wrap_content"
  12.         android:layout_alignParentTop="true"
  13.         android:layout_marginTop="-40dp"
  14.         android:background="#00FF0000"
  15.         android:paddingLeft="10dp"
  16.         android:src="@drawable/back" />
  17.     <ImageView
  18.         android:id="@+id/iv_detail_touxiang"
  19.         android:layout_width="80dp"
  20.         android:layout_height="wrap_content"
  21.         android:layout_centerHorizontal="true"
  22.         android:layout_marginTop="50dp" />
  23.     <TextView
  24.         android:id="@+id/tv_datail_xingming"
  25.         android:layout_width="match_parent"
  26.         android:layout_height="wrap_content"
  27.         android:layout_below="@id/iv_detail_touxiang"
  28.         android:gravity="center"
  29.         android:text="姓名"
  30.         android:textSize="30sp" />
  31.     <TextView
  32.         android:id="@+id/tv_detail_dianhuahaoma"
  33.         android:layout_width="match_parent"
  34.         android:layout_height="wrap_content"
  35.         android:layout_below="@id/tv_datail_xingming"
  36.         android:gravity="center"
  37.         android:text="电话号码:12345667"
  38.         android:textSize="20sp" />
  39.     <TextView
  40.         android:id="@+id/tv_detail_dianziyoujian"
  41.         android:layout_width="match_parent"
  42.         android:layout_height="wrap_content"
  43.         android:layout_below="@id/tv_detail_dianhuahaoma"
  44.         android:gravity="center"
  45.         android:text="电子邮件:13445@qq.com"
  46.         android:textSize="20sp" />
  47.     <TextView
  48.         android:id="@+id/tv_detail_beizhu"
  49.         android:layout_width="match_parent"
  50.         android:layout_height="wrap_content"
  51.         android:layout_below="@id/tv_detail_dianziyoujian"
  52.         android:gravity="center"
  53.         android:text="备注:同学"
  54.         android:textSize="20sp" />
  55.     <TextView
  56.         android:id="@+id/tv_detail_danweixinxi"
  57.         android:layout_width="match_parent"
  58.         android:layout_height="wrap_content"
  59.         android:layout_below="@id/tv_detail_beizhu"
  60.         android:gravity="center"
  61.         android:text="单位信息:国企"
  62.         android:textSize="20sp" />
  63.     <LinearLayout
  64.         android:layout_width="match_parent"
  65.         android:layout_height="wrap_content"
  66.         android:layout_below="@id/tv_detail_danweixinxi"
  67.         android:orientation="vertical"
  68.         android:paddingLeft="10dp"
  69.         android:paddingRight="10dp">
  70.         <Button
  71.             android:id="@+id/btn_dadianhua"
  72.             android:layout_width="match_parent"
  73.             android:layout_height="wrap_content"
  74.             android:text="打电话" />
  75.         <Button
  76.             android:id="@+id/btn_faxiaoxi"
  77.             android:layout_width="match_parent"
  78.             android:layout_height="wrap_content"
  79.             android:text="发消息" />
  80.         <Button
  81.             android:id="@+id/btn_bianji"
  82.             android:layout_width="match_parent"
  83.             android:layout_height="wrap_content"
  84.             android:text="编辑" />
  85.         <Button
  86.             android:id="@+id/btn_shanchu"
  87.             android:layout_width="match_parent"
  88.             android:layout_height="wrap_content"
  89.             android:text="删除" />
  90.     </LinearLayout>
  91. </RelativeLayout>
复制代码
activity_main.xml
  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.     android:orientation="vertical"
  7.     tools:context=".MainActivity">
  8.     <EditText
  9.         android:id="@+id/et_sousuo"
  10.         android:layout_width="match_parent"
  11.         android:layout_height="wrap_content"
  12.         android:layout_marginLeft="5dp"
  13.         android:layout_marginTop="10dp"
  14.         android:layout_marginRight="5dp"
  15.         android:background="@drawable/sou_suo_kuang"
  16.         android:drawableLeft="@drawable/sousuo"
  17.         android:textColor="#4D4F60"
  18.         android:textSize="30sp" />
  19.     <ListView
  20.         android:id="@+id/lv_lianxiren"
  21.         android:layout_width="match_parent"
  22.         android:layout_height="wrap_content"
  23.         android:layout_below="@id/et_sousuo"
  24.         android:layout_weight="1" />
  25.     <ImageButton
  26.         android:id="@+id/ib_tianjialianxiren"
  27.         android:layout_width="wrap_content"
  28.         android:layout_height="wrap_content"
  29.         android:layout_alignParentRight="true"
  30.         android:layout_alignParentBottom="true"
  31.         android:layout_marginRight="20dp"
  32.         android:layout_marginBottom="80dp"
  33.         android:background="#00FF0000"
  34.         android:src="@drawable/add" />
  35. </RelativeLayout>
复制代码
lian_xi_ren_bu_ju.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="wrap_content"
  5.     android:orientation="vertical">
  6.     <TextView
  7.         android:id="@+id/tv_zimu"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="wrap_content"
  10.         android:paddingLeft="20dp"
  11.         android:text="A"
  12.         android:textSize="30sp" />
  13.     <LinearLayout
  14.         android:layout_width="match_parent"
  15.         android:layout_height="wrap_content"
  16.         android:orientation="horizontal"
  17.         android:padding="10dp">
  18.         <ImageView
  19.             android:id="@+id/iv_touxiang"
  20.             android:layout_width="80dp"
  21.             android:layout_height="80dp"
  22.             android:src="@color/black" />
  23.         <TextView
  24.             android:id="@+id/tv_xingming"
  25.             android:layout_width="match_parent"
  26.             android:layout_height="wrap_content"
  27.             android:paddingLeft="10dp"
  28.             android:paddingTop="4dp"
  29.             android:textSize="50sp" />
  30.     </LinearLayout>
  31. </LinearLayout>
复制代码
spinner_item.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="wrap_content"
  5.     android:gravity="center_vertical"
  6.     android:orientation="horizontal">
  7.     <ImageView
  8.         android:id="@+id/imageView"
  9.         android:layout_width="120dp"
  10.         android:layout_height="120dp"
  11.         android:layout_margin="8dp" />
  12. </LinearLayout>
复制代码
AndroidManifest.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.     package="com.example.theseventhexperiment">
  4.     <uses-permission android:name="android.permission.CALL_PHONE"/>
  5.     <uses-permission android:name="android.permission.SEND_SMS"/>
  6.     <application
  7.         android:allowBackup="true"
  8.         android:icon="@mipmap/ic_launcher"
  9.         android:label="@string/app_name"
  10.         android:roundIcon="@mipmap/ic_launcher_round"
  11.         android:supportsRtl="true"
  12.         android:theme="@style/Theme.TheSeventhExperiment">
  13.         <activity android:name=".ContactInformationActivity"></activity>
  14.         <activity android:name=".AddContactActivity" />
  15.         <activity android:name=".MainActivity">
  16.             <intent-filter>
  17.                 <action android:name="android.intent.action.MAIN" />
  18.                 <category android:name="android.intent.category.LAUNCHER" />
  19.             </intent-filter>
  20.         </activity>
  21.     </application>
  22. </manifest>
复制代码
干系操纵:
switch语句报错:https://blog.csdn.net/mjh1667002013/article/details/134763804
办理Android虚拟机启动时System UI isn‘t responding错误_system ui isn't responding-CSDN博客
汉语言处理处罚包HanLP下载地址:Maven Repository: com.hankcs » hanlp » portable-1.8.4 (mvnrepository.com)
导入jar包教程(假如没有libs文件夹就创建一个):
https://blog.csdn.net/weixin_46409629/article/details/129414986?app_version=6.2.8&code=app_1562916241&csdn_share_tail=%7B%22

项目存在的问题:
1.spinner下拉图标(白色的,所以看不见)遮挡图片问题,如下图,为了美观没有使用填满颜色图片,spinner的设置在stype.xml文件内,必要再设计.

 2.数据库有时报错:
Database Inspector:

Error reading Sqlite database: Database 'LiveSqliteDatabaseId(path=/data/data/com.example.theseventhexperiment/databases/contact_db.db, name=contact_db.db, connectionId=1) not found

但是项目仍可正常运行,推测是版本问题或者数据库没有及时断开毗连
3.运行卡顿问题,代码待优化
工程文件:
通过网盘分享的文件:TheSeventhExperiment.zip
链接: https://pan.baidu.com/s/1gLrwrdai95-mHhRDfBieXw?pwd=h42a提取码: h42a
gitee:android studio: 移动应用开发实验代码




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

何小豆儿在此

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表