【android】安卓大作业「课程日历」

发布时间:2024年01月06日

项目要求

项目: 课程日历
-项目概况: 项目记录一周的课程信息。
?用户可以编辑周一~周五的课程表(每天最多安排5门课程) ;
?用户可以按日查看课程表。
-项目要求:
?项目包含2个活动及其对应的布局:
① 显示课程活动:单击“周一”~“周五”按钮中的一个,按时间顺序显示当日的课程信息(上课时间、课程名称、教室);单击“编辑”按钮,进入下一个活动;
② 编辑课程活动:针对选定的周几,可以新增、修改或删除当日的课程。编辑完毕后,用户单击“保存”按钮则更新当日课程表,或单击“撤销”按钮取消刚才的编辑操作,或单击“返回”按钮,回到显示课程活动。
?布局设计:
① 显示课程活动布局:选用合适的视图控件显示课程信息;
② 编辑课程活动布局:选用恰当的视图控件提供课程编辑方式。
?功能设计:
① 能完成活动之间的跳转;
② 用数据库、数据表存储课程信息;
③ 能编辑和查询单日课程信息。


项目流程图

在这里插入图片描述


结果展示

原始界面:
在这里插入图片描述?

点击周一按钮后界面:(其余周数就不进行展示了,差不多)
在这里插入图片描述

选中周数后点击编辑按钮:
在这里插入图片描述

没有选中周数就点击编辑按钮出现的提示Toast:
在这里插入图片描述

输入相关课程信息后点击新增按钮:
在这里插入图片描述

在新增后点击撤销按钮:
在这里插入图片描述

在之前没有编辑操作或者已经撤销一次之后再次点击撤销会弹出提示:
在这里插入图片描述

三个editview如果有一个为空时点击新增按钮会出现的提示:
在这里插入图片描述

一天内课程数为5再点击新建:
在这里插入图片描述

点击listview中的课程会进行提示:
在这里插入图片描述

在选中课程之后点击删除按钮:
在这里插入图片描述

在删除操作后点击撤销按钮:
在这里插入图片描述

在没有选中课程就点击删除按钮出现的提示:
在这里插入图片描述

在选中第一个课程后并且在输入框中输入新的时间以及教室后点击保存按钮:
在这里插入图片描述

在保存之后点击撤销按钮:
在这里插入图片描述

点击返回按钮:
在这里插入图片描述

UI设计

在MainActivity中有使用六个按钮,分别对应的是周一,周二,周三,周四,周五和返回。在下方还有一个listview,用来显示查询出来的课程信息。
listView对应的layout使用的也是相对布局,包含三个TextView,用来分别显示课程的名称,时间以及上课教室。
EditActivity里面包含一个listview,用来显示查询出来的课程信息以及供用户进行选中,五个按钮,分别对应的是新增,删除,保存,撤销以及返回,还有一个textview用来对用户进行提示,3个EditText用来读取需要编辑的课程信息。
MainActivity:
在这里插入图片描述

EditActivity:
在这里插入图片描述

Listview的layout:

在这里插入图片描述

activity_main.xml代码

<?xml?version="1.0"?encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????xmlns:app="http://schemas.android.com/apk/res-auto"
????xmlns:tools="http://schemas.android.com/tools"
????android:layout_width="match_parent"
????android:layout_height="match_parent"
????tools:context=".MainActivity">

????<Button
????????android:id="@+id/button3"
????????android:layout_width="79dp"
????????android:layout_height="54dp"
????????android:text="周三"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.524"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.048"?/>

????<Button
????????android:id="@+id/button4"
????????android:layout_width="79dp"
????????android:layout_height="54dp"
????????android:text="周四"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.762"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.048"?/>

????<Button
????????android:id="@+id/button2"
????????android:layout_width="79dp"
????????android:layout_height="54dp"
????????android:text="周二"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.286"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.048"?/>

????<Button
????????android:id="@+id/button1"
????????android:layout_width="79dp"
????????android:layout_height="54dp"
????????android:text="周一"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.048"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.048"?/>

????<Button
????????android:id="@+id/button5"
????????android:layout_width="79dp"
????????android:layout_height="54dp"
????????android:text="周五"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.996"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.048"?/>

????<ListView
????????android:id="@+id/list1"
????????android:layout_width="413dp"
????????android:layout_height="367dp"
????????android:layout_marginTop="104dp"
????????app:layout_constraintTop_toTopOf="parent"
????????tools:layout_editor_absoluteX="-1dp"?/>

????<Button
????????android:id="@+id/buttonEdit"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:text="编辑"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.498"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.953"?/></androidx.constraintlayout.widget.ConstraintLayout>12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394

activity_edit.xml代码

<?xml?version="1.0"?encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????xmlns:app="http://schemas.android.com/apk/res-auto"
????xmlns:tools="http://schemas.android.com/tools"
????android:layout_width="match_parent"
????android:layout_height="match_parent"
????tools:context=".EditActivity">

????<TextView
????????android:id="@+id/textView3"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:text="时间:"
????????android:textSize="24sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.233"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.615"?/>

????<Button
????????android:id="@+id/buttonDelete"
????????android:layout_width="103dp"
????????android:layout_height="57dp"
????????android:text="删除"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.334"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.905"?/>

????<Button
????????android:id="@+id/buttonZ"
????????android:layout_width="103dp"
????????android:layout_height="57dp"
????????android:text="撤销"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="1.0"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.905"?/>

????<Button
????????android:id="@+id/buttonAdd"
????????android:layout_width="103dp"
????????android:layout_height="57dp"
????????android:text="新增"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.0"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.905"?/>

????<Button
????????android:id="@+id/buttonSave"
????????android:layout_width="103dp"
????????android:layout_height="57dp"
????????android:text="保存"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.668"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.905"?/>

????<ListView
????????android:id="@+id/list2"
????????android:layout_width="411dp"
????????android:layout_height="282dp"
????????tools:layout_editor_absoluteX="0dp"
????????tools:layout_editor_absoluteY="0dp"?/>

????<TextView
????????android:id="@+id/textView"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:text="如需修改,请先选中其中一节课"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="@+id/list2"
????????app:layout_constraintVertical_bias="0.802"?/>

????<EditText
????????android:id="@+id/editTextTime"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:ems="10"
????????android:inputType="textPersonName"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.781"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="@+id/list2"
????????app:layout_constraintVertical_bias="0.607"?/>

????<EditText
????????android:id="@+id/editTextName"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:ems="10"
????????android:inputType="textPersonName"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.781"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.507"?/>

????<EditText
????????android:id="@+id/editTextRoom"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:ems="10"
????????android:inputType="textPersonName"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.786"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="@+id/list2"
????????app:layout_constraintVertical_bias="0.699"?/>

????<TextView
????????android:id="@+id/textView4"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:text="教室:"
????????android:textSize="24sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.233"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.705"?/>

????<TextView
????????android:id="@+id/textView2"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:text="课程名:"
????????android:textSize="24sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.174"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.516"?/>

????<Button
????????android:id="@+id/buttonBack"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:text="返回"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.498"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.992"?/></androidx.constraintlayout.widget.ConstraintLayout>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166

activity_class.xml代码

<?xml?version="1.0"?encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????xmlns:app="http://schemas.android.com/apk/res-auto"
????xmlns:tools="http://schemas.android.com/tools"
????android:layout_width="match_parent"
????android:layout_height="match_parent">

????<TextView
????????android:id="@+id/textViewName"
????????android:layout_width="151dp"
????????android:layout_height="58dp"
????????android:text="TextView"
????????android:textSize="20sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.026"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.021"?/>

????<TextView
????????android:id="@+id/textViewTime"
????????android:layout_width="107dp"
????????android:layout_height="46dp"
????????android:text="TextView"
????????android:textSize="34sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.527"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.023"?/>

????<TextView
????????android:id="@+id/textViewRoom"
????????android:layout_width="108dp"
????????android:layout_height="44dp"
????????android:text="TextView"
????????android:textSize="34sp"
????????app:layout_constraintBottom_toBottomOf="parent"
????????app:layout_constraintEnd_toEndOf="parent"
????????app:layout_constraintHorizontal_bias="0.881"
????????app:layout_constraintStart_toStartOf="parent"
????????app:layout_constraintTop_toTopOf="parent"
????????app:layout_constraintVertical_bias="0.023"?/></androidx.constraintlayout.widget.ConstraintLayout>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647

功能设计

简单功能说明

在MainActivity中有一个编辑按钮,按下可以跳转到EditActivity中。其中的Intent包括了Bundle,里面存储着当前选中的日子中从数据库查询出来的课程信息总和,即list_class(因为需要传递的数据是Arraylist类型的,所以首先需要把Class类Parcel化了才行),以及所选的是周几。
在EditActivity中接收来自MainActivity传递过来的Intent,并读取其中包含的Bundle中的课程数据,并展示在listview2中。
EditActivity中有个返回按钮,按下可以通过Intent重新回到MainActivity中
我创建了一个类,MyHelper,来当做调用SQLite数据库的工具类。在里面的onCreate方法里创建数据表,以及插入一些基本课程信息。
在进入EditActivity界面后,我设置了四个按钮新增,删除,保存,撤销。分别对应不同的方法来进行数据库操作。
在点击新增按钮之后,会首先进行判断,是否三个textview都不为空,一旦有一个为空就会提示用户“不能为空”并且终止操作,因为一旦不进行检测会导致空数据的存入。如都不为空,就将三个editview中的数据传入到insert方法中,调用MyHelper中的getWritableDatabase方法来获取db,将课程信息存入values中,再通过db.insert存入数据库中。然后把课程信息加入到list_class中(这样才可以实现listview的动态刷新),接着调用MyAdapter的notifyDataSetChanged方法来刷新listview,显示新增的课程。


以下代码附有注释


MainActivity.java代码

package?com.example.a2022finalproject;import?androidx.appcompat.app.AppCompatActivity;import?android.annotation.SuppressLint;import?android.content.Context;import?android.content.Intent;import?android.database.Cursor;import?android.database.sqlite.SQLiteDatabase;import?android.os.Bundle;import?android.os.Parcelable;import?android.view.LayoutInflater;import?android.view.View;import?android.view.ViewGroup;import?android.widget.BaseAdapter;import?android.widget.Button;import?android.widget.ListView;import?android.widget.TextView;import?android.widget.Toast;import?java.util.ArrayList;import?java.util.Collections;import?java.util.Comparator;import?java.util.List;public?class?MainActivity?extends?AppCompatActivity?implements?View.OnClickListener?{
????private?Button?btn1,?btn2,?btn3,?btn4,?btn5,?btn6;
????private?ListView?lv;
????private?MyHelper?myHelper?=?new?MyHelper(this);
????private?MyAdapter?ma?=?new?MyAdapter();
????private?String?weekNo?=?"0";
????//Class类信息的存储对象
????private?List<Class>?list_class?=?new?ArrayList<>();
????@Override
????protected?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_main);
????????//初始化
????????init();
????}
????//?初始化
????public?void?init()?{
????????btn1?=?findViewById(R.id.button1);
????????btn2?=?findViewById(R.id.button2);
????????btn3?=?findViewById(R.id.button3);
????????btn4?=?findViewById(R.id.button4);
????????btn5?=?findViewById(R.id.button5);
????????btn6?=?findViewById(R.id.buttonEdit);
????????lv?=?findViewById(R.id.list1);
????????btn1.setOnClickListener(this);
????????btn2.setOnClickListener(this);
????????btn3.setOnClickListener(this);
????????btn4.setOnClickListener(this);
????????btn5.setOnClickListener(this);
????????btn6.setOnClickListener(this);
????}

????//?查找数据库中的课程信息
????@SuppressLint("Range")
????public?void?query(String?day)?{
????????SQLiteDatabase?db?=?myHelper.getReadableDatabase();
????????Cursor?cursor?=?db.query("class",?null,?"weekNo=?",?new?String[]{day},?null,?null,?null);
????????if?(cursor.getCount()?!=?0)?{
????????????while?(cursor.moveToNext())?{
????????????????//?加入list_class中存储
????????????????list_class.add(new?Class(day,?cursor.getString(cursor.getColumnIndex("name")),?cursor.getString(cursor.getColumnIndex("time")),?cursor.getString(cursor.getColumnIndex("room"))));
????????????}
????????}
????????db.close();
????}
????//?按照时间排序函数
????public?static?class?TimeSort?implements?Comparator<Class>?{
????????@Override
????????public?int?compare(Class?aClass,?Class?t1)?{
????????????return?aClass.getTime().compareTo(t1.getTime());
????????}
????}

????@Override
????public?void?onClick(View?view)?{
????????switch?(view.getId())?{
????????????//?周一
????????????case?R.id.button1:
????????????????weekNo?=?"1";
????????????????list_class?=?new?ArrayList<>();
????????????????query("1");
????????????????Collections.sort(list_class,?new?TimeSort());//按照时间排序
????????????????lv.setAdapter(ma);//显示在listview中
????????????????break;
????????????//?周二
????????????case?R.id.button2:
????????????????weekNo?=?"2";
????????????????list_class?=?new?ArrayList<>();
????????????????query("2");
????????????????Collections.sort(list_class,?new?TimeSort());
????????????????lv.setAdapter(ma);
????????????????break;
????????????//?周三
????????????case?R.id.button3:
????????????????weekNo?=?"3";
????????????????list_class?=?new?ArrayList<>();
????????????????query("3");
????????????????Collections.sort(list_class,?new?TimeSort());
????????????????lv.setAdapter(ma);
????????????????break;
????????????//?周四
????????????case?R.id.button4:
????????????????weekNo?=?"4";
????????????????list_class?=?new?ArrayList<>();
????????????????query("4");
????????????????Collections.sort(list_class,?new?TimeSort());
????????????????lv.setAdapter(ma);
????????????????break;
????????????//?周五
????????????case?R.id.button5:
????????????????weekNo?=?"5";
????????????????list_class?=?new?ArrayList<>();
????????????????query("5");
????????????????Collections.sort(list_class,?new?TimeSort());
????????????????lv.setAdapter(ma);
????????????????break;
????????????//?修改课程信息
????????????case?R.id.buttonEdit:
????????????????//?判断是否选中了某一天
????????????????if?(weekNo?==?"0"){
????????????????????Toast.makeText(this,?"请先选择一天从而进行编辑操作",?Toast.LENGTH_LONG).show();
????????????????}
????????????????else{
????????????????????//?因为需要传递的数据时ArrayList所以需要使用Bundle来进行传递
????????????????????Intent?intent?=?new?Intent(MainActivity.this,?EditActivity.class);
????????????????????Bundle?bundle?=?new?Bundle();
????????????????????//?注意,对应的Class类需要进行Parcelable化
????????????????????bundle.putParcelableArrayList("list_class",?(ArrayList<??extends?Parcelable>)?list_class);
????????????????????bundle.putString("weekNo",?weekNo);
????????????????????intent.putExtras(bundle);
????????????????????startActivity(intent);
????????????????}
????????????????break;
????????}
????}

????public?class?MyAdapter?extends?BaseAdapter?{
????????@Override
????????public?int?getCount()?{
????????????return?list_class.size();
????????}

????????@Override
????????public?Object?getItem(int?i)?{
????????????return?list_class.get(i);
????????}

????????@Override
????????public?long?getItemId(int?i)?{
????????????return?i;
????????}

????????@Override
????????public?View?getView(int?i,?View?view,?ViewGroup?viewGroup)?{
????????????//?配置listview中的显示效果
????????????View?newView?=?View.inflate(MainActivity.this,?R.layout.activity_class,?null);
????????????TextView?textView1?=?newView.findViewById(R.id.textViewName);
????????????TextView?textView2?=?newView.findViewById(R.id.textViewTime);
????????????TextView?textView3?=?newView.findViewById(R.id.textViewRoom);
????????????textView1.setText(list_class.get(i).getName());
????????????textView2.setText(list_class.get(i).getTime());
????????????textView3.setText(list_class.get(i).getRoom());
????????????return?newView;
????????}
????}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171

EditActivity.java代码

package?com.example.a2022finalproject;import?androidx.appcompat.app.AppCompatActivity;import?android.content.ContentValues;import?android.content.Intent;import?android.database.sqlite.SQLiteDatabase;import?android.os.Bundle;import?android.view.View;import?android.view.ViewGroup;import?android.widget.AdapterView;import?android.widget.BaseAdapter;import?android.widget.Button;import?android.widget.EditText;import?android.widget.ListView;import?android.widget.TextView;import?android.widget.Toast;import?java.util.ArrayList;import?java.util.Collections;import?java.util.Comparator;import?java.util.List;public?class?EditActivity?extends?AppCompatActivity?implements?View.OnClickListener?{
????private?Button?btnAdd,?btnDelete,?btnZ,?btnSave,?btnBack;
????private?EditText?etName,?etTime,?etRoom;
????private?ListView?list2;
????private?List<Class>?list_class?=?new?ArrayList<>();
????private?MyAdapter?ma?=?new?MyAdapter();
????private?MyHelper?myHelper?=?new?MyHelper(this);
????private?String?name,?time,?room,?weekNo;
????private?int?chosenItem?=?-1;//?选中的课程序号
????private?int?showItem;
????private?String?changedIndex?=?"0";//0代表先前没有进行操作
????private?Class?changedItem,?changedItem2;

????@Override
????protected?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_edit);
????????init();
????}
????//初始化
????public?void?init()?{
????????btnAdd?=?findViewById(R.id.buttonAdd);
????????btnDelete?=?findViewById(R.id.buttonDelete);
????????btnZ?=?findViewById(R.id.buttonZ);
????????btnSave?=?findViewById(R.id.buttonSave);
????????btnBack?=?findViewById(R.id.buttonBack);
????????list2?=?findViewById(R.id.list2);
????????//设置listview的点击实践,实现点击课程记录下它对应的序号
????????list2.setOnItemClickListener(new?AdapterView.OnItemClickListener()?{
????????????@Override
????????????public?void?onItemClick(AdapterView<?>?adapterView,?View?view,?int?i,?long?l)?{
????????????????chosenItem?=?i;
????????????????showItem?=?chosenItem?+?1;
????????????????Toast.makeText(EditActivity.this,?"你已选中第"?+?showItem?+?"项",?Toast.LENGTH_SHORT).show();
????????????}
????????});
????????btnAdd.setOnClickListener(this);
????????btnDelete.setOnClickListener(this);
????????btnZ.setOnClickListener(this);
????????btnSave.setOnClickListener(this);
????????btnBack.setOnClickListener(this);
????????etName?=?findViewById(R.id.editTextName);
????????etTime?=?findViewById(R.id.editTextTime);
????????etRoom?=?findViewById(R.id.editTextRoom);
????????//接受来自MainActivity中的信息
????????Intent?intent?=?getIntent();
????????Bundle?bundle?=?intent.getExtras();
????????list_class?=?bundle.getParcelableArrayList("list_class");
????????weekNo?=?bundle.getString("weekNo");
????????//展示在list2中
????????list2.setAdapter(ma);
????}

????//插入方法
????private?boolean?insert(String?name,?String?time,?String?room)?{
????????changedIndex?=?"insert";//记录本次操作,便于撤销
????????SQLiteDatabase?db?=?myHelper.getWritableDatabase();
????????ContentValues?values?=?new?ContentValues();
????????values.put("weekNo",?weekNo);
????????values.put("name",?name);
????????values.put("time",?time);
????????values.put("room",?room);
????????long?id?=?db.insert("class",?null,?values);
????????db.close();
????????Class?classNew?=?new?Class(weekNo,?name,?time,?room);
????????//需要同时对list_class中的进行修改,不然notifyDataSetChanged方法不会生效,就不能实现动态刷新
????????list_class.add(classNew);
????????Collections.sort(list_class,?new?MainActivity.TimeSort());//时间排序
????????changedItem?=?classNew;//记录下插入的课程信息,便于撤销时删除
????????ma.notifyDataSetChanged();//刷新listview
????????return?id?>?0;
????}

????//用于撤销中对应删除的反操作
????private?boolean?insert(Class?item)?{
????????SQLiteDatabase?db?=?myHelper.getWritableDatabase();
????????ContentValues?values?=?new?ContentValues();
????????values.put("weekNo",?weekNo);
????????values.put("name",?item.getName());
????????values.put("time",?item.getTime());
????????values.put("room",?item.getRoom());
????????long?id?=?db.insert("class",?null,?values);
????????db.close();
????????list_class.add(item);
????????Collections.sort(list_class,?new?MainActivity.TimeSort());
????????ma.notifyDataSetChanged();
????????changedIndex?=?"0";//重置操作信息,避免多次撤销
????????return?id?>?0;
????}

????//删除操作
????private?boolean?delete(int?chosenItem)?{
????????changedIndex?=?"delete";//记录操作
????????Class?item?=?(Class)?list2.getItemAtPosition(chosenItem);
????????changedItem?=?item;//记录删除的课程信息
????????SQLiteDatabase?db?=?myHelper.getWritableDatabase();
????????long?id?=?db.delete("class",?"name?=???and?weekNo?=??",?new?String[]{item.getName(),?weekNo});
????????db.close();
????????//动态刷新
????????list_class.remove(item);
????????ma.notifyDataSetChanged();
????????return?id?>?0;
????}
????//用于撤销中的新增的反操作
????private?boolean?delete(Class?item)?{
????????SQLiteDatabase?db?=?myHelper.getWritableDatabase();
????????long?id?=?db.delete("class",?"name?=???and?weekNo?=??",?new?String[]{item.getName(),?weekNo});
????????db.close();
????????list_class.remove(item);
????????ma.notifyDataSetChanged();
????????changedIndex?=?"0";
????????return?id?>?0;
????}

????//保存操作,即update
????private?boolean?save(String?name,?String?time,?String?room)?{
????????changedIndex?=?"save";//记录操作
????????Class?item?=?(Class)?list2.getItemAtPosition(chosenItem);
????????changedItem?=?item;//记录修改的原课程信息
????????SQLiteDatabase?db?=?myHelper.getWritableDatabase();
????????ContentValues?values?=?new?ContentValues();
????????Class?item2?=?new?Class();//记录更新后的课程信息
????????if?(!name.isEmpty()){//对于为空的字段判断为不进行修改,保持原状
????????????values.put("name",?name);
????????????item2.setName(name);
????????}else{
????????????item2.setName(item.getName());
????????}
????????if?(!time.isEmpty()){
????????????values.put("time",?time);
????????????item2.setTime(time);
????????}else{
????????????item2.setTime(item.getTime());
????????}
????????if?(!room.isEmpty()){
????????????values.put("room",?room);
????????????item2.setRoom(room);
????????}else{
????????????item2.setRoom(item.getRoom());
????????}
????????//通过周几和课程名称来确定一门课程
????????int?updateCount?=?db.update("class",?values,?"name?=???and?time?=??",?new?String[]{item.getName(),?item.getTime()});
????????db.close();
????????//动态刷新
????????list_class.remove(item);
????????list_class.add(item2);
????????Collections.sort(list_class,?new?MainActivity.TimeSort());
????????changedItem2?=?item2;
????????ma.notifyDataSetChanged();
????????return?updateCount?>?0;
????}

????//用于撤销操作中保存操作的反操作
????private?boolean?save(Class?item,?Class?item2)?{
????????SQLiteDatabase?db?=?myHelper.getWritableDatabase();
????????ContentValues?values?=?new?ContentValues();
????????if(item.getName()?!=?item2.getName()){
????????????values.put("name",?item.getName());
????????}
????????if(item.getTime()?!=?item2.getTime()){
????????????values.put("time",?item.getTime());
????????}
????????if(item.getRoom()?!=?item2.getRoom()){
????????????values.put("room",?item.getRoom());
????????}
????????int?updateCount?=?db.update("class",?values,?"name?=???and?time?=??",?new?String[]{item2.getName(),?item2.getTime()});
????????db.close();
????????//动态刷新
????????list_class.remove(item2);
????????list_class.add(item);
????????Collections.sort(list_class,?new?MainActivity.TimeSort());
????????ma.notifyDataSetChanged();
????????changedIndex?=?"0";//还原操作标记
????????return?updateCount?>?0;
????}

????@Override
????public?void?onClick(View?view)?{
????????switch?(view.getId())?{
????????????case?R.id.buttonAdd:
????????????????if(list_class.size()?>=?5){
????????????????????Toast.makeText(EditActivity.this,?"新建失败,课程最多一天5门",?Toast.LENGTH_SHORT).show();
????????????????????break;
????????????????}
????????????????name?=?etName.getText().toString().trim();
????????????????time?=?etTime.getText().toString().trim();
????????????????room?=?etRoom.getText().toString().trim();
????????????????if(name.isEmpty()?||?time.isEmpty()?||?room.isEmpty()){//判断是否为空,避免插入空信息的课程
????????????????????Toast.makeText(EditActivity.this,?"课程名称,时间,教室不能为空",?Toast.LENGTH_SHORT).show();
????????????????????break;
????????????????}
????????????????if?(insert(name,?time,?room))?{
????????????????????Toast.makeText(EditActivity.this,?"新增成功",?Toast.LENGTH_SHORT).show();
????????????????}
????????????????break;
????????????case?R.id.buttonDelete:
????????????????if?(chosenItem?==?-1){//判断是否选中了课程
????????????????????Toast.makeText(EditActivity.this,?"请先选择一节课",?Toast.LENGTH_SHORT).show();
????????????????}else{
????????????????????if?(delete(chosenItem))?{
????????????????????????changedIndex?=?"-1";?//?重置,防止误删
????????????????????????Toast.makeText(EditActivity.this,?"删除成功",?Toast.LENGTH_SHORT).show();
????????????????????}
????????????????}
????????????????break;
????????????case?R.id.buttonZ:
????????????????if(changedIndex?==?"0"){//判断是否进行过操作
????????????????????Toast.makeText(EditActivity.this,?"没有需要撤回的操作",?Toast.LENGTH_SHORT).show();
????????????????}else?if(changedIndex?==?"insert"){
????????????????????if(delete(changedItem)){
????????????????????????Toast.makeText(EditActivity.this,?"撤回新增成功",?Toast.LENGTH_SHORT).show();
????????????????????}
????????????????}else?if(changedIndex?==?"delete"){
????????????????????if(insert(changedItem)){
????????????????????????Toast.makeText(EditActivity.this,?"撤回删除成功",?Toast.LENGTH_SHORT).show();
????????????????????}

????????????????}else?if(changedIndex?==?"save"){
????????????????????if(save(changedItem,?changedItem2)){
????????????????????????Toast.makeText(EditActivity.this,?"撤回保存成功",?Toast.LENGTH_SHORT).show();
????????????????????}
????????????????}
????????????????break;
????????????case?R.id.buttonSave:
????????????????if?(chosenItem?==?-1){//判断是否选中课
????????????????????Toast.makeText(EditActivity.this,?"请先选择一节课",?Toast.LENGTH_SHORT).show();
????????????????}else{
????????????????????name?=?etName.getText().toString().trim();
????????????????????time?=?etTime.getText().toString().trim();
????????????????????room?=?etRoom.getText().toString().trim();
????????????????????if?(save(name,?time,?room))?{
????????????????????????Toast.makeText(EditActivity.this,?"保存成功",?Toast.LENGTH_SHORT).show();
????????????????????}
????????????????}
????????????????break;
????????????case?R.id.buttonBack:
????????????????Intent?intent?=?new?Intent(EditActivity.this,?MainActivity.class);
????????????????startActivity(intent);
????????????????break;
????????}
????}

????public?class?MyAdapter?extends?BaseAdapter?{
????????@Override
????????public?int?getCount()?{
????????????return?list_class.size();
????????}

????????@Override
????????public?Object?getItem(int?i)?{
????????????return?list_class.get(i);
????????}

????????@Override
????????public?long?getItemId(int?i)?{
????????????return?i;
????????}

????????@Override
????????public?View?getView(int?i,?View?view,?ViewGroup?viewGroup)?{
????????????View?newView?=?View.inflate(EditActivity.this,?R.layout.activity_class,?null);
????????????TextView?textView1?=?newView.findViewById(R.id.textViewName);
????????????TextView?textView2?=?newView.findViewById(R.id.textViewTime);
????????????TextView?textView3?=?newView.findViewById(R.id.textViewRoom);
????????????textView1.setText(list_class.get(i).getName());
????????????textView2.setText(list_class.get(i).getTime());
????????????textView3.setText(list_class.get(i).getRoom());
????????????return?newView;
????????}
????}}

Class.java代码

package?com.example.a2022finalproject;import?android.os.Parcel;import?android.os.Parcelable;public?class?Class?implements?Parcelable?{
????private?String?weekNo;
????private?String?name;
????private?String?time;
????private?String?room;
????public?Class(String?weekNo,?String?name,?String?time,?String?room){
????????this.weekNo?=?weekNo;
????????this.name?=?name;
????????this.time?=?time;
????????this.room?=?room;
????}
????public?Class(){

????}
????//Parcel
????protected?Class(Parcel?in)?{
????????weekNo?=?in.readString();
????????name?=?in.readString();
????????time?=?in.readString();
????????room?=?in.readString();
????}

????public?static?final?Creator<Class>?CREATOR?=?new?Creator<Class>()?{
????????@Override
????????public?Class?createFromParcel(Parcel?in)?{
????????????return?new?Class(in);
????????}

????????@Override
????????public?Class[]?newArray(int?size)?{
????????????return?new?Class[size];
????????}
????};

????public?String?getName(){
????????return?name;
????}
????public?void?setName(String?name){
????????this.name?=?name;
????}
????public?String?getWeekNo(){
????????return?weekNo;
????}
????public?void?setWeekNo(String?weekNo){
????????this.weekNo?=?weekNo;
????}
????public?String?getTime(){
????????return?time;
????}
????public?void?setTime(String?time){
????????this.time?=?time;
????}
????public?String?getRoom(){
????????return?room;
????}
????public?void?setRoom(String?room){
????????this.room?=?room;
????}

????@Override
????public?int?describeContents()?{
????????return?0;
????}

????@Override
????public?void?writeToParcel(Parcel?parcel,?int?i)?{
????????parcel.writeString(weekNo);
????????parcel.writeString(name);
????????parcel.writeString(time);
????????parcel.writeString(room);
????}}

MyHelper.java代码

package?com.example.a2022finalproject;import?android.content.ContentValues;import?android.content.Context;import?android.database.sqlite.SQLiteDatabase;import?android.database.sqlite.SQLiteOpenHelper;import?androidx.annotation.Nullable;import?java.sql.Time;//数据库操作类public?class?MyHelper?extends?SQLiteOpenHelper?{
????public?MyHelper(@Nullable?Context?context)?{
????????super(context,?"class.db",?null,?1);
????}

????@Override
????public?void?onCreate(SQLiteDatabase?db)?{
????????//初始化数据库,存入一些基本课程信息
????????db.execSQL("CREATE?TABLE?class(weekNo?VATCHAR(20),?name?VARCHAR(20),?time?VATCHAR(20),?room?VARCHAR(20))");
????????ContentValues?values?=?new?ContentValues();
????????values.put("weekNo",?"1");
????????values.put("name",?"Web应用程序开发");
????????values.put("time",?"09:40");
????????values.put("room",?"29-106");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"1");
????????values.put("name",?"智能移动设备软件开发");
????????values.put("time",?"14:00");
????????values.put("room",?"29-106");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"2");
????????values.put("name",?"编译原理实验");
????????values.put("time",?"10:35");
????????values.put("room",?"29-106");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"2");
????????values.put("name",?"软件项目管理");
????????values.put("time",?"14:00");
????????values.put("room",?"23-213");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"2");
????????values.put("name",?"软件项目管理实验");
????????values.put("time",?"15:40");
????????values.put("room",?"20-109");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"3");
????????values.put("name",?"马克思主义基本原理");
????????values.put("time",?"08:00");
????????values.put("room",?"16-103");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"4");
????????values.put("name",?"编译原理");
????????values.put("time",?"10:35");
????????values.put("room",?"23-319");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"5");
????????values.put("name",?"Python与数据分析");
????????values.put("time",?"08:45");
????????values.put("room",?"25-315");
????????db.insert("class",?null,?values);
????????values?=?new?ContentValues();
????????values.put("weekNo",?"5");
????????values.put("name",?"Python与数据分析实验");
????????values.put("time",?"10:35");
????????values.put("room",?"20-206");
????????db.insert("class",?null,?values);
????}

????@Override
????public?void?onUpgrade(SQLiteDatabase?sqLiteDatabase,?int?i,?int?i1)?{

????}}

总结反思

  1. 一开始困扰我的是关于listview的问题:就是在MainActivity中,尽管我的listview是放在中下方的位置的,距离顶部还有三分之一的距离,大小也做了限制,但是在实际运行过程中发现课程信息还是会显示在屏幕的最顶上,好像是没有做限制一样。想了半天不知道怎么一回事,后来发现只需要给listview加一个marginTop属性就可以解决这个问题了。

  2. 第二个是关于跨Activity传递数据的问题,本来可以简单的直接使用Intent,然后putExtra就可以了,但是我发现好像这样是不能传递ArrayList类型的,所以我使用了bundle来存储ArrayList,然后发现这样的话需要将Class类Parcelabled才可以,这样才最终完成了将list_class传递给编辑界面的功能。

  3. 第三个是关于怎么按照时间排序的,一开始没什么头绪,后来找到可以使用Collection.sort来搞定,不过需要写一个TimeSort的函数。

  4. 第四个是怎么选中listview上的课程,因为删除和保存两个功能都是需要提前选中课程才可以进行操作的,所以怎么选中要进行操作的课程就是个问题了。后来发现可以给listview2设置点击监听器,通过setOnItemClickListener这个方法来设置,参数new一个AdapterView.OnItemClickListener实例,重写OnItemClick方法就可以实现了。

  5. 第五个是怎么使得在我们对数据库课程信息做出了编辑操作之后实时在listview中体现出来。一开始我只是加了一个适配器的notifyDataSetChanged方法,但是发现并没有生效。原来是需要把list_class中的内容也更改了,这样才会使得可以实现动态刷新。

  6. 第六个是在保存时,如果只是想修改课程时间,而不修改课程名称和教室,那么就需要重新输入一遍信息,要不然就会变成空白。所以后来我在save函数里加入了判断,如果edittext中为空白就不存入values中,这样也就解决了这个问题。

本项目我觉得还是有很多地方可以提升和改进的。比如可以在MainActivity中设置成左右滑切换哪一天。还有在EditActivity中可以给每一节课加一个单选框,这样相比起Toast来提示选择的哪一节课更直观。还有关于数据库的数据结构设计还可以更好一点(其实是依托答辩 ),添加主键可以防止出现一些错误。关于撤回可以设计成使用数据库的事务回滚来完成。

文章来源:https://blog.csdn.net/m0_66999594/article/details/135353077
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。