一、程序界面

1.课程表首页

一周有7天,一天有10节课。

课程表首页的布局activity_main.xml框架设计大致如此:

  • 最外层使用线性布局设置屏幕水平方向android:orientation=“horizontal”。
  • 在内层使用八个GridLayout将屏幕分为八块。其中第一块是节课,后面的为周一至日,7天。
  • 因为是水平排列的,所以权重和宽度相关联。
  • 把每个GridLayout的宽度设置为0dp。除第一个GridLayout权值为0.5其余设为1。目的是让第一列占比低一些。
  • 每一个GridLayout都设置为竖直方向android:orientation=“vertical”。目的是每一节课都是竖着往下排列的。
  • ​因为是竖直排列的,所以权重和高度有关。把每个GridLayout的高度设置为0dp。除第一个GridLayout权值为0.25其余设为1。目的是让第一行占比低一些。

activity_main.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity"> <GridLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25"
android:gravity="center"
android:text="" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="1" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="2" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="3" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="4" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="5" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="6" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="7" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="8" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="9" /> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:gravity="center"
android:text="10" />
</GridLayout> <GridLayout
android:id="@+id/d1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25"
android:autoSizeMaxTextSize="30sp"
android:autoSizeMinTextSize="5sp"
android:autoSizeStepGranularity="1sp"
android:gravity="center"
android:text="周一"
android:textSize="20sp" />
</GridLayout> <GridLayout
android:id="@+id/d2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25" android:gravity="center"
android:text="周二"
android:textSize="20dp" />
</GridLayout> <GridLayout
android:id="@+id/d3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25" android:gravity="center"
android:text="周三"
android:textSize="20dp" />
</GridLayout> <GridLayout
android:id="@+id/d4"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25"
android:gravity="center"
android:text="周四"
android:textSize="20dp" />
</GridLayout> <GridLayout
android:id="@+id/d5"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25"
android:gravity="center"
android:text="周五"
android:textSize="20dp" />
</GridLayout> <GridLayout
android:id="@+id/d6"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25"
android:gravity="center"
android:text="周六"
android:textSize="20dp" />
</GridLayout> <GridLayout
android:id="@+id/d7"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFAFA"
android:orientation="vertical"
android:rowCount="11"> <TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_rowWeight="0.25"
android:gravity="center"
android:text="周日"
android:textSize="20dp" />
</GridLayout>
</LinearLayout>

发现xml并没有像图一有课程框。可以直接在activity_main.xml中依次添加,但是考虑到有7×10个EditText需要弄,还需要为每个EditText设置id(这个id之后非常关键),而且在xml写死的话对后期拓展(课程数量增加、减少、重构)很不便。所以我使用Java在MainActivity中动态添加课程框。
MainActivity.java代码如下:

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.GridLayout;
import android.widget.TextView; public class MainActivity extends AppCompatActivity {
private int[] weekId = {R.id.d1, R.id.d2, R.id.d3, R.id.d4, R.id.d5, R.id.d6, R.id.d7}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initWeeks();
} public void initWeeks() {
//创建一个GridLayout对象
GridLayout gridLayout;
//定义每个框的id,之后会动态改变id值
int id = 1; //渲染每一列(周)
for (int i = 0; i < 7; i++) {
//注入GridLayout对应的列,根据星期几调用LayoutColumn方法
gridLayout = findViewById(weekId[i]); //渲染每一行(节课)
for (int j = 1; j < 10; j += 2) {
//声明一个新的TextView
TextView textView1 = new TextView(this); //给TextView设置style样式
textView1.setId(id++);
textView1.setText("");
textView1.setMaxLines(5);
textView1.setEllipsize(TextUtils.TruncateAt.END);
textView1.setBackgroundColor(Color.parseColor("#F0FFFF"));
textView1.setGravity(Gravity.CENTER); //GridLayout.LayoutParams设置在此gridLayout列中TextView布局
GridLayout.LayoutParams params1 = new GridLayout.LayoutParams();
params1.setMargins(5, 10, 5, 10);
params1.width = GridLayout.LayoutParams.MATCH_PARENT;
params1.height = 0;
//设置在gridLayout中的方位,参数1:在第几行。参数2:占几行。参数3:权值
//这个权值是根据xml中第一个gridLayout节课权值设定的。
params1.rowSpec = GridLayout.spec(j, 2, 1); //把TextView和布局样式添加到此gridLayout中
gridLayout.addView(textView1, params1);
}
}
} }

运行程序:

2.添加课程对话框

课程信息有:星期几,节次,课程名,任课教师

activity_add.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/myDialogStyle"

android:layout_width="300dp"
android:layout_height="450dp"
android:background="#88ffffff"
android:orientation="vertical"
tools:context=".AddActivity"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="添加课程"
android:textColor="@color/black"
android:textSize="40dp" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="时间:"
android:textColor="@color/cardview_dark_background"
android:textSize="30dp" /> <Spinner
android:id="@+id/spinnerDay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/day"></Spinner>
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="节课:"
android:textColor="@color/cardview_dark_background"
android:textSize="30dp" /> <Spinner
android:id="@+id/spinnerTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/time"></Spinner>
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="科目:"
android:textColor="@color/cardview_dark_background"
android:textSize="30dp" /> <EditText
android:id="@+id/edtSubject"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="任课教师:"
android:textColor="@color/cardview_dark_background"
android:textSize="30dp" /> <EditText
android:id="@+id/edtTeacher"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"> <Button
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消" /> <Button
android:id="@+id/btnSave"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="保存" />
</LinearLayout>
</LinearLayout>

AddActivity.java:

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Window; public class AddActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 继承AppCompatActivity的活动,要去掉标题栏,使用supportRequestWindowFeature()方法
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_add);
}
}

在AndroidManifest.xml修改AddActivity的主题为对话框样式:

<activity
android:name=".AddActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.Dialog"
>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>

3.菜单

如何启动添加课程的对话框呢?

我们使用右上角菜单+按钮

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

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_menu"
android:icon="@android:drawable/ic_input_add"
android:title="添加课程"
app:showAsAction="ifRoom"></item>
</menu>

在MainActivity类中重写onCreateOptionsMenu方法:

@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, AddActivity.class);
startActivity(intent);
return true;
}
});
return super.onCreateOptionsMenu(menu);
}

4.样式文件

style.xml

<?xml version="1.0" encoding="utf-8"?>
<resources> <style name="dayStyle">
<item name="android:layout_width">48dp</item>
<item name="android:layout_height">30dp</item>
<item name="android:layout_gravity">center</item>
<item name="android:gravity">center</item>
<item name="android:background">#e9e9e9</item>
<item name="android:textSize">20dp</item>
</style> <style id="c" name="numb">
<item name="android:layout_width">20dp</item>
<item name="android:layout_height">70dp</item>
<item name="android:gravity">center</item>
<item name="android:layout_gravity">center</item>
<item name="android:textSize">15dp</item>
<item name="android:background">#e9e9e9</item>
</style> <dimen name="text_width">40dp</dimen>
<dimen name="text_height">130dp</dimen>
<dimen name="text_size">10dp</dimen>
<style name="Class">
<item name="android:layout_margin">5dp</item>
<item name="android:layout_width">42dp</item>
<item name="android:layout_height">130dp</item>
<item name="android:layout_gravity">center</item>
<item name="android:gravity">center</item>
<item name="android:layout_rowSpan">2</item>
<item name="android:textSize">12dp</item>
</style> <style name="myDialogStyle" parent="Theme.AppCompat">
<!--边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--背景色,此处的背景色请一定要设置为透明度背景色-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--window Is Translucent 窗口是半透明的-->
<item name="android:windowIsTranslucent">false</item>
<!--window No Title窗口无标题-->
<item name="android:windowNoTitle">true</item>
<!--弹出动画-->
<item name="android:windowAnimationStyle">@null</item>
</style>
</resources>

运行程序:

      

二、添加课程数据

填写完课程信息后,把信息保存在SQLite中,重新加载MainActivity并渲染数据到课程表。

思路:

需要考虑如何映射数据关系,即当需要添加课程,该如何定位到我选择的位置?

这时候上面我们动态设置的id的作用就显示出来了。上述id是从1开始往下依次增加到35(7天×5节课)。可以通过星期几和第几节课算出对应该课程id。

1.使用SQLite数据库保存课程信息

在MainActivity类同级目录创建DBHelper类(建classes_db表):

package com.sdbi.classschedule;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import androidx.annotation.Nullable; public class DBHelper extends SQLiteOpenHelper {
public final static String TABLE_NAME = "tabClass"; public DBHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
} @Override
public void onCreate(SQLiteDatabase db) {
// 建表
db.execSQL("create table " + TABLE_NAME +
" (c_id Integer not null primary key," +
" 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-35 条课程数据,对应一周7*5课时,以便添加课程
for (int i = 1; i < 36; i++) {
contentValues.put("c_id", i);
db.insert(TABLE_NAME, null, contentValues);
}
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
}

2.创建课程类

对应表中的课程信息,创建课程类Classes.java

public class Classes {
private int c_id;
private String c_name;
private String c_time;
private String c_day;
private String c_teacher; 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;
} public String getC_teacher() {
return c_teacher;
} public void setC_teacher(String c_teacher) {
this.c_teacher = c_teacher;
} @Override
public String toString() {
return "Classes{" +
"c_id=" + c_id +
", c_name='" + c_name + '\'' +
", c_time='" + c_time + '\'' +
", c_day='" + c_day + '\'' +
", c_teacher='" + c_teacher + '\'' +
'}';
}
}

3.定义工具类Utils

定义一个工具类,用于将星期几转化成对应的整型数字

package com.sdbi.classschedule;

public class Utils {
public static int getDay(String day) {
int j = 0;
switch (day) {
case "星期一": {
j = 1;
break;
}
case "星期二": {
j = 2;
break;
}
case "星期三": {
j = 3;
break;
}
case "星期四": {
j = 4;
break;
}
case "星期五": {
j = 5;
break;
}
case "星期六": {
j = 6;
break;
}
case "星期日": {
j = 7;
break;
}
}
return j;
}
}

4.修改MainActivity

定义查询课程数据的方法query()和显示课程数据的方法display()。

并在onCreate()方法中调用显示课程数据的方法。

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;
import android.widget.TextView; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
public static final String DB_NAME = "classes_db.db"; private int[] weekId = {R.id.d1, R.id.d2, R.id.d3, R.id.d4, R.id.d5, R.id.d6, R.id.d7}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initWeeks(); // 初始化课程表控件 // 获得数据库管理类对象
DBHelper dbHelper = new DBHelper(MainActivity.this, DB_NAME, null, 1); display(dbHelper); // 调用显示课程数据的方法
} public void initWeeks() {
//创建一个GridLayout对象
GridLayout gridLayout;
//定义每个框的id,之后会动态改变id值
int id = 1; //渲染每一列(周)
for (int i = 0; i < 7; i++) {
// 注入GridLayout对应的列,根据星期几调用LayoutColumn方法
gridLayout = findViewById(weekId[i]);
// 渲染每一行(节课)
for (int j = 1; j < 10; j += 2) {
// 声明一个新的TextView
TextView textView = new TextView(this); // 给TextView设置style样式
textView.setId(id++);
textView.setText("");
textView.setMaxLines(5);
textView.setEllipsize(TextUtils.TruncateAt.END); // TextView内容过长时,结尾加省略号
textView.setBackgroundColor(Color.parseColor("#F0FFFF"));
textView.setGravity(Gravity.CENTER); // GridLayout.LayoutParams设置在此gridLayout列中TextView布局
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.setMargins(5, 10, 5, 10);
params.width = GridLayout.LayoutParams.MATCH_PARENT;
params.height = 0;
// 设置在gridLayout中的方位,参数1:在第几行。参数2:占几行。参数3:权值
// 这个权值是根据xml中第一个gridLayout节课权值设定的。
params.rowSpec = GridLayout.spec(j, 2, 1); // 把TextView和布局样式添加到此gridLayout中
gridLayout.addView(textView, params);
}
}
Log.d(TAG, "initWeeks: id = " + id);
} @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, AddActivity.class);
startActivity(intent);
return true;
}
});
return super.onCreateOptionsMenu(menu);
} // 显示课程表数据
private void display(DBHelper dbHelper) {
// 从数据库获取课程数据保存到列表中
List<Classes> 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 tvClass = 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())) {
tvClass.setBackgroundColor(Color.rgb(28, 217, 204));
} // 课程表信息显示出来
tvClass.setText(aClass.getC_name() + "\n" + aClass.getC_teacher());
}
} @SuppressLint("Range")
public List<Classes> query(DBHelper dbHelper) {
List<Classes> classesList = new ArrayList<>();
// 通过DBHelper类获取一个读写的SQLiteDatabase对象
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(DBHelper.TABLE_NAME, null, null, null, null, null, null);
// 将游标移到开头
cursor.moveToFirst();
while (!cursor.isAfterLast()) { // 游标只要不是在最后一行之后,就一直循环
if (!cursor.getString(cursor.getColumnIndex("c_day")).equals("0")) {
Classes aClass = new Classes();
aClass.setC_id(Integer.parseInt(cursor.getString(cursor.getColumnIndex("c_id"))));
aClass.setC_name(cursor.getString(cursor.getColumnIndex("c_name")));
aClass.setC_time(cursor.getString(cursor.getColumnIndex("c_time")));
aClass.setC_day(cursor.getString(cursor.getColumnIndex("c_day")));
aClass.setC_teacher(cursor.getString(cursor.getColumnIndex("c_teacher")));
classesList.add(aClass);
}
// 将游标移到下一行
cursor.moveToNext();
}
db.close();
return classesList;
} }

5.修改AddActivity

增加更新数据的方法update(),给”保存“和”取消“按钮设置监听器。

package com.sdbi.classschedule;

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.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner; public class AddActivity extends AppCompatActivity {
private Spinner spinnerDay, spinnerTime;
private EditText edtSubject, edtTeacher;
private Button btnCancel, btnSave; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 继承AppCompatActivity的活动,要去掉标题栏,使用supportRequestWindowFeature()方法
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_add); // 当点击dialog之外完成此activity
setFinishOnTouchOutside(true); //关闭按钮操作
btnCancel = (Button) findViewById(R.id.btnCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AddActivity.this.finish();
}
}); //保存按钮操作
btnSave = findViewById(R.id.btnSave);
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(); spinnerDay = findViewById(R.id.spinnerDay);
String day = spinnerDay.getSelectedItem().toString(); if (day.equals("--请选择--")) {
btnSave.setError("");
return;
}
spinnerTime = findViewById(R.id.spinnerTime);
String time = spinnerTime.getSelectedItem().toString();
if (time.equals("--请选择--")) {
btnSave.setError("");
return;
} edtSubject = findViewById(R.id.edtSubject);
String text = edtSubject.getText().toString();
if ("".equals(text)) {
btnSave.setError("");
return;
} edtTeacher = findViewById(R.id.edtTeacher);
String teacher = edtTeacher.getText().toString();
if ("".equals(teacher)) {
btnSave.setError("");
return;
} // 创建一个数据库对象
DBHelper dbHelper = new DBHelper(AddActivity.this, MainActivity.DB_NAME, null, 1); // 把数据存在contentValues中
ContentValues contentValues = new ContentValues();
// getId()方法目的是通过星期几和第几节课算出对应该课程id
contentValues.put("c_id", getId(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(AddActivity.this, MainActivity.class);
startActivity(intent);
}
});
} public String getId(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();
// 修改数据
db.update(DBHelper.TABLE_NAME, contentValues, "c_id = ?", a);
// 释放连接
db.close();
}
}

至此,课程数据的添加和课程表的显示功能已经完成。

三、查看课程详细数据

1、创建课程详情布局文件

activity_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/myDialogStyle"
android:layout_width="300dp"
android:layout_height="350dp"
android:background="#fff"
android:orientation="vertical"
tools:context=".DetailActivity"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="课程详情"
android:textColor="@color/black"
android:textSize="30dp" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="时间:"
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" />
<TextView
android:id="@+id/tvDay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="节课:"
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" /> <TextView
android:id="@+id/tvTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="课程:"
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" /> <TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="任课教师:"
android:textColor="@color/cardview_dark_background"
android:textSize="20dp" /> <TextView
android:id="@+id/tvTeacher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:autoSizeMaxTextSize="30sp"
android:autoSizeMinTextSize="5sp"
android:autoSizeStepGranularity="1sp"
android:text=""
android:textColor="@color/cardview_dark_background"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>

2、创建Activity

DetailActivity.java

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
import android.widget.TextView; public class DetailActivity extends AppCompatActivity {
private TextView day, time, name, teacher; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_detail); Intent intent = getIntent();
name = findViewById(R.id.tvName);
name.setText(intent.getStringExtra("name")); day = findViewById(R.id.tvDay);
day.setText(intent.getStringExtra("day")); time = findViewById(R.id.tvTime);
time.setText(intent.getStringExtra("time")); teacher = findViewById(R.id.tvTeacher);
teacher.setText(intent.getStringExtra("teacher"));
}
}

3、修改清单文件

将DetailActivity配置为对话框式活动

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> <application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ClassSchedule"
tools:targetApi="31">
<activity
android:name=".DetailActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.Dialog"
>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".AddActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.Dialog">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application> </manifest>

4、修改MainActivity

添加单击事件打开课程详细页面

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;
import android.widget.TextView; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
public static final String DB_NAME = "classes_db.db";
private DBHelper dbHelper;
private List<Classes> classes = new ArrayList<Classes>(); private int[] weekId = {R.id.d1, R.id.d2, R.id.d3, R.id.d4, R.id.d5, R.id.d6, R.id.d7}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initWeeks(); // 初始化课程表控件 // 获得数据库管理类对象
dbHelper = new DBHelper(MainActivity.this, DB_NAME, null, 1); display(dbHelper); // 调用显示课程数据的方法
} public void initWeeks() {
//创建一个GridLayout对象
GridLayout gridLayout;
//定义每个框的id,之后会动态改变id值
int id = 1; //渲染每一列(周)
for (int i = 0; i < 7; i++) {
// 注入GridLayout对应的列,根据星期几调用LayoutColumn方法
gridLayout = findViewById(weekId[i]);
// 渲染每一行(节课)
for (int j = 1; j < 10; j += 2) {
// 声明一个新的TextView
TextView textView = new TextView(this); // 给TextView设置style样式
textView.setId(id++);
textView.setText("");
textView.setMaxLines(5);
textView.setEllipsize(TextUtils.TruncateAt.END); // TextView内容过长时,结尾加省略号
textView.setBackgroundColor(Color.parseColor("#F0FFFF"));
textView.setGravity(Gravity.CENTER); // GridLayout.LayoutParams设置在此gridLayout列中TextView布局
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.setMargins(5, 10, 5, 10);
params.width = GridLayout.LayoutParams.MATCH_PARENT;
params.height = 0;
// 设置在gridLayout中的方位,参数1:在第几行。参数2:占几行。参数3:权值
// 这个权值是根据xml中第一个gridLayout节课权值设定的。
params.rowSpec = GridLayout.spec(j, 2, 1); // 把TextView和布局样式添加到此gridLayout中
gridLayout.addView(textView, params);
}
}
} @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, AddActivity.class);
startActivity(intent);
return true;
}
});
return super.onCreateOptionsMenu(menu);
} // 显示课程表数据
private void display(DBHelper dbHelper) {
// 从数据库获取课程数据保存到列表中
classes = query(dbHelper);
Log.d(TAG, "display: classes.size() = " + classes.size()); for (Classes aClass : classes) {
Log.d(TAG, "display: id = " + aClass.getC_id() + ", time = " + aClass.getC_time() + ", day = " + aClass.getC_day());
// 第几节课,奇数节次,“1-2节”中的1,“5-6节”中的5
int i = Integer.parseInt(aClass.getC_time().charAt(0) + "");
// 星期几
int j = Utils.getDay(aClass.getC_day());
// 获取此课程对应TextView的id
TextView tvClass = 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())) {
tvClass.setBackgroundColor(Color.rgb(28, 217, 204));
} // 课程表信息显示出来
tvClass.setText(aClass.getC_name() + "\n" + aClass.getC_teacher()); // 单击此课程框
tvClass.setOnClickListener(MainActivity.this
);
}
} @SuppressLint("Range")
public List<Classes> query(DBHelper dbHelper) {
List<Classes> classesList = new ArrayList<>();
// 通过DBHelper类获取一个读写的SQLiteDatabase对象
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(DBHelper.TABLE_NAME, null, null, null, null, null, null);
// 将游标移到开头
cursor.moveToFirst();
while (!cursor.isAfterLast()) { // 游标只要不是在最后一行之后,就一直循环
if (!cursor.getString(cursor.getColumnIndex("c_day")).equals("0")) {
Classes aClass = new Classes();
aClass.setC_id(Integer.parseInt(cursor.getString(cursor.getColumnIndex("c_id"))));
aClass.setC_name(cursor.getString(cursor.getColumnIndex("c_name")));
aClass.setC_time(cursor.getString(cursor.getColumnIndex("c_time")));
aClass.setC_day(cursor.getString(cursor.getColumnIndex("c_day")));
aClass.setC_teacher(cursor.getString(cursor.getColumnIndex("c_teacher")));
classesList.add(aClass);
}
// 将游标移到下一行
cursor.moveToNext();
}
db.close();
return classesList;
} @SuppressLint("Range")
@Override
public void onClick(View v) {
TextView textView = (TextView) v;
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query(DBHelper.TABLE_NAME, null, "c_id = ?", new String[]{String.valueOf(textView.getId())}, null, null, null); // 将游标移到开头
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
Classes Class = new Classes();
Intent intent = new Intent();
intent.putExtra("day", cursor.getString(cursor.getColumnIndex("c_day")));
intent.putExtra("time", cursor.getString(cursor.getColumnIndex("c_time")));
intent.putExtra("name", cursor.getString(cursor.getColumnIndex("c_name")));
intent.putExtra("teacher", cursor.getString(cursor.getColumnIndex("c_teacher")));
intent.setClass(MainActivity.this, DetailActivity.class);
startActivity(intent);
}
}
}

运行程序,单击课程

四、删除课程

因为课程数据是在数据库初始化时固定了35条空白记录,所以,删除课程时,不能删除该条记录,而是应该将该记录设置为空。

因而删除课程,实际上是使用update()方法将该课程的每个字段设置为“0”.

另外,我们可以通过长按课程框弹出对话框来确认是否删除该课程。

修改MainActivity.java

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;
import android.widget.TextView; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnLongClickListener {
private static final String TAG = "MainActivity";
public static final String DB_NAME = "classes_db.db";
private DBHelper dbHelper;
private List<Classes> classes = new ArrayList<Classes>(); private int[] weekId = {R.id.d1, R.id.d2, R.id.d3, R.id.d4, R.id.d5, R.id.d6, R.id.d7}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initWeeks(); // 初始化课程表控件 // 获得数据库管理类对象
dbHelper = new DBHelper(MainActivity.this, DB_NAME, null, 1); display(dbHelper); // 调用显示课程数据的方法
} public void initWeeks() {
//创建一个GridLayout对象
GridLayout gridLayout;
//定义每个框的id,之后会动态改变id值
int id = 1; //渲染每一列(周)
for (int i = 0; i < 7; i++) {
// 注入GridLayout对应的列,根据星期几调用LayoutColumn方法
gridLayout = findViewById(weekId[i]);
// 渲染每一行(节课)
for (int j = 1; j < 10; j += 2) {
// 声明一个新的TextView
TextView textView = new TextView(this); // 给TextView设置style样式
textView.setId(id++);
textView.setText("");
textView.setMaxLines(5);
textView.setEllipsize(TextUtils.TruncateAt.END); // TextView内容过长时,结尾加省略号
textView.setBackgroundColor(Color.parseColor("#F0FFFF"));
textView.setGravity(Gravity.CENTER); // GridLayout.LayoutParams设置在此gridLayout列中TextView布局
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.setMargins(5, 10, 5, 10);
params.width = GridLayout.LayoutParams.MATCH_PARENT;
params.height = 0;
// 设置在gridLayout中的方位,参数1:在第几行。参数2:占几行。参数3:权值
// 这个权值是根据xml中第一个gridLayout节课权值设定的。
params.rowSpec = GridLayout.spec(j, 2, 1); // 把TextView和布局样式添加到此gridLayout中
gridLayout.addView(textView, params);
}
}
} @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, AddActivity.class);
startActivity(intent);
return true;
}
});
return super.onCreateOptionsMenu(menu);
} // 显示课程表数据
private void display(DBHelper dbHelper) {
// 从数据库获取课程数据保存到列表中
classes = query(dbHelper);
Log.d(TAG, "display: classes.size() = " + classes.size()); for (Classes aClass : classes) {
Log.d(TAG, "display: id = " + aClass.getC_id() + ", time = " + aClass.getC_time() + ", day = " + aClass.getC_day());
// 第几节课,奇数节次,“1-2节”中的1,“5-6节”中的5
int i = Integer.parseInt(aClass.getC_time().charAt(0) + "");
// 星期几
int j = Utils.getDay(aClass.getC_day());
// 获取此课程对应TextView的id
TextView tvClass = 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())) {
tvClass.setBackgroundColor(Color.rgb(28, 217, 204));
} // 课程表信息显示出来
tvClass.setText(aClass.getC_name() + "\n" + aClass.getC_teacher()); // 单击此课程框
tvClass.setOnClickListener(MainActivity.this); // 长按此课程框
tvClass.setOnLongClickListener(MainActivity.this
);
}
} @SuppressLint("Range")
public List<Classes> query(DBHelper dbHelper) {
List<Classes> classesList = new ArrayList<>();
// 通过DBHelper类获取一个读写的SQLiteDatabase对象
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(DBHelper.TABLE_NAME, null, null, null, null, null, null);
// 将游标移到开头
cursor.moveToFirst();
while (!cursor.isAfterLast()) { // 游标只要不是在最后一行之后,就一直循环
if (!cursor.getString(cursor.getColumnIndex("c_day")).equals("0")) {
Classes aClass = new Classes();
aClass.setC_id(Integer.parseInt(cursor.getString(cursor.getColumnIndex("c_id"))));
aClass.setC_name(cursor.getString(cursor.getColumnIndex("c_name")));
aClass.setC_time(cursor.getString(cursor.getColumnIndex("c_time")));
aClass.setC_day(cursor.getString(cursor.getColumnIndex("c_day")));
aClass.setC_teacher(cursor.getString(cursor.getColumnIndex("c_teacher")));
classesList.add(aClass);
}
// 将游标移到下一行
cursor.moveToNext();
}
db.close();
return classesList;
} @SuppressLint("Range")
@Override
public void onClick(View v) {
TextView textView = (TextView) v;
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query(DBHelper.TABLE_NAME, null, "c_id = ?", new String[]{String.valueOf(textView.getId())}, null, null, null); // 将游标移到开头
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
Classes Class = new Classes();
Intent intent = new Intent();
intent.putExtra("day", cursor.getString(cursor.getColumnIndex("c_day")));
intent.putExtra("time", cursor.getString(cursor.getColumnIndex("c_time")));
intent.putExtra("name", cursor.getString(cursor.getColumnIndex("c_name")));
intent.putExtra("teacher", cursor.getString(cursor.getColumnIndex("c_teacher")));
intent.setClass(MainActivity.this, DetailActivity.class);
startActivity(intent);
}
} @SuppressLint("ResourceType")
@Override
public boolean onLongClick(View v) {
TextView textView = (TextView) v;
Classes aClass = null;
int count = 0;
for (Classes bClass : classes) {
if (bClass.getC_id() == v.getId()) {
aClass = bClass;
break;
}
}
Log.d(TAG, "onLongClick: id = " + v.getId() + ":" + aClass.getC_name() + ":" + aClass.getC_day() + ":" + aClass.getC_time()); AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("删除");
builder.setMessage("确定要删除\n" + aClass.getC_day() + aClass.getC_time() + aClass.getC_name() + "?");
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { }
});
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("UPDATE " + DBHelper.TABLE_NAME + " SET c_name = '0', c_teacher = '0', c_day = '0', c_time = '0' WHERE c_id = ?", new String[]{String.valueOf(v.getId())}); // 启动MainActivity
Intent intent = new Intent();
intent.addFlags(intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
builder.show();
return true
;
}

}

运行程序

18.SQLite应用案例-课程表的更多相关文章

  1. Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)

    Linux基础:https://www.cnblogs.com/dunitian/p/4822808.html#linux 之前看到朋友还动不动 apt-get update upgrade,就很纳闷 ...

  2. 18 Loader代码案例

    目录结构: MainActivity.java 代码: package com.qf.day18_loader_demo2; import android.app.Activity; import a ...

  3. 18.Selenium+Python案例 -- 豆瓣

    一.具体代码实现: from selenium import webdriver driver = webdriver.Firefox() driver.get('https://www.douban ...

  4. SQLite源程序分析之sqlite3.c

    /****************************************************************************** ** This file is an a ...

  5. SQLite数据库 简介、特点、优势、局限性及使用

    SQLite简介 SQLite是一个进程内的轻量级嵌入式数据库,它的数据库就是一个文件,实现了自给自足.无服务器.零配置的.事务性的SQL数据库引擎.它是一个零配置的数据库,这就体现出来SQLite与 ...

  6. SQLite占用资源少原因

    本篇承接上篇SQLite详解的下篇,介绍SQLIte为什么占用资源少的原因?本文主要参考https://blog.csdn.net/hanyingzhong/article/details/46400 ...

  7. sql语法巧用之not取反

    数据库的重要性和通用性都不用说了,什么sql的通用性,sql优化之类的也不必说了,咱们今天来聊聊另一个有意思的话题:如何取一个筛选的反面案例. 1. 举几个正反案例的例子 为了让大家理解我们的假设场景 ...

  8. 新著作计划:《水利水电工程施工导流 水力计算与.NET编程》

    目   录 第一篇 基础理论篇 第1章 施工导截流设计概述 第2章 基本水力计算 2.1 临界水深计算 2.2 正常水深计算 2.3 堰流水力计算 2.4 明渠流水力计算 2.5 管流水力计算 第3章 ...

  9. 3.python基础补充(集合,collection系列,深浅拷贝)

    一.集合 1.集合(set): 把不同的元素组成一起形成集合,是python基本的数据类型.集合元素(set elements):组成集合的成员 python的set和其他语言类似, 是一个无序不重复 ...

  10. 【热门收藏】iOS开发人员必看的精品资料(100个)——下载目录

    iPhone.iPad产品风靡全球,巨大的用户群刺激着iOS软件开发需求,然而国内人才缺口很大,正处于供不应求的状态,ios开发前景大好.我们整理了51CTO下载中心100份热门的ios开发资料,做了 ...

随机推荐

  1. Navicat修改mysql表的字符集和排序规则

    突然想起前一阵子,在做javaweb后端debug的时候遇到的这个问题.由于在Dao层测试的时候没有尝试过中文的测试例,所以在Service写好后一直不报错但是无法插入数据库. 找了好久才发现是Mys ...

  2. SnowFlake 雪花算法详解与实现 & MP中的应用

    BackGround 现在的服务基本是分布式,微服务形式的,而且大数据量也导致分库分表的产生,对于水平分表就需要保证表中 id 的全局唯一性. 对于 MySQL 而言,一个表中的主键 id 一般使用自 ...

  3. JZOJ 3737. 【NOI2014模拟7.11】挖宝藏

    \(\text{Solution}\) 当 \(h=1\) 时显然是斯坦纳树板子,最方案必然是树形的 \(h > 1\) 时,考虑在每一层新建一个状态表示上一层宝藏全部挖完到这层某个点的答案 同 ...

  4. JZOJ 6800.NOIP2020.9.19模拟spongebob

    题目大意 求形如 \[\sum_{i=1}^n |a_ix + b_i| \] 的最小值 思路 我们显然可以先把系数 \(a\) 提出来 于是就成了 \(\sum_{i=1}^n |a_i|·|x + ...

  5. Gold Transportation

    题目 百度 分析 很容易想到二分答案 然后考虑判定 条件很多,奇奇怪怪 那就上网络流吧 边权 \(\leq mid\) 两个城市连边 \(inf\) 源点与所有城市连边,边权为本城市有金矿量 城市与自 ...

  6. honoka和格点三角形

    题目: honoka最近在研究三角形计数问题.她认为,满足以下三个条件的三角形是"好三角形".1.三角形的三个顶点均为格点,即横坐标和纵坐标均为整数.2.三角形的面积为 .3.三角 ...

  7. vue ie11 缺少 ':' html

    IE11 用vue 出现这错 怎么处理啊 ,用的html页做的 ,没用脚手架这类的东西 vue本身在没有babel做降级的情况下没法在IE上跑的,配个babel,还有polyfill这两个加上就好了 ...

  8. k8s(docker-desktop)简单搭建zookeeper三节点集群

    前提 已经安装了docker-desktop,并且其中的kubernetes启动运行的.或者安装了k8s环境就行 可以正常下载dockerhub的镜像,这里采用了dockerhub官方制作的镜像 启动 ...

  9. git 日常基本使用

    // 将远程仓库下的所有分支拉取到本地 git fetch origin // 将dev分支合并到当前所在的分支 git merge dev // 基于当前分支克隆出新的本地分支 git checko ...

  10. 简单介绍Python中如何给字典设置默认值

    这篇文章主要介绍了Python中如何给字典设置默认值问题,具有很好的参考价值,希望对大家有所帮助.如有错误或未考虑完全的地方,望不吝赐教 Python字典设置默认值 我们都知道,在 Python 的字 ...