一、程序界面

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. C# File、FileInfo、Directory、DirectoryInfo

    本文主要介绍文件类.文件信息类.目录类.目录信息类的常用属性和方法 1.File(文件类) // 1.判断文件是否存在 bool isFileExist = File.Exists(@"D: ...

  2. Netty进阶

    1.Netty问题 TCP协议都存在着黏包和半包问题,但是UDP没有 1.粘包现象 发送方分10次发送,接收方一次接受了10次发送的消息 2.半包现象 调整服务器的接受缓冲区大小(调小) 半包会导致服 ...

  3. CSS_语法格式

    * 格式: 选择器{ 属性名1:属性值1: 属性名2:属性值2: ... } *选择器:筛选具有相似特征的元素 *注意: *没一对属性需要使用":"隔开,对最后一对属性可以不加&q ...

  4. 一篇文章让你了解这个基于树莓派而设计的工业计算机-CM4 Industrial

    CM4 Industrial是一款基于 Raspberry Pi / 树莓派 Compute Module 4,由EDATEC面向工业应用设计的嵌入式计算机设计的工业嵌入式计算机.系统可以根据不同的应 ...

  5. JZOJ 3469. 【NOIP2013模拟联考7】数列(sequence)

    \(\text{Solution}\) 明显的 \(\text{K-D Tree}\) 基操题 提前给出了数列,那么考虑提前建好树,省去重构 但还是要开 \(O\) \(\text{Code}\) # ...

  6. NameError: name '_name_' is not defined

    if _name_ == '_main_': 错误的原因可能是name是双下划线.(明显下面的下划线要长一点) if __name_ == '_main__':

  7. 一文吃透 Go 内置 RPC 原理

    hello 大家好呀,我是小楼,这是系列文<Go底层原理剖析>的第三篇,依旧分析 Http 模块.我们今天来看 Go内置的 RPC.说起 RPC 大家想到的一般是框架,Go 作为编程语言竟 ...

  8. 3. 贪心思想(todo)

    目录 1. 分配饼干 2. 不重叠区间个数 3. 投飞镖刺破气球 5. 买卖股票最大的收益 6. 买卖股票的最大收益 II 9. 修改一个数成为非递减数组 10. 子数组的最大和 11. 分隔字符串使 ...

  9. DRF排序

    排序 对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序. 使用方法: 在类视图中设置filter_backends, 使用 ...

  10. 数据类型之字符串(string)(四)

    字符串本质是:字符序列不可变1.字符串编码,Unicode ord('A') ord('王') 2.创建字符串,引号 a = 'Hello python!' b = "I'm a teach ...