从零打造Android课程表(安卓开发初体验)

您所在的位置:网站首页 课程开发表格怎么做的 从零打造Android课程表(安卓开发初体验)

从零打造Android课程表(安卓开发初体验)

2024-07-16 03:22:07| 来源: 网络整理| 查看: 265

前言:

使用Android Studio开发,SQLite数据库,dialog对话框,Intent组件交互,java动态生成组件等技术。(博客最下方有所有代码。若不想复制粘贴,可下载源码)

先展示效果图,别放弃!!

①初始课程表②右上角添加课程③填写信息④显示课程⑤长按显示详情

逻辑就是这么简单,程序亦是如此!

话不多说直接开始: 我们把整个程序拆分,按照增量模型完成项目(先完成基础,也是核心功能)。先完成核心功能模块图一,再完成图二三四增加课程模块。最后完成图五非核心功能模块。测试每个模块之间衔接是否有bug。(我们希望是没有的,但时常事与愿违) 实现核心功能

第一步:从需求、设计入手。

一周有七天,一天有十节课。课程表结构的activity_main.xml框架设计大致如此。

分析架构:

最外层使用线性布局设置屏幕水平方向android:orientation=“horizontal”。

在内层使用八个GridLayout将屏幕分为八块。其中第一块是节课,后面的为周一至日。

​ 关键点:因为是水平排列的,所以权重和宽度相关联。把每个GridLayout的宽度设置为0dp。除第一个GridLayout权值为0.5其余设为1。目的是让第一列占比低一些。

每一个GridLayout都设置为竖直方向android:orientation=“vertical”。目的是每一节课都是竖着往下排列的。

​ 关键点:同理,因为是竖直排列的,所以权重和高度有关。把每个GridLayout的高度设置为0dp。除第一个GridLayout权值为0.25其余设为1。目的是让第一行占比低一些。

分析有了,上activity_main.xml代码:

点击跳转到activity_main.xml

发现xml并没有像图一有课程框。可以直接在activity_main.xml中依次添加,但是考虑到有7×10个EditText需要弄,还需要为每个EditText设置id(这个id之后非常关键),而且在xml写死的话对后期拓展(课程数量增加、减少、重构)很不便。所以我使用java在MainActivity中动态添加课程框。 public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //动态渲染课程框 framework(); } public void framework() { //创建一个GridLayout对象 GridLayout gridLayout; //定义每个框的id,之后会动态改变id值 int id = 1; //渲染每一列(周) for (int i = 1; i

这时候就有一个classes_db表,有id分别为1-36记录存放对应课程数据。(这个id对应上述EditText的id)

添加课程dialog对话框(图二)用于把数据存放到上述classes_db表中:

在activity_main.xml同级目录下创建activity_set.xml:

这里就不赘述基础了0.0

在MainActivity类同级目录创建DialogModal类,处理课程数据,保存在数据库,并跳回MainActivity:

public class DialogModal extends Activity { Button close_activity; Button save_activity; Spinner selected_time; Spinner selected_day; EditText subject; EditText teacher; //数据库名,表名 public final String DB_NAME = "classes_db.db"; public final String TABLE_NAME = "classes_db"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_set); //当点击dialog之外完成此activity setFinishOnTouchOutside (true); //关闭按钮操作 close_activity=(Button) findViewById(R.id.close_activity); close_activity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { DialogModal.this.finish(); } }); //保存按钮操作 save_activity = findViewById(R.id.save_activity); save_activity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); selected_day = findViewById(R.id.selected_day); String day = selected_day.getSelectedItem().toString(); if (day.equals("--请选择--")) { save_activity.setError(""); return; } selected_time = findViewById(R.id.selected_time); String time = selected_time.getSelectedItem().toString(); if (time.equals("--请选择--")) { save_activity.setError(""); return; } subject = findViewById(R.id.subject); String text = subject.getText().toString(); if ("".equals(text)) { save_activity.setError(""); return; } teacher = findViewById(R.id.teacher); String teacher = subject.getText().toString(); if ("".equals(teacher)) { save_activity.setError(""); return; } //创建一个数据库对象,为了更新数据 DBHelper dbHelper = new DBHelper(DialogModal.this, DB_NAME, null, 1); //把数据存在contentValues中 ContentValues contentValues = new ContentValues(); //combineId()方法目的是通过星期几和第几节课算出对应该课程id contentValues.put("c_id", combineId(day, time)); contentValues.put("c_name", text); contentValues.put("c_time", time); contentValues.put("c_day", day); contentValues.put("c_teacher", teacher); //更新数据库记录 update(dbHelper, contentValues); //清空栈内所有activity intent.setFlags(intent.FLAG_ACTIVITY_CLEAR_TASK); //启动MainActivity intent.setClass(DialogModal.this, MainActivity.class); startActivity(intent); } }); } public String combineId(String day, String time) { //星期几转换成int类型 int day1 = utils.getDay(day); //如1-2节课只取1 int time1 = Integer.parseInt(time.substring(0, 1)); return String.valueOf((day1 - 1) * 5 + ((time1 - 1)/2 + 1)); } public void update(DBHelper dbHelper, ContentValues contentValues){ String []a = {contentValues.get("c_id").toString()}; // 通过DBHelper类获取一个读写的SQLiteDatabase对象 SQLiteDatabase db=dbHelper.getWritableDatabase(); // 修改数据 // 参数1:tablename // 参数2:修改的值 // 参数3:修改的条件(SQL where语句) // 参数4:表示whereClause语句中的表达式的占位符参数列表,这些字符串会替换where条件中? db.update(TABLE_NAME,contentValues,"c_id=?", a); // 释放连接 db.close(); } } utils类

​ 现在问题又来了,如何从图一过渡到图二?

细心的小伙伴已经看到右上角的+号了!

在res文件夹下创建menu文件夹,创建menu.xml:

在MainActivity类中重写onCreateOptionsMenu方法:(Intent就是为了activity跳转)

@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); MenuItem menuItem=menu.findItem(R.id.action_menu); menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { Intent intent = new Intent(); intent.setClass(MainActivity.this, DialogModal.class); startActivity(intent); return true; } }); return super.onCreateOptionsMenu(menu); }

这样+号就出现了,就可以连接图一图二了!

更新MainActivity,先看onCreate方法增加的调用。

public class MainActivity extends AppCompatActivity implements View.OnTouchListener { public final String DB_NAME = "classes_db.db"; public final String TABLE_NAME = "classes_db"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // getSupportActionBar().hide(); //拿到数据库对象,为了读取数据 DBHelper dbHelper = new DBHelper(MainActivity.this, DB_NAME, null, 1); //动态渲染课程框 framework(); //将数据库课程渲染到课程框 applyDraw(dbHelper); } public void applyDraw(DBHelper dbHelper) { //从数据库拿到课程数据保存在链表 List classes = query(dbHelper); for (Classes aClass : classes) { //第几节课 int i = Integer.parseInt(aClass.getC_time().charAt(0) + ""); //星期几 int j = utils.getDay(aClass.getC_day()); //获取此课程对应TextView的id TextView Class = findViewById((j - 1) * 5 + ((i - 1)/2 + 1)); //判断如果课程星期==当前星期,如此课程信息和当前都是星期二就把背景颜色更换。 Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE"); if (aClass.getC_day().equals(simpleDateFormat.format(date).toString())) { Class.setBackgroundColor(Color.rgb(28, 217, 204)); } //课程表信息映射出来 Class.setText(aClass.getC_name()); //触碰此课程框触发 Class.setOnTouchListener(this); } } @SuppressLint("Range") public List query(DBHelper dbHelper) { List classes = new ArrayList(); // 通过DBHelper类获取一个读写的SQLiteDatabase对象 SQLiteDatabase db = dbHelper.getWritableDatabase(); // 参数1:table_name // 参数2:columns 要查询出来的列名。相当于 select *** from table语句中的 ***部分 // 参数3:selection 查询条件字句,在条件子句允许使用占位符“?”表示条件值 // 参数4:selectionArgs :对应于 selection参数 占位符的值 // 参数5:groupby 相当于 select *** from table where && group by ... 语句中 ... 的部分 // 参数6:having 相当于 select *** from table where && group by ...having %%% 语句中 %%% 的部分 // 参数7:orderBy :相当于 select ***from ?? where&& group by ...having %%% order by@@语句中的@@ 部分,如: personid desc(按person 降序) Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null); // 将游标移到开头 cursor.moveToFirst(); while (!cursor.isAfterLast()) { // 游标只要不是在最后一行之后,就一直循环 if (!cursor.getString(cursor.getColumnIndex("c_day")).equals("0")) { Classes Class = new Classes(); Class.setC_id(Integer.parseInt(cursor.getString(cursor.getColumnIndex("c_id")))); Class.setC_name(cursor.getString(cursor.getColumnIndex("c_name"))); Class.setC_time(cursor.getString(cursor.getColumnIndex("c_time"))); Class.setC_day(cursor.getString(cursor.getColumnIndex("c_day"))); classes.add(Class); } // 将游标移到下一行 cursor.moveToNext(); } db.close(); return classes; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); MenuItem menuItem=menu.findItem(R.id.action_menu); menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { Intent intent = new Intent(); intent.setClass(MainActivity.this, DialogModal.class); startActivity(intent); return true; } }); return super.onCreateOptionsMenu(menu); } }

至此,核心功能就完成了!

实现非功能需求

在MainActivity类中重写此方法(注意我们已经在applyDraw方法最后一行中注册了课程框的onTouch监听):

@SuppressLint("Range") @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: { TextView textView = (TextView) view; DBHelper dbHelper = new DBHelper(MainActivity.this, DB_NAME, null, 1); SQLiteDatabase db = dbHelper.getWritableDatabase(); // 参数1:table_name // 参数2:columns 要查询出来的列名。相当于 select *** from table语句中的 ***部分 // 参数3:selection 查询条件字句,在条件子句允许使用占位符“?”表示条件值 // 参数4:selectionArgs :对应于 selection参数 占位符的值 // 参数5:groupby 相当于 select *** from table where && group by ... 语句中 ... 的部分 // 参数6:having 相当于 select *** from table where && group by ...having %%% 语句中 %%% 的部分 // 参数7:orderBy :相当于 select ***from ?? where&& group by ...having %%% order by@@语句中的@@ 部分,如: personid desc(按person 降序) // Cursor cursor = db.query(TABLE_NAME, null, "c_id=?", new String[]{String.valueOf(textView.getId())}, null, null, null); Cursor cursor = db.query(TABLE_NAME, null, "c_id=?", new String[]{String.valueOf(textView.getId())}, null, null, null); // 将游标移到开头 cursor.moveToFirst(); if (!cursor.isAfterLast()) { Classes Class = new Classes(); System.out.println(textView.getId()); System.out.println(cursor.getString(cursor.getColumnIndex("c_name"))); Intent intent = new Intent(); intent.putExtra("name", cursor.getString(cursor.getColumnIndex("c_name"))); intent.putExtra("time", cursor.getString(cursor.getColumnIndex("c_time"))); intent.putExtra("day", cursor.getString(cursor.getColumnIndex("c_day"))); intent.putExtra("teacher", cursor.getString(cursor.getColumnIndex("c_teacher"))); intent.setClass(MainActivity.this, Detail.class); startActivity(intent); } return true; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { Intent intent = new Intent(this, MainActivity.class); startActivity(intent); break; } } return false; }

上所有代码:

项目结构:

在这里插入图片描述

根据项目结构从上到下排序

Classes类:

public class Classes { private int c_id; private String c_name; private String c_time; private String c_day; @Override public String toString() { return "Classes{" + "c_id=" + c_id + ", c_name='" + c_name + '\'' + ", c_time='" + c_time + '\'' + ", c_day='" + c_day + '\'' + '}'; } public int getC_id() { return c_id; } public void setC_id(int c_id) { this.c_id = c_id; } public String getC_name() { return c_name; } public void setC_name(String c_name) { this.c_name = c_name; } public String getC_time() { return c_time; } public void setC_time(String c_time) { this.c_time = c_time; } public String getC_day() { return c_day; } public void setC_day(String c_day) { this.c_day = c_day; } }

DBHelper类:

public class DBHelper extends SQLiteOpenHelper { public SQLiteDatabase getWritableDatabase() { return super.getWritableDatabase(); } public DBHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { sqLiteDatabase.execSQL("create table classes_db" + "(c_id Integer not null primary key autoincrement," + " c_name varchar(50) not null," + " c_time varchar(50) not null," + " c_day varchar(50) not null," + " c_teacher varchar(50) not null)"); // 创建ContentValue设置参数 ContentValues contentValues = new ContentValues(); //课程名字 contentValues.put("c_name", "0"); //第几节课 contentValues.put("c_time", "0"); //星期几 contentValues.put("c_day", "0"); //任课教师 contentValues.put("c_teacher", "0"); //插入id 1-36 个课程数据,以便添加课程 for (int i = 1; i

返回

activity_press.xml

activity_set.xml

menu.xml

strings.xml:

schedule --请选择-- 星期一 星期二 星期三 星期四 星期五 星期六 星期日 --请选择-- 1-2节课 3-4节课 5-6节课 7-8节课 9-10节课

styles.xml

48dp 30dp center center #e9e9e9 20dp 20dp 70dp center center 15dp #e9e9e9 40dp 130dp 10dp 5dp 42dp 130dp center center 2 12dp @color/transparent true true @null

AndroidManifest.xml



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭