20212325 2023-2024-2 《移动平台开发与实践》综合实践

20212325 2023-2024-2 《移动平台开发与实践》综合实践

1.综合实践内容

  • 实现学生信息管理系统:
    1. 学生信息管理系统的用户登录信息MD5加密匹配, SharedPreferences 实现自动登录;
    2. 使用android studio内置SQLite数据库,能够进行学生信息的增、删、查、改;
    3. UI界面完善简洁,一目了然,函数调用逻辑清晰完整。

2.实践过程

2.1数据库设计
  • 学生信息表:

    字段数据类型主键外键是否为空说明
    numbervarchar学号
    namevarchar姓名
    Yearvarchar年龄
    Sexvarchar性别
    Birthvarchar出生日期
    Addressvarchar住址
    Phonevarchar电话
2.2总体调用逻辑
  • image-20240617163128484
2.3与UI的对应关系
  • 截屏2024-06-17 16.31.51

    确定了需要的UI界面后先写前端的UI界面代码。

2.4编写UI界面
  • 登录界面activity_login

    截屏2024-06-16 14.47.27

  • 登录加载界面activity_begin(在登录后出现学生信息系统图标模仿app加载)

    截屏2024-06-16 14.51.34

  • 系统欢迎&功能选择界面activity_main

    截屏2024-06-16 14.56.20

  • 学生信息录入界面activity_add_students

    截屏2024-06-17 16.30.44

  • 学生信息浏览界面activity_search_students

    截屏2024-06-16 14.57.33

  • 学生信息修改界面activity_mod_students

    截屏2024-06-16 14.57.54

  • 学生信息检索查询界面activity_query_students

    截屏2024-06-16 14.58.20

  • 学生信息删除界面activity_delete_students

    截屏2024-06-16 14.58.45

2.5代码编写逻辑
2.5.1用户登录
  • etNameetPwd 两个文本控件用来输入用户名和密码:

    etName = findViewById(R.id.et_name);
    etPwd = findViewById(R.id.et_pwd);
    
  • 用户点击btnLogin 后触发登录操作:

    btnLogin = findViewById(R.id.btn_login);
    
  • 初次登录需要完整填写用户密码,这里我使用了md5加密来验证密码:

    if (name.equals("admin") && (MD5Utils.code(pwd)).equals(MD5Utils.code("20212325"))) {
      Toast.makeText(LoginActivity.this, "登录成功",
                     Toast.LENGTH_SHORT).show();
    

    新建MD5Utils类用于实现32位md5加密,将预设密码(20212325)的md5值和用户输入密码的md5值比对,比对成功则登录成功。

  • 我在这里还使用了 CheckBox 控件,用于选择是否记住用户名和密码,选择记住就会将用户名和密码存储到 SharedPreferences

    if (cb.isChecked()) {
                        editor.putString("cb_name", name);
                        editor.putString("cb_pwd", pwd);
                        editor.putBoolean("cb_checked", true);
    }
    

    如果没有勾选,则更新 SharedPreferences 不记住登录状态:

    else {
                        editor.putBoolean("cb_checked", false);
                    }
    
  • 实现自动登录:

    之前的课上我们学过SharedPreferences用法,目前只有MODE_PRIVATE一种模式能使用

    这里SharedPreferences从“zidong”文件中读取记住的用户名和密码。

     sp = getSharedPreferences("zidong", Context.MODE_PRIVATE);
            aBoolean = sp.getBoolean("cb_checked", false);
            if (aBoolean) {
                Intent intent = new Intent(LoginActivity.this, BeginActivity.class);
                startActivity(intent);
                finish();
            }
    

    通过 aBoolean = sp.getBoolean("cb_checked", false); 判断用户之前是否选择了记住登录状态,如果 aBooleantrue,则直接跳转到 BeginActivity,实现自动登录。

2.5.2登录加载
  • 在登录成功之后我想模仿app的加载界面,主要使用了Timer和TimerTask进行延时跳转

    Timer timer=new Timer();
            TimerTask task=new TimerTask() {
                @Override
                public void run() {
                    Intent intent=new Intent(BeginActivity.this,MainActivity.class);
                    startActivity(intent);
                    finish();
                }
            };
    timer.schedule(task,3000);
    

    这里的3000毫秒就是显示启动画面后,等待3秒,然后自动跳转到主界面。

2.5.3系统欢迎和功能选择界面
  • 这一页为系统的中心界面,监听不同的按钮点击事件,提供登录后所有操作的入口并进行相应跳转。

        public void onClick(View v) {
            int id=v.getId();
            if(id==R.id.add_students){
                Intent intent1=new Intent(MainActivity.this,AddStudentsActivity.class);
                startActivity(intent1);
            } else if (id== R.id.search_students) {
                Intent intent2=new Intent(MainActivity.this,SearchStudentsActivity.class);
                startActivity(intent2);
            } else if (id== R.id.mod_students) {
                Intent intent3=new Intent(MainActivity.this,ModStudentsActivity.class);
                startActivity(intent3);
            } else if (id== R.id.query_students) {
                Intent intent4=new Intent(MainActivity.this,QueryStudentsActivity.class);
                startActivity(intent4);
            } else if (id==R.id.delete_students) {
                Intent intent5=new Intent(MainActivity.this,DeleteStudentsActivity.class);
                startActivity(intent5);
            } else if (id== R.id.btn_back) {
                DigLogShow();
            }
        }
    /**
    
  • 另外本页还可以退出登录,用户点击退出时就清空在登录时写入“zidong”文件的登录信息,并跳回登录界面

    private void DigLogShow() {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("退出提示")
                    .setMessage("是否退出?")
                    .setPositiveButton("否", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    })
                    .setNegativeButton("是", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent intent6=new Intent(MainActivity.this,LoginActivity.class);
                            SharedPreferences sharedPreferences = getSharedPreferences("zidong", Context.MODE_PRIVATE);
                            sharedPreferences.edit().clear().apply();
                            Toast.makeText(MainActivity.this,"退出成功!",Toast.LENGTH_LONG).show();
                            startActivity(intent6);
                        }
                    });
            builder.create().show();
        }
    
2.5.4学生信息浏览、添加、修改、删除、查找
  1. 学生信息浏览

点击学生信息浏览功能后加载数据,因为学生信息以列表ListView形式呈现,为了将学生信息数据和ListView绑定,这里用到了适配器,使用适配器绑定控件和学生信息之后学生信息便可以动态更新,以便屏幕上的信息可滚动呈现。

mData = new ArrayList<>();
System.out.println("长度为:" + mData.size());//设置适配器:加载每一行数据到列表当中
adapter = new Adapter(this, mData);
listView.setAdapter(adapter);
loadData();//显示学生信息列表函数

之后便可以动态更新

private void loadData() {
      List<StudentsBean> list = DbStudents.search();
      mData.clear();
      mData.addAll(list);
      adapter.notifyDataSetChanged();//实时更新
  }

适配器adapter的代码逻辑,先定义变量并初始化:

  • context 用于获取当前环境的引用。
  • mData 列表,存储我们要显示的数据对象 StudentsBean
  • inflater 用于将XML布局转换为视图对象。
Context context;
List<StudentsBean> mData;
LayoutInflater inflater;
public Adapter(Context context, List<StudentsBean> mData) {
      this.context = context;
      this.mData = mData;
      inflater = LayoutInflater.from(context);
  }

返回需要的各类数据,重写getview方法,返回视图

public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder holder = null;
      if (convertView == null) {
          convertView = inflater.inflate(R.layout.item_students, parent, false);
          holder = new ViewHolder(convertView);
          convertView.setTag(holder);
      } else {
          holder = (ViewHolder) convertView.getTag();
      }
      StudentsBean bean=mData.get(position);
      holder.TvNumber.setText("学号:"+bean.getNumber());
      holder.TvName.setText("姓名:"+bean.getName());
      holder.TvYear.setText("年龄:"+bean.getYear());
      holder.TvSex.setText("性别:"+bean.getSex());
      holder.TvBirth.setText("生日:"+bean.getBirth());
      holder.TvAddress.setText("地址:"+bean.getAddress());
      holder.TvPhone.setText("电话:"+bean.getPhone());
      return convertView;
  }

使用ViewHolder存储对于列表项的引用,可以避免在每次 getView 调用时重复调用 findViewById,可以大大提高性能。

  class ViewHolder {
      TextView TvNumber,TvName, TvYear, TvSex, TvBirth,TvAddress,TvPhone;

      public ViewHolder(View view) {
          TvNumber= view.findViewById(R.id.tv_number);
          TvName = view.findViewById(R.id.tv_name);
          TvYear = view.findViewById(R.id.tv_year);
          TvSex = view.findViewById(R.id.tv_sex);
          TvBirth = view.findViewById(R.id.tv_birth);
          TvAddress = view.findViewById(R.id.tv_address);
          TvPhone = view.findViewById(R.id.tv_phone);

      }
  }
  1. 学生信息添加、修改

    在编写代码时一开始想把修改和添加编写到一起,后面发现使用一个页面非常乱,于是又添加了一个修改的搜索页面,只是在AddStudentActivity中根据intent中 getStringExtra 方法获取的 number 是否为空判断是否为修改操作

private void initData() {
      Intent intent = getIntent();
      if (intent != null) {
          number = intent.getStringExtra("number");
          if (number != null) {
              tv_title.setText("修改学生信息");
              BtnSave.setText("修  改");
              EtNumber.setText(intent.getStringExtra("number"));
              EtName.setText(intent.getStringExtra("name"));
              EtYear.setText(intent.getStringExtra("year"));
              EtSex.setText(intent.getStringExtra("sex"));
              EtBirth.setText(intent.getStringExtra("birth"));
              EtAddress.setText(intent.getStringExtra("address"));
              EtPhone.setText(intent.getStringExtra("phone"));
          }
      }
  }

number 为null则保持默认界面,默认为添加操作

if(id==R.id.btn_back) {
                Intent intent1 = new Intent(AddStudentsActivity.this, MainActivity.class);
                startActivity(intent1);
            } else if (id== R.id.btn_save) {
                //输入
                String number = EtNumber.getText().toString().trim();
                String name = EtName.getText().toString().trim();
                String year = EtYear.getText().toString().trim();
                String sex = EtSex.getText().toString().trim();
                String birth = EtBirth.getText().toString().trim();
                String address = EtAddress.getText().toString().trim();
                String phone = EtPhone.getText().toString().trim();
                StudentsBean studentsBeans = dbStudents.QueryFromStudentByNumber(number);

添加成功提示框:

private void showDeleteDialog() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("录入成功提示")
                .setMessage("已成功录入!\n是否继续?")
                .setPositiveButton("否", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent=new Intent(AddStudentsActivity.this,MainActivity.class);
                        startActivity(intent);
                    }
                })
                .setNegativeButton("是", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //将输入框清空
                        EtNumber.setText("");
                        EtName.setText("");
                        EtYear.setText("");
                        EtSex.setText("");
                        EtBirth.setText("");
                        EtAddress.setText("");
                        EtPhone.setText("");
                    }
                });
        builder.create().show();
    }

number 不为null界面标题 (tv_title) 设置为 "修改学生信息",保存按钮 (BtnSave) 的文本设置为 "修 改"。使用从 Intent 中获取的其他额外信息填充界面上剩余的 EditText 控件,包括学号、姓名、年龄、性别、出生日期、地址和电话。

if (number != null) {//修改操作
                    if (name.length() > 0) {
                        if (dbStudents.updateStudent(number, name, year,sex,birth,address,phone)) {
                            Toast.makeText(AddStudentsActivity.this,"修改成功",Toast.LENGTH_LONG).show();
                            setResult(2);
                            showDeleteDialog2();
                        }
                    } else {
                        Toast.makeText(AddStudentsActivity.this,"修改的内容不能为空!",Toast.LENGTH_LONG).show();
                    }

                }

修改成功提示框:

private void showDeleteDialog2() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("修改成功提示")
                .setMessage("已成功修改!")
                .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent=new Intent(AddStudentsActivity.this,MainActivity.class);
                        startActivity(intent);
                    }
                });
        builder.create().show();
    }

下面为内部调用图:
截屏2024-06-17 16.32.36

  1. 学生信息删除

点击删除功能后,要先显示出目前数据库中已有的学生信息数据,然后我想的是长按进行删除。

先加载学生信息数据:

private void loadData() {
    List<StudentsBean> list = DbStudents.search();
    mData.clear();
    mData.addAll(list);
    adapter.notifyDataSetChanged();
}

然后设置长按时间监听器setLVClickListener ,当用户长按列表项时,调用 deleteItem 方法进行删除操作:

private void setLVClickListener() {
    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            StudentsBean studentsBean = mData.get(position);
            deleteItem(studentsBean);
            return false;
        }
    });
}

deleteItem 方法显示一个对话框,让用户确认是否删除选中的学生记录。如果用户确认,就调用 DbStudents 类的 deleteItemFromStudentByNumber 方法从数据库中删除记录,并从数据源 mData 中移除对应的 StudentsBean 对象,然后实时通知适配器更新界面:

private void deleteItem(final StudentsBean studentsBean) {
    //弹出对话框确认删除操作
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("提示信息").setMessage("您确定要删除这条记录么?")
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    DbStudents.deleteItemFromStudentByNumber(studentsBean.getNumber());
                    mData.remove(studentsBean);//实时刷新,从数据源删除
                    adapter.notifyDataSetChanged();
                }
            });
    builder.create().show();
}
  1. 学生信息查找

同学生信息浏览一样,查找与其非常类似,所以为了更方便地将学生信息和ListView动态绑定,这里也采用适配器,创建好 Adapter 适配器实例并将其设置给 ListView。同时绑定 ListViewEditText 控件,初始化 mData,创建 DbStudents 数据库操作类的实例

QueryLv = findViewById(R.id.query_lv);
EtName = findViewById(R.id.et_name);
EtNumber = findViewById(R.id.et_number);
mData = new ArrayList<>();
adapter = new Adapter(this, mData);
QueryLv.setAdapter(adapter);
dbStudents = new DbStudents(this);

实现 View.OnClickListener 接口的 onClick 方法,处理按钮点击事件

@Override
public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.iv_back) {
        // 处理返回按钮点击事件
    } else if (id == R.id.iv_query) {
        // 处理查询按钮点击事件
    }
}

当用户点击返回按钮时,创建一个新的 Intent 跳转到 MainActivity 并完成当前 QueryStudentsActivity

if (id == R.id.iv_back) {
    Intent intent = new Intent(QueryStudentsActivity.this, MainActivity.class);
    startActivity(intent);
    finish();
}

当用户点击查询按钮时,获取 EditText 中输入的学号和姓名,验证输入是否有效。如果输入有效,调用 DbStudents 类的 getStudentListByNumberAndName 方法执行查询,获取查询结果列表,更新 mData,并通知适配器数据已更改,之后更新 ListView 显示。查询成功后就清空原有数据,将查询结果添加到 mData 中,并调用适配器的 notifyDataSetChanged 方法来刷新 ListView 显示新的学生信息列表。

else if (id == R.id.iv_query) {
    String number = EtNumber.getText().toString().trim();
    String name = EtName.getText().toString().trim();
    if (TextUtils.isEmpty(number) || TextUtils.isEmpty(name)) {
        // 检查输入是否为空,并提示用户
    } else {
        // 执行查询操作
        List<StudentsBean> list = DbStudents.getStudentListByNumberAndName(number, name);
        mData.clear();
        mData.addAll(list);
        adapter.notifyDataSetChanged();
    }
}
2.5.5数据库交互操作

数据库的操作非常简单,在数据库文件中写好创建库、增、删、查、改的相关代码:

public class DbStudents extends SQLiteOpenHelper {
    private static SQLiteDatabase db;
    public DbStudents(@Nullable Context context) {
        super(context, "birth.db", null, 1);
        System.out.println("数据库创建成功");
        db = getReadableDatabase();
    }

    public static List<StudentsBean> getStudentListByNumberAndName(String number , String name) {
        List<StudentsBean> list = new ArrayList<>();
        String sql = "select * from student where number like '%" + number + "%' and name like '%" + name + "%'";
        Cursor cursor = db.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            @SuppressLint("Range") int id = cursor.getInt(cursor.getColumnIndex("id"));
            @SuppressLint("Range") String number1 = cursor.getString(cursor.getColumnIndex("number"));
            @SuppressLint("Range") String name1 = cursor.getString(cursor.getColumnIndex("name"));
            @SuppressLint("Range") String year = cursor.getString(cursor.getColumnIndex("year"));
            @SuppressLint("Range") String sex = cursor.getString(cursor.getColumnIndex("sex"));
            @SuppressLint("Range") String birth = cursor.getString(cursor.getColumnIndex("birth"));
            @SuppressLint("Range") String address = cursor.getString(cursor.getColumnIndex("address"));
            @SuppressLint("Range") String phone = cursor.getString(cursor.getColumnIndex("phone"));
            StudentsBean studentsBean = new StudentsBean(id,number1, name1,year, sex,birth,address,phone);
            list.add(studentsBean);
        }
        return list;
    }

    public static List<StudentsBean> getStudentListByNumber(String number) {
        List<StudentsBean> list = new ArrayList<>();
        String sql = "select * from student where number="+number;
        Cursor cursor = db.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            @SuppressLint("Range") int id = cursor.getInt(cursor.getColumnIndex("id"));
            @SuppressLint("Range") String number1 = cursor.getString(cursor.getColumnIndex("number"));
            @SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex("name"));
            @SuppressLint("Range") String year = cursor.getString(cursor.getColumnIndex("year"));
            @SuppressLint("Range") String sex = cursor.getString(cursor.getColumnIndex("sex"));
            @SuppressLint("Range") String birth = cursor.getString(cursor.getColumnIndex("birth"));
            @SuppressLint("Range") String address = cursor.getString(cursor.getColumnIndex("address"));
            @SuppressLint("Range") String phone = cursor.getString(cursor.getColumnIndex("phone"));
            StudentsBean studentsBean = new StudentsBean(id,number1, name,year, sex,birth,address,phone);
            list.add(studentsBean);
        }
        return list;
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = ("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT," +
                "number VARCHAR(50) not null," +
                "name VARCHAR(20) not null," +
                "year VARCHAR(2) not null," +
                "sex VARCHAR(2) not null," +
                "birth varchar(60) not null," +
                "address Varchar(60) not null," +
                "phone VARCHAR(11) not null)");

        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists student");
        onCreate(db);
    }
    public void insertStudents(String number,String name, String year, String sex, String birth,
                            String address,String phone) {
        db.execSQL("INSERT INTO student(number,name,year,sex,birth,address,phone)VALUES(?,?,?,?,?,?,?)",
                new String[]{number,name,year,sex, birth,address,phone});
    }
    /**
     * 浏览
     * */
    public static List<StudentsBean> search() {
        List<StudentsBean> list = new ArrayList<>();
        String sql = "select * from student order by number";
        Cursor cursor = db.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            @SuppressLint("Range") int id = cursor.getInt(cursor.getColumnIndex("id"));
            @SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndex("number"));
            @SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex("name"));
            @SuppressLint("Range") String year = cursor.getString(cursor.getColumnIndex("year"));
            @SuppressLint("Range") String sex = cursor.getString(cursor.getColumnIndex("sex"));
            @SuppressLint("Range") String birth = cursor.getString(cursor.getColumnIndex("birth"));
            @SuppressLint("Range") String address = cursor.getString(cursor.getColumnIndex("address"));
            @SuppressLint("Range") String phone = cursor.getString(cursor.getColumnIndex("phone"));
            StudentsBean studentsBean = new StudentsBean(id,number, name,year, sex,birth,address,phone);
            list.add(studentsBean);
        }
        return list;
    }
    public static int deleteItemFromStudentByNumber(String number) {
        int i = db.delete("student", "number=?", new String[]{number + ""});
        return i;
    }
/**
 * 查询学号是否存在
 * */
    public static StudentsBean QueryFromStudentByNumber(String number) {
      //  List<StudentsBean> list = new ArrayList<>();
        StudentsBean studentsBean = null;
        String sql = "select * from student where number ="+number;
        Cursor cursor = db.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            @SuppressLint("Range") int id = cursor.getInt(cursor.getColumnIndex("id"));
            @SuppressLint("Range") String number1 = cursor.getString(cursor.getColumnIndex("number"));
            @SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex("name"));
            @SuppressLint("Range") String year = cursor.getString(cursor.getColumnIndex("year"));
            @SuppressLint("Range") String sex = cursor.getString(cursor.getColumnIndex("sex"));
            @SuppressLint("Range") String birth = cursor.getString(cursor.getColumnIndex("birth"));
            @SuppressLint("Range") String address = cursor.getString(cursor.getColumnIndex("address"));
            @SuppressLint("Range") String phone = cursor.getString(cursor.getColumnIndex("phone"));
            studentsBean = new StudentsBean(id, number1, name, year, sex, birth, address, phone);
        //    list.add(studentsBean);
        }
        return studentsBean;
    }
    //修改数据
    public boolean updateStudent(String number,String name,String year,String sex,String birth,String address,String phone){
        ContentValues contentValues=new ContentValues();
        contentValues.put("name",name);
        contentValues.put("year",year);
        contentValues.put("sex",sex);
        contentValues.put("birth",birth);
        contentValues.put("address",address);
        contentValues.put("phone",phone);
        String sql="number"+"=?";
        String[] strings=new String[]{number};
        return
                db.update("student",contentValues,sql,strings)>0;
    }
}
2.6程序运行视频

学生信息系统

3.学习中遇到的问题及解决

  • 问题1:将学生信息录入和修改的代码合并在一个java文件后前端无法识别是录入还是修改操作,但是二者实际操作类似,把代码拆开成两个java则赘余

  • 问题1解决方案:单独写一个学生信息修改的跳转界面,在该界面用户搜索要修改的学生学号,点击该学生信息后,跳转到修改/录入界面,根据intent中GetStringExtra获取传入的学号,有学号信息这说明为修改操作,对应页面也进行修改。

    截屏2024-06-17 10.58.15

  • 问题2:在后台线程中更新组件引起截屏2024-05-06 20.39.49

  • 问题2解决方案:使用 runOnUiThread() 方法将UI更新操作切换回主线程执行

  • 问题3:适配器与数据绑定后ListView显示还是空的

  • 问题3解决方案:在学生信息录入、更新、删除后调用适配器的 notifyDataSetChanged() 方法

  • 问题4:滑动列表有一些卡顿

  • 问题4解决方法:使用ViewHolder模式来缓存视图,确保每个列表项的视图只被创建一次,避免在每次调用时进行复杂的布局操作或重复的视图创建。因为学生信息列表项的布局中包含图片,所以在 getView() 中,就只更新变化的部分,不用每次更新整个视图。

4.综合实践学习感悟

  • 本次开发过程中,我对Android中的适配器和Intent机制有了更深入的理解和实践。适配器模式在Android中扮演着至关重要的角色,作为数据和视图之间的桥梁,负责将数据源中的数据展示到用户界面上。适配器不仅填充ListView,通过复用视图提高性能,并动态展示学生信息列表。

  • 编写适配器时,在getView()方法中,本次采用了ViewHolder模式来优化列表的滚动性能,通过缓存视图引用避免重复调用findViewById(),这样就可以减少内存分配和提高滚动灵敏度,可见适配器的灵活性。其他视图组件比如GridView和RecyclerView也能跟其搭配使用。

    在上第二节课的时候,我们就知道Intent机制是Android组件间通信的基石。使用Intent主要是在不同的Activity之间传递数据和请求、启动新的Activity、比如从主界面跳转到添加学生信息的界面,或者从查询结果跳转到修改学生信息的界面。在进行学生信息修改和录入时我也是通过Intent携带的额外数据学号来区分用户选择的操作类型,最终通过getIntent().getStringExtra()方法获取后对应地进行页面修改。以及还有使用Intent进行结果的回传。在添加或修改学生信息后,我是通过设置结果码setResult()和Intent,然后将结果传递回发起请求的Activity,接着进行进一步的刷新界面或显示提示信息。

5.课程总结

随着这段丰富而充实的学习旅程渐渐落下帷幕,我心中充满了感激与收获。王老师的课程讲解深入浅出,为我们打开了Android开发的大门。一学期以来,我不仅系统地掌握了从基础语法到应用的各方位知识,更在实践中深化了对技术的理解与应用。

课程内容涵盖了Android开发的多个方面,从界面布局的精细打磨到UI组件的灵活运用,从资源管理与权限控制的必要知识到四大组件的深入理解,再到数据存储和网络编程的实用技巧,以及多媒体功能的集成应用。这一系列的知识点,通过王老师条理清晰的讲解和精心设计的实验内容,变得生动而易于掌握。

课程中王老师给我们推荐了《第一行代码:Android》这本书,书籍内容也是对课程内容很好的补充,由浅入深,整体很全面,从最基本的四大组件到MVVM模式、异步、协程等,有着大量Kotlin的介绍,都是一些比较使用的编码技巧,实践参考性比较强,上课的时候没怎么听懂的在书中大部分也能找到答案。

最后对王老师的耐心指导表示最诚挚的感谢。也感谢和我一起学习的同学们的一路陪伴,这是我本科阶段最后的课业学习,我所学到的知识和技能,我所遇到的bug踩到的坑,与老师和同学们共度的时光,与代码互相折磨的时刻,我都将永远珍惜。

参考资料

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值