diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index e0bb9b3..828dc84 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -22,20 +22,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index bfcb44d..b59ee59 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -11,8 +11,8 @@ android {
applicationId = "uk.kagurach.android101"
minSdk = 31
targetSdk = 34
- versionCode = 153
- versionName = "1.5.3"
+ versionCode = 155
+ versionName = "1.5.4"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -68,6 +68,7 @@ dependencies {
implementation(libs.androidx.annotation)
implementation(libs.androidx.lifecycle.livedata.ktx)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
+ implementation(libs.androidx.datastore.rxjava3)
testImplementation(libs.junit)
diff --git a/app/src/main/java/uk/kagurach/android101/Page3.java b/app/src/main/java/uk/kagurach/android101/Page3.java
index 098c32b..8abb09c 100644
--- a/app/src/main/java/uk/kagurach/android101/Page3.java
+++ b/app/src/main/java/uk/kagurach/android101/Page3.java
@@ -116,6 +116,7 @@ public class Page3 extends AppCompatActivity {
Button dot = findViewById(R.id.P3Dot);
switch (o) {
case "退格":
+ case "BackSpace":
if (!s.isEmpty()) {
if (s.length() == 1) {
s = "";
diff --git a/app/src/main/java/uk/kagurach/android101/Page5.java b/app/src/main/java/uk/kagurach/android101/Page5.java
index f7e4b6f..d1bbcbb 100644
--- a/app/src/main/java/uk/kagurach/android101/Page5.java
+++ b/app/src/main/java/uk/kagurach/android101/Page5.java
@@ -1,15 +1,32 @@
package uk.kagurach.android101;
+import android.content.Context;
import android.os.Bundle;
+import android.preference.Preference;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
+import androidx.datastore.rxjava3.RxDataStore;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import uk.kagurach.android101.misc.AutoCompleHelper.AnimalTypeAutoCompleteHelper;
public class Page5 extends AppCompatActivity {
+ AnimalTypeAutoCompleteHelper completeHelper = null;
+ RxDataStore mDataStore = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -20,5 +37,64 @@ public class Page5 extends AppCompatActivity {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
+
+
+ // Set auto-suggestions for animals
+ AutoCompleteTextView autoCompleteTextView = findViewById(R.id.AnimalTypeAutoCompleteInput);
+ try {
+ completeHelper = new AnimalTypeAutoCompleteHelper(this);
+ completeHelper.Load();
+ autoCompleteTextView.setAdapter(
+ completeHelper.GetArrayAdapter(
+ this,android.R.layout.simple_list_item_1
+ ));
+ } catch (IOException e){
+ Log.e("P5IOException", Objects.requireNonNull(e.getMessage()));
+ }
+
+ // Set Button Handler
+ Button P5AddAnimalButton = findViewById(R.id.P5AddAnimalButton);
+ P5AddAnimalButton.setOnClickListener(new AddAminalButtonHander());
}
-}
\ No newline at end of file
+
+
+
+ class AddAminalButtonHander implements View.OnClickListener {
+ @Override
+ public void onClick(View v) {
+ TextView name = findViewById(R.id.P5AnimalNameInput);
+ AutoCompleteTextView type = findViewById(R.id.AnimalTypeAutoCompleteInput);
+
+ if (name.getText().toString().isEmpty()||type.getText().toString().isEmpty()){
+ ToastHelper.SmartToast.ShowToast("Please input all fields",v.getContext());
+ }
+
+ try {
+ completeHelper.AddEntry(type.getText().toString());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ try {
+ completeHelper.Sync();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ type.setAdapter(
+ completeHelper.GetArrayAdapter(
+ v.getContext(),android.R.layout.simple_list_item_1
+ ));
+ }
+ }
+
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (getCurrentFocus() != null) {
+ InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+}
+
diff --git a/app/src/main/java/uk/kagurach/android101/misc/AutoCompleHelper/AbstractAutoCompleteHelper.java b/app/src/main/java/uk/kagurach/android101/misc/AutoCompleHelper/AbstractAutoCompleteHelper.java
new file mode 100644
index 0000000..cb8a67b
--- /dev/null
+++ b/app/src/main/java/uk/kagurach/android101/misc/AutoCompleHelper/AbstractAutoCompleteHelper.java
@@ -0,0 +1,77 @@
+package uk.kagurach.android101.misc.AutoCompleHelper;
+
+import android.content.Context;
+import android.widget.ArrayAdapter;
+
+import androidx.annotation.LayoutRes;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Scanner;
+import java.util.Set;
+
+public abstract class AbstractAutoCompleteHelper {
+ List data = null;
+ public String dataFile = null;
+ boolean loaded = false;
+
+ abstract void AddEntry(String name) throws IOException;
+ abstract void DeleteEntry(String name);
+ public void Load() throws IOException {
+ if (dataFile==null){
+ throw new RuntimeException("dataFile not specified");
+ }
+ File _data = new File(dataFile);
+ if (!_data.isFile()){
+ _data.createNewFile();
+ }
+ if (!_data.canRead() || !_data.canWrite()){
+ throw new RuntimeException("File permission denied");
+ }
+ loaded = true;
+ Scanner scanner = new Scanner(_data);
+
+ if (data == null) {
+ data = new ArrayList<>();
+ }else {
+ // 去重
+ Set set = new LinkedHashSet<>(data);
+ data = new ArrayList<>(set);
+ }
+ while (scanner.hasNextLine()){
+ data.add(scanner.nextLine());
+ }
+
+ }
+ public void Sync() throws IOException {
+ if (dataFile==null){
+ throw new RuntimeException("dataFile not specified");
+ }
+ File _data = new File(dataFile);
+ if (!_data.isFile()){
+ _data.createNewFile();
+ }
+ if (!_data.canRead() || !_data.canWrite()){
+ throw new RuntimeException("File permission denied");
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ for (String name:data) {
+ stringBuilder.append(name);
+ stringBuilder.append('\n');
+ }
+ try (FileWriter fileWriter = new FileWriter(_data,false)) {
+ fileWriter.write(stringBuilder.toString());
+ }
+ catch (IOException e){
+ throw new IOException(e);
+ }
+ }
+
+ public abstract ArrayAdapter GetArrayAdapter(
+ Context ctx, @LayoutRes int resource);
+}
diff --git a/app/src/main/java/uk/kagurach/android101/misc/AutoCompleHelper/AnimalTypeAutoCompleteHelper.java b/app/src/main/java/uk/kagurach/android101/misc/AutoCompleHelper/AnimalTypeAutoCompleteHelper.java
new file mode 100644
index 0000000..01f747d
--- /dev/null
+++ b/app/src/main/java/uk/kagurach/android101/misc/AutoCompleHelper/AnimalTypeAutoCompleteHelper.java
@@ -0,0 +1,49 @@
+package uk.kagurach.android101.misc.AutoCompleHelper;
+
+import android.content.Context;
+import android.widget.ArrayAdapter;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.LayoutRes;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class AnimalTypeAutoCompleteHelper extends AbstractAutoCompleteHelper {
+ public AnimalTypeAutoCompleteHelper(Context ctx) throws IOException {
+ dataFile = ctx.getFilesDir().getAbsolutePath() + File.separator + "animalTypes.dat";
+ Load();
+ }
+
+
+ @Override
+ public void AddEntry(String name) throws IOException {
+ if (!loaded){
+ throw new RuntimeException("Haven't loaded");
+ }
+ if (data.contains(name)){
+ return;
+ }
+ data.add(name);
+ Sync();
+ }
+
+ @Override
+ public void DeleteEntry(String name) {
+
+ }
+
+ @Override
+ public ArrayAdapter GetArrayAdapter(
+ Context ctx, @LayoutRes int resource) {
+ if (data == null) {
+ return new ArrayAdapter<>(ctx, resource,
+ new String[]{
+ "cat","dog","喵喵"
+ }
+ );
+ }
+ return new ArrayAdapter<>(ctx, resource, data);
+ }
+}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 80020c9..43522d8 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -32,6 +32,7 @@
android:layout_weight="1"
android:text="@string/next_page"
android:enabled="false"
+ android:backgroundTint="#81D4FA"
/>
diff --git a/app/src/main/res/layout/activity_page5.xml b/app/src/main/res/layout/activity_page5.xml
index 530c183..5a7835c 100644
--- a/app/src/main/res/layout/activity_page5.xml
+++ b/app/src/main/res/layout/activity_page5.xml
@@ -7,4 +7,114 @@
android:layout_height="match_parent"
tools:context=".Page5">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 80ce590..5bb6d93 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -17,4 +17,22 @@
AI 准备好了
你吃了吗?
振动手机
+ 动物管理系统\n当前后端: KV对
+ 姓名
+ 可爱喵
+ 类型
+ 喵喵
+ 添加
+ 清除数据
+ 添加页面
+ 你好,世界!
+ 下一页
+ 单击下一页,长按上一页
+ 测试文本
+ 设置颜色
+ 设置
+ 设置文本
+ 弱智计算器
+ 退格
+ 查询
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 72dda31..d6f9a5d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4,22 +4,14 @@
You haven\'t finished😇
Finish
Not Finish
- add_page
+ add_page
Edit Your TODO Item Here
Enter Title
Delete
Delete!!
Android101
- 你好,世界!
- 下一页
- 单击下一页,长按上一页
- 测试文本
- 设置颜色
- 设置
- 设置文本
- 弱智计算器
- 退格
+ BackSpace
Open TODO
User
AI
@@ -27,4 +19,20 @@
AI Ready
你吃了吗?
Vibrate
+ Animal Manage System\nCurrent Backend: KV Pair
+ Name
+ NachoNeko
+ Type
+ Cat
+ add
+ Clean DATA
+ Query
+ Simple Calc
+ Hello World!
+ Next Page
+ Next page for short press and previous for long
+ Test Text 123
+ Set Color
+ Set
+ Set Text
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index ec70d6e..982620a 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -2,15 +2,15 @@
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index c03bfb8..dff1290 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,15 +1,15 @@
[versions]
-agp = "8.3.2"
+agp = "8.4.1"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
-appcompat = "1.6.1"
+appcompat = "1.7.0"
material = "1.12.0"
activity = "1.9.0"
constraintlayout = "2.1.4"
-lifecycleRuntimeKtx = "2.8.0"
+lifecycleRuntimeKtx = "2.8.1"
activityCompose = "1.9.0"
composeBom = "2024.05.00"
roomCommon = "2.6.1"
@@ -17,8 +17,9 @@ roomKtx = "2.6.1"
navigationFragmentKtx = "2.7.7"
navigationUiKtx = "2.7.7"
annotation = "1.8.0"
-lifecycleLivedataKtx = "2.8.0"
-lifecycleViewmodelKtx = "2.8.0"
+lifecycleLivedataKtx = "2.8.1"
+lifecycleViewmodelKtx = "2.8.1"
+datastoreRxjava3 = "1.1.1"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -46,6 +47,7 @@ androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation
androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "annotation" }
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
+androidx-datastore-rxjava3 = { group = "androidx.datastore", name = "datastore-rxjava3", version.ref = "datastoreRxjava3" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b55fa81..adcea3f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Fri Mar 08 22:31:04 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists