From ebeab323fbf5f02a638eb914500107265397eea4 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 00:59:54 +0000
Subject: [PATCH 01/14] feat: user dict saved to disk every time hide keyboard
---
app/src/main/java/com/osfans/trime/ime/core/Trime.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index 98437e361c..5a70594a9e 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -918,6 +918,7 @@ public void commitTextByChar(String text) {
private boolean handleBack(int keyCode) {
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
requestHideSelf(0);
+ Rime.finalize1();
return true;
}
return false;
From 7b48015d7830400e3c33916e360e7a2f5655bde6 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 09:33:45 +0800
Subject: [PATCH 02/14] feat: destroy rime every time keyboard hide
---
app/src/main/java/com/osfans/trime/ime/core/Trime.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index 5a70594a9e..6880008ca7 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -918,7 +918,9 @@ public void commitTextByChar(String text) {
private boolean handleBack(int keyCode) {
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
requestHideSelf(0);
- Rime.finalize1();
+ Rime.destroy();
+ getImeConfig().destroy();
+ System.exit(0); // 清理內存
return true;
}
return false;
From 279103bd819d219c1e2532f519d2195692c4725c Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 10:37:10 +0800
Subject: [PATCH 03/14] feat: update rime destroy time
---
app/src/main/java/com/osfans/trime/ime/core/Trime.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index 6880008ca7..d7daeafccd 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -301,6 +301,7 @@ public void onWindowHidden() {
}
isWindowShown = false;
+ Rime.destroy();
if (getPrefs().getConf().getSyncBackgroundEnabled()) {
final Message msg = new Message();
msg.obj = this;
@@ -918,9 +919,6 @@ public void commitTextByChar(String text) {
private boolean handleBack(int keyCode) {
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
requestHideSelf(0);
- Rime.destroy();
- getImeConfig().destroy();
- System.exit(0); // 清理內存
return true;
}
return false;
From e8de9ac7bf288f895db580e5e30662e70f46c400 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 11:00:04 +0800
Subject: [PATCH 04/14] feat: update destory time to onWindowHidden
---
app/src/main/java/com/osfans/trime/core/Rime.java | 6 ++++++
.../java/com/osfans/trime/ime/core/Trime.java | 15 ++++++++++++++-
.../java/com/osfans/trime/util/ShortcutUtils.kt | 4 ++++
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/com/osfans/trime/core/Rime.java b/app/src/main/java/com/osfans/trime/core/Rime.java
index 94862df7aa..e36d843cf8 100644
--- a/app/src/main/java/com/osfans/trime/core/Rime.java
+++ b/app/src/main/java/com/osfans/trime/core/Rime.java
@@ -691,6 +691,12 @@ public static boolean syncUserData(Context context) {
return b;
}
+ public static boolean saveUserData(Context context) {
+ destroy();
+ get(context, true);
+ return true;
+ }
+
// init
public static native void setup(String shared_data_dir, String user_data_dir);
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index d7daeafccd..2167c047f5 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -258,6 +258,16 @@ public static Trime getServiceOrNull() {
}
return false;
});
+
+ private static final Handler writeUserDataHandler =
+ new Handler(
+ msg -> {
+ if (!((Trime) msg.obj).isShowInputRequested()) { // 若当前没有输入面板,则后台同步。防止面板关闭后5秒内再次打开
+ ShortcutUtils.INSTANCE.writeUserData((Trime) msg.obj);
+ ((Trime) msg.obj).loadConfig();
+ }
+ return false;
+ });
public Trime() {
try {
@@ -301,11 +311,14 @@ public void onWindowHidden() {
}
isWindowShown = false;
- Rime.destroy();
if (getPrefs().getConf().getSyncBackgroundEnabled()) {
final Message msg = new Message();
msg.obj = this;
syncBackgroundHandler.sendMessageDelayed(msg, 5000); // 输入面板隐藏5秒后,开始后台同步
+ } else {
+ final Message msg = new Message();
+ msg.obj = this;
+ writeUserDataHandler.sendMessageDelayed(msg, 5000); // 输入面板隐藏5秒后,开始后台同步
}
Timber.d(methodName + "eventListeners");
diff --git a/app/src/main/java/com/osfans/trime/util/ShortcutUtils.kt b/app/src/main/java/com/osfans/trime/util/ShortcutUtils.kt
index b56a8bc258..a0cd2a6507 100644
--- a/app/src/main/java/com/osfans/trime/util/ShortcutUtils.kt
+++ b/app/src/main/java/com/osfans/trime/util/ShortcutUtils.kt
@@ -128,6 +128,10 @@ object ShortcutUtils {
prefs.conf.lastSyncStatus = Rime.syncUserData(context)
}
+ fun writeUserData(context: Context) {
+ Rime.saveUserData(context)
+ }
+
fun openCategory(keyCode: Int): Boolean {
val category = applicationLaunchKeyCategories[keyCode]
return if (category != null) {
From 9f290748893ee54f19b2ae18212baba1f538ff85 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 12:17:51 +0800
Subject: [PATCH 05/14] fix: removed unused space
---
app/src/main/java/com/osfans/trime/ime/core/Trime.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index 2167c047f5..ae2de64636 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -258,7 +258,7 @@ public static Trime getServiceOrNull() {
}
return false;
});
-
+
private static final Handler writeUserDataHandler =
new Handler(
msg -> {
From e25163f060a11c16b7bb7b5eeef217775530f0d7 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 13:32:17 +0800
Subject: [PATCH 06/14] feat: manage data in clipboard / draft / collection by
tumuyan
---
app/src/main/AndroidManifest.xml | 4 +
app/src/main/assets/rime/trime.yaml | 11 +-
.../osfans/trime/data/db/CollectionDao.java | 92 ++++++++++
.../java/com/osfans/trime/data/db/DbBean.java | 2 +-
.../trime/data/db/clipboard/ClipboardDao.java | 16 +-
.../osfans/trime/data/db/draft/DraftDao.java | 22 ++-
.../java/com/osfans/trime/ime/core/Trime.java | 4 +-
.../trime/ime/enums/SymbolKeyboardType.kt | 3 +
.../trime/ime/symbol/CheckableAdatper.java | 109 ++++++++++++
.../trime/ime/symbol/CollectionAdapter.java | 159 ++++++++++++++++++
.../trime/ime/symbol/LiquidKeyboard.java | 54 +++++-
.../trime/settings/LiquidKeyboardActivity.kt | 135 +++++++++++++++
.../trime/settings/fragments/OtherFragment.kt | 22 +++
app/src/main/res/layout/checkable_item.xml | 26 +++
.../res/layout/liquid_keyboard_activity.xml | 67 ++++++++
app/src/main/res/values-zh-rCN/strings.xml | 6 +
app/src/main/res/values-zh-rTW/strings.xml | 6 +
app/src/main/res/xml/other_preference.xml | 11 ++
18 files changed, 736 insertions(+), 13 deletions(-)
create mode 100644 app/src/main/java/com/osfans/trime/data/db/CollectionDao.java
create mode 100644 app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java
create mode 100644 app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java
create mode 100644 app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt
create mode 100644 app/src/main/res/layout/checkable_item.xml
create mode 100644 app/src/main/res/layout/liquid_keyboard_activity.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aee06a25e6..938d25a3cd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -77,6 +77,10 @@
+
diff --git a/app/src/main/assets/rime/trime.yaml b/app/src/main/assets/rime/trime.yaml
index 1c1e8cd65e..c3d5d70aca 100644
--- a/app/src/main/assets/rime/trime.yaml
+++ b/app/src/main/assets/rime/trime.yaml
@@ -693,7 +693,7 @@ liquid_keyboard:
single_width: 60 #single类型的按键宽度
vertical_gap: 1 #纵向按键间隙
margin_x: 0.5 #左右按键间隙的1/2
- keyboards: [emoji, math, ascii, cn, history, clipboard, draft, tabs, exit, candidate, list, ids , table, symbol, unit, new, jp, pinyin, grease, rusa, korea, lation, yinbiao, exit] #tab列表
+ keyboards: [emoji, math, ascii, cn, history, clipboard, draft, collection, tabs, exit, candidate, list, ids , table, symbol, unit, new, jp, pinyin, grease, rusa, korea, lation, yinbiao, yanwenzi, exit] #tab列表
exit:
name: 返回
type: NO_KEY
@@ -712,10 +712,13 @@ liquid_keyboard:
type: HISTORY
emoji:
type: SINGLE
- keys: "🙂😂🤣😆🙃😅🙈🙉🙊☹😑😄🤐😨😱🌚🌝🤔❤💔♡🌹💣👌👍😣😥😮🙄😏😕😯😪😫😴😌🤑😉😋😎😍😘😚😛😜😝😒😓😔😲😷🤒😇🤓🤗🤕🙁😖😞😟😤😢😭😦😧😨😩😬😰😳😵😡😠☝✌🖕👎🙏🤘👏💪💋☘🍀🌸☕🍵🍺🍻🍦🍬🍚🍜🍲🍖🎂💤"
+ keys: "🙂😂🤣😆🙃😅🥺🙈🙉🙊☹😑😄🤐😨😱🌚🌝🤔❤💔🌹💣👌👍😣😥😮🙄😏😕😯😪😫😴😌🤑😉😋😎😍😘😚😛😜😝😒😓😔😲😷🤒😇🤓🤗🤕🙁😖😞😟😤😢😭😦😧😨😩😬😰😳😵😡😠☝✌🖕👎🙏🤘👏💪💋☘🍀🌸☕🍵🍺🍻🍦🍬🍚🍜🍲🍖🎂💤"
clipboard:
type: CLIPBOARD
name: 剪贴
+ collection:
+ type: COLLECTION
+ name: 收藏
draft:
type: DRAFT
name: 草稿
@@ -792,6 +795,10 @@ liquid_keyboard:
type: SINGLE
name: "音标"
keys: ["a:", "ɔ:", "ɜː", "i:", "u:", "ʌ", "ɒ", "ə", "ɪ", "ʊ", "e", "æ", "eɪ", "aɪ", "ɔɪ", "ɪə", "eə", "ʊə", "əʊ", "aʊ", "p", "t", "k", "f", "θ", "s", "b", "d", "g", "v", "ð", "z", "ʃ", "h", "ts", "tʃ", "j", "tr", "ʒ", "r", "dz", "dʒ", "dr", "w", "m", "n", "ŋ", "l"]
+ yanwenzi:
+ type: VAR_LENGTH
+ name: "颜文字"
+ keys: ["⎛⎝≥⏝⏝≤⎠⎞", "^_^", "^ω^", "^o^", "~\\(≧▽≦)/~", "*^_^*", "↖(^ω^)↗", "(^o^)/", "(=^▽^=)", "=^_^=", "(*^ω^*)", "٩(๑^o^๑)۶", "o( ̄▽ ̄)o", "Y(^_^)Y", "٩( 'ω' )و", "╰(*´︶`*)╯", "*罒▽罒*", "ヾ ^_^♪", "= ̄ω ̄=", "︿( ̄︶ ̄)︿", "(´▽`)ノ♪", "乁( ˙ ω˙乁)", "✧*。٩(ˊωˋ*)و✧*。", "~( ̄▽ ̄~)(~ ̄▽ ̄)~", "QwQ", "(●—●)", "(๑• . •๑)", "ヾ(≧O≦)〃嗷~", "罒ω罒", "(。ì _ í。)", "(๑•ี_เ•ี๑)", "ㄟ(≧◇≦)ㄏ", "(*/ω\*)", "●▽●", "٩(๑òωó๑)۶", "✺◟(∗❛ัᴗ❛ั∗)◞✺", "( σ'ω')σ", "♡^▽^♡", "(๑•̀ㅂ•́)و✧", "(ง •̀_•́)ง", "(。・ω・。)ノ♡", "(☆_☆)", "(๑°3°๑)", "_(•̀ω•́ 」∠)_", "♪~(´ε` )", "~(^з^)-☆", "(´∀`)♡", "ლ(´ڡ`ლ)", "(>﹏<)", "T_T", "⊙︿⊙", "〒▽〒", "⊙﹏⊙", "π_π", "(。•́︿•̀。)", "(ToT)/~~~", "╯﹏╰", "ಥ_ಥ", "(╥╯^╰╥)", "(〃′o`)", "●﹏●", "( •̥́ ˍ •̀ू )", "(つд⊂)", "心塞(´-ωก`)", "(╥﹏╥)", "┭┮﹏┭┮", "(;´д`)ゞ", "(´;︵;`)", "(。﹏。)", "┗( T﹏T )┛", "QAQ", "ヘ(_ _ヘ)", "╰(‵□′)╯", "(* ̄︿ ̄)", ">o<", "(-`ェ´-怒)", "ヽ(‘⌒´メ)ノ", "(*`Ω´*)v", "(。•ˇ‸ˇ•。)", "(怒`Д´怒)", "٩(๑`^´๑)۶", "(;`O´)o", "╰_╯", "(#`皿´)<怒怒怒!!!", "<(`^´)>", "(`Δ´)!", "ψ(`∇´)ψ", "(;′⌒`)", "s(・`ヘ´・;)ゞ", "(▼皿▼#)", " ̄へ ̄", "←_←", "(╯‵□′)╯︵┴─┴", "(▼へ▼メ)", "☄ฺ(◣д◢)☄ฺ", "→_→", "⊙_⊙", "d(ŐдŐ๑)", "Σ( ° △ °|||)︴", "(((φ(◎ロ◎;)φ)))", "⊙▽⊙", "(๑ŐдŐ)b", "╭(°A°`)╮", "(๑òᆺó๑)", "⊙ω⊙", "Σ(っ °Д °;)っ", " (゚Д゚≡゚д゚)!?", "( *・ω・)✄╰ひ╯", "(⊙x⊙;)", "┌(。Д。)┐", "(°ー°〃)", "︽⊙_⊙︽", "!!!∑(°Д°ノ)ノ", "(๑ŐдŐ)b☆d(ŐдŐ๑)", "Σ⊙▃⊙川", "ヽ(*。>Д<)o゜", "━((*′д`)爻(′д`*))━!!!!", "=_=", "╮(╯_╰)╭", "(︶︿︶)", "_(:з」∠)_", "@_@", "╮(╯▽╰)╭", "(@ ̄ー ̄@)", "_(:3」∠❀)_", "눈_눈", "╭(╯ε╰)╮", "(ー_ー)!!", "_(:D)∠)_", "o_O", "╭(╯^╰)╮", "(;一_一)", "´_>`", "-_-#", "┑( ̄Д  ̄)┍", "≡ ̄﹏ ̄≡", "○| ̄|_", "-_-||", "ㄟ( ▔, ▔ )ㄏ", "( _ _)ノ|壁", "▄█▀█●"]
ascii:
type: SINGLE
name: 英文
diff --git a/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java b/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java
new file mode 100644
index 0000000000..62cb4cf9cb
--- /dev/null
+++ b/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java
@@ -0,0 +1,92 @@
+package com.osfans.trime.data.db;
+
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import androidx.annotation.NonNull;
+import com.osfans.trime.ime.core.Trime;
+import com.osfans.trime.ime.symbol.SimpleKeyBean;
+import java.util.ArrayList;
+import java.util.List;
+import timber.log.Timber;
+
+public class CollectionDao {
+
+ private DbHelper helper;
+ private static CollectionDao self;
+ private static String DB_NAME = "collection.db";
+
+ public static CollectionDao get() {
+ if (null == self) self = new CollectionDao();
+ return self;
+ }
+
+ public CollectionDao() {}
+
+ /** 插入新记录 * */
+ public void insert(@NonNull DbBean clipboardBean) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ db.execSQL(
+ "insert into t_data(text,html,type,time) values(?,?,?,?)",
+ new Object[] {
+ clipboardBean.getText(),
+ clipboardBean.getHtml(),
+ clipboardBean.getType(),
+ clipboardBean.getTime()
+ });
+ db.close();
+ }
+
+ /** 删除文字相同的剪贴板记录,插入新记录 * */
+ public void add(@NonNull DbBean clipboardBean) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ db.delete("t_data", "text=?", new String[] {clipboardBean.getText()});
+ db.execSQL(
+ "insert into t_data(text,html,type,time) values(?,?,?,?)",
+ new Object[] {
+ clipboardBean.getText(),
+ clipboardBean.getHtml(),
+ clipboardBean.getType(),
+ clipboardBean.getTime()
+ });
+ db.close();
+ }
+
+ /** 删除记录 * */
+ public void delete(@NonNull String str) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ db.delete("t_data", "text=?", new String[] {str});
+ db.close();
+ }
+
+ public void delete(@NonNull List list) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ for (SimpleKeyBean bean : list) db.delete("t_data", "text=?", new String[] {bean.getText()});
+ db.close();
+ }
+
+ public List getAllSimpleBean() {
+
+ List list = new ArrayList<>();
+
+ String sql = "select text , html , type , time from t_data ORDER BY time DESC";
+
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+
+ SQLiteDatabase db = helper.getWritableDatabase();
+ Cursor cursor = db.rawQuery(sql, null);
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ DbBean v = new DbBean(cursor.getString(0));
+ list.add(v);
+ }
+ cursor.close();
+ }
+ db.close();
+ Timber.d("getAllSimpleBean() size=%s", list.size());
+ return list;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/osfans/trime/data/db/DbBean.java b/app/src/main/java/com/osfans/trime/data/db/DbBean.java
index 72e52e98f6..95e5705abb 100644
--- a/app/src/main/java/com/osfans/trime/data/db/DbBean.java
+++ b/app/src/main/java/com/osfans/trime/data/db/DbBean.java
@@ -6,7 +6,7 @@ public class DbBean extends SimpleKeyBean {
private long time;
private String text;
private final String html;
- private int type;
+ private int type; // 0 text, 1 html
public long getTime() {
return time;
diff --git a/app/src/main/java/com/osfans/trime/data/db/clipboard/ClipboardDao.java b/app/src/main/java/com/osfans/trime/data/db/clipboard/ClipboardDao.java
index 621b4aa61c..25ad1a8f0e 100644
--- a/app/src/main/java/com/osfans/trime/data/db/clipboard/ClipboardDao.java
+++ b/app/src/main/java/com/osfans/trime/data/db/clipboard/ClipboardDao.java
@@ -15,6 +15,7 @@ public class ClipboardDao {
private DbHelper helper;
private static ClipboardDao self;
+ private static String DB_NAME = "clipboard.db";
public static ClipboardDao get() {
if (null == self) self = new ClipboardDao();
@@ -25,7 +26,7 @@ public ClipboardDao() {}
/** 插入新记录 * */
public void insert(@NonNull DbBean clipboardBean) {
- helper = new DbHelper(Trime.getService(), "clipboard.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL(
"insert into t_data(text,html,type,time) values(?,?,?,?)",
@@ -40,7 +41,7 @@ public void insert(@NonNull DbBean clipboardBean) {
/** 删除文字相同的剪贴板记录,插入新记录 * */
public void add(@NonNull DbBean clipboardBean) {
- helper = new DbHelper(Trime.getService(), "clipboard.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
db.delete("t_data", "text=?", new String[] {clipboardBean.getText()});
db.execSQL(
@@ -56,12 +57,19 @@ public void add(@NonNull DbBean clipboardBean) {
/** 删除记录 * */
public void delete(@NonNull String str) {
- helper = new DbHelper(Trime.getService(), "clipboard.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
db.delete("t_data", "text=?", new String[] {str});
db.close();
}
+ public void delete(@NonNull List list) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ for (SimpleKeyBean bean : list) db.delete("t_data", "text=?", new String[] {bean.getText()});
+ db.close();
+ }
+
public List getAllSimpleBean(int size) {
List list = new ArrayList<>();
@@ -70,7 +78,7 @@ public List getAllSimpleBean(int size) {
String sql = "select text , html , type , time from t_data ORDER BY time DESC";
if (size > 0) sql = sql + " limit 0," + size;
- helper = new DbHelper(Trime.getService(), "clipboard.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery(sql, null);
diff --git a/app/src/main/java/com/osfans/trime/data/db/draft/DraftDao.java b/app/src/main/java/com/osfans/trime/data/db/draft/DraftDao.java
index fac654aef0..f9aa91129e 100644
--- a/app/src/main/java/com/osfans/trime/data/db/draft/DraftDao.java
+++ b/app/src/main/java/com/osfans/trime/data/db/draft/DraftDao.java
@@ -16,6 +16,7 @@ public class DraftDao {
private SQLiteOpenHelper helper;
private static DraftDao self;
+ private static String DB_NAME = "draft.db";
public static DraftDao get() {
if (null == self) self = new DraftDao();
@@ -26,7 +27,7 @@ public DraftDao() {}
/** 插入新记录 * */
public void insert(@NonNull DbBean bean) {
- helper = new DbHelper(Trime.getService(), "draft.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL(
"insert into t_data(text,html,type,time) values(?,?,?,?)",
@@ -36,7 +37,7 @@ public void insert(@NonNull DbBean bean) {
/** 删除文字相同的记录,插入新记录 * */
public void add(@NonNull DbBean bean) {
- helper = new DbHelper(Trime.getService(), "draft.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
db.delete("t_data", "text=?", new String[] {bean.getText()});
db.execSQL(
@@ -45,6 +46,21 @@ public void add(@NonNull DbBean bean) {
db.close();
}
+ /** 删除记录 * */
+ public void delete(@NonNull String str) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ db.delete("t_data", "text=?", new String[] {str});
+ db.close();
+ }
+
+ public void delete(@NonNull List list) {
+ helper = new DbHelper(Trime.getService(), DB_NAME);
+ SQLiteDatabase db = helper.getWritableDatabase();
+ for (SimpleKeyBean bean : list) db.delete("t_data", "text=?", new String[] {bean.getText()});
+ db.close();
+ }
+
public List getAllSimpleBean(int size) {
List list = new ArrayList<>();
@@ -53,7 +69,7 @@ public List getAllSimpleBean(int size) {
String sql = "select text , html , type , time from t_data ORDER BY time DESC";
if (size > 0) sql = sql + " limit 0," + size;
- helper = new DbHelper(Trime.getService(), "draft.db");
+ helper = new DbHelper(Trime.getService(), DB_NAME);
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery(sql, null);
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index ae2de64636..9fa55a48d9 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -62,6 +62,7 @@
import com.osfans.trime.core.Rime;
import com.osfans.trime.data.AppPrefs;
import com.osfans.trime.data.Config;
+import com.osfans.trime.data.db.CollectionDao;
import com.osfans.trime.data.db.clipboard.ClipboardDao;
import com.osfans.trime.data.db.draft.DraftDao;
import com.osfans.trime.databinding.CompositionRootBinding;
@@ -237,9 +238,7 @@ public void run() {
};
@Synchronized
- @NonNull
public static Trime getService() {
- assert self != null;
return self;
}
@@ -405,6 +404,7 @@ public void onCreate() {
new LiquidKeyboard(
this, getImeConfig().getClipboardLimit(), getImeConfig().getDraftLimit());
clipBoardMonitor();
+ CollectionDao.get();
DraftDao.get();
} catch (Exception e) {
e.printStackTrace();
diff --git a/app/src/main/java/com/osfans/trime/ime/enums/SymbolKeyboardType.kt b/app/src/main/java/com/osfans/trime/ime/enums/SymbolKeyboardType.kt
index b77945efb3..2f2bdb400d 100644
--- a/app/src/main/java/com/osfans/trime/ime/enums/SymbolKeyboardType.kt
+++ b/app/src/main/java/com/osfans/trime/ime/enums/SymbolKeyboardType.kt
@@ -16,6 +16,9 @@ enum class SymbolKeyboardType {
// 剪贴板(大段文本自动缩略,按键长度自适应。)
CLIPBOARD,
+ // 收藏的文本, 复用剪贴板
+ COLLECTION,
+
// 文本框编辑历史,即“草稿箱”
DRAFT,
diff --git a/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java b/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java
new file mode 100644
index 0000000000..1680022f60
--- /dev/null
+++ b/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java
@@ -0,0 +1,109 @@
+package com.osfans.trime.ime.symbol;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import com.osfans.trime.R;
+import com.osfans.trime.data.db.CollectionDao;
+import com.osfans.trime.data.db.DbBean;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class CheckableAdatper extends ArrayAdapter {
+ private LayoutInflater layoutInflater = null;
+ private List words;
+
+ public List getChecked() {
+ return checked;
+ }
+
+ private List checked;
+
+ public CheckableAdatper(@NonNull Context context, int resource, @NonNull List objects) {
+ super(context, resource, objects);
+ layoutInflater = LayoutInflater.from(context);
+ words = objects;
+ checked = new ArrayList<>();
+ Log.i("UserDictAdatper", "set words.size=" + words.size());
+ }
+
+ public void clickItem(int position) {
+ if (checked.contains(position)) checked.remove((Integer) position);
+ else checked.add(position);
+
+ notifyDataSetChanged();
+ }
+
+ public List remove(int checkPositon) {
+ Collections.sort(checked, Collections.reverseOrder());
+ List result = new ArrayList<>();
+ for (int i : checked) {
+ if (i > words.size()) continue;
+ result.add(words.get(i));
+ words.remove(i);
+ }
+ checked.clear();
+
+ if (checkPositon >= 0) checked.add(checkPositon);
+
+ notifyDataSetChanged();
+ return result;
+ }
+
+ public List collectSelected() {
+ Collections.sort(checked, Collections.reverseOrder());
+ List result = new ArrayList<>();
+ for (int i : checked) {
+ if (i > words.size()) continue;
+ SimpleKeyBean bean = words.get(i);
+ result.add(bean);
+ CollectionDao.get().insert(new DbBean(bean.getText()));
+ }
+ return result;
+ }
+
+ @Override
+ public int getCount() {
+ return words.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return words.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ private static class ViewHolder {
+ private TextView textView;
+ private CheckBox checkBox;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // 优化后
+ ViewHolder holder;
+ if (convertView == null) {
+ convertView = layoutInflater.inflate(R.layout.checkable_item, null);
+ holder = new ViewHolder();
+ holder.textView = (TextView) convertView.findViewById(R.id.textView);
+ holder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+ holder.checkBox.setText(words.get(position).getText());
+ holder.checkBox.setChecked(checked.contains(position));
+ return convertView;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java b/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java
new file mode 100644
index 0000000000..0d6723fa20
--- /dev/null
+++ b/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java
@@ -0,0 +1,159 @@
+package com.osfans.trime.ime.symbol;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import com.blankj.utilcode.util.ToastUtils;
+import com.google.android.flexbox.FlexboxLayoutManager;
+import com.osfans.trime.R;
+import com.osfans.trime.data.Config;
+import java.util.List;
+
+public class CollectionAdapter extends RecyclerView.Adapter {
+ private final Context myContext;
+ private final List list;
+ private int keyMarginX, keyMarginTop;
+ private Integer textColor;
+ private float textSize;
+ private Typeface textFont;
+ private Config config;
+
+ public CollectionAdapter(Context context, List itemlist) {
+ myContext = context;
+ list = itemlist;
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ public void configStyle(int keyMarginX, int keyMarginTop) {
+ this.keyMarginX = keyMarginX;
+ this.keyMarginTop = keyMarginTop;
+
+ // 边框尺寸、圆角、字号直接读取主题通用参数。配色优先读取 liquidKeyboard 专用参数。
+ config = Config.get(myContext);
+ textColor = config.getLiquidColor("long_text_color");
+ if (textColor == null) textColor = config.getLiquidColor("key_text_color");
+
+ textSize = config.getFloat("key_long_text_size");
+ if (textSize <= 0) textSize = config.getFloat("label_text_size");
+
+ textFont = config.getFont("long_text_font");
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(myContext).inflate(R.layout.simple_key_item, parent, false);
+ return new ItemViewHolder(view);
+ }
+
+ static class ItemViewHolder extends RecyclerView.ViewHolder {
+ public ItemViewHolder(View view) {
+ super(view);
+
+ listItemLayout = view.findViewById(R.id.listitem_layout);
+ mTitle = view.findViewById(R.id.simple_key);
+ }
+
+ LinearLayout listItemLayout;
+ TextView mTitle;
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int index) {
+
+ if (viewHolder instanceof CollectionAdapter.ItemViewHolder) {
+ SimpleKeyBean searchHistoryBean = list.get(index);
+ final CollectionAdapter.ItemViewHolder itemViewHold =
+ ((CollectionAdapter.ItemViewHolder) viewHolder);
+
+ if (textFont != null) itemViewHold.mTitle.setTypeface(textFont);
+
+ String text = searchHistoryBean.getText();
+ if (text.length() > 300) itemViewHold.mTitle.setText(text.substring(0, 300));
+ else itemViewHold.mTitle.setText(text);
+
+ if (textSize > 0) itemViewHold.mTitle.setTextSize(textSize);
+
+ ViewGroup.LayoutParams lp = itemViewHold.listItemLayout.getLayoutParams();
+ if (lp instanceof FlexboxLayoutManager.LayoutParams) {
+ FlexboxLayoutManager.LayoutParams flexboxLp =
+ (FlexboxLayoutManager.LayoutParams) itemViewHold.listItemLayout.getLayoutParams();
+
+ itemViewHold.mTitle.setTextColor(textColor);
+
+ int marginTop = flexboxLp.getMarginTop();
+ int marginX = flexboxLp.getMarginLeft();
+ if (keyMarginTop > 0) marginTop = keyMarginTop;
+ if (keyMarginX > 0) marginX = keyMarginX;
+
+ flexboxLp.setMargins(marginX, marginTop, marginX, flexboxLp.getMarginBottom());
+
+ // TODO 设置剪贴板列表样式
+ // copy SimpleAdapter 会造成高度始终为 3 行无法自适应的效果。
+
+ }
+
+ Drawable background =
+ config.getDrawable(
+ "long_text_back_color", "key_border", "key_long_text_border", "round_corner", null);
+
+ if (background != null) itemViewHold.listItemLayout.setBackground(background);
+ // 如果设置了回调,则设置点击事件
+ if (mOnItemClickListener != null) {
+ itemViewHold.listItemLayout.setOnClickListener(
+ view -> {
+ int position = itemViewHold.getLayoutPosition();
+ mOnItemClickListener.onItemClick(itemViewHold.listItemLayout, position);
+ });
+ }
+
+ itemViewHold.listItemLayout.setOnLongClickListener(
+ view -> {
+ int position = itemViewHold.getLayoutPosition();
+ // TODO 长按删除、编辑剪贴板
+ // 当文本较长时,目前样式只缩略显示为 3 行,长按时 toast 消息可以预览全文,略有用处。
+ ToastUtils.showShort(list.get(position).getText());
+ return true;
+ });
+
+ // TODO 剪贴板列表点击时产生背景变色效果
+ itemViewHold.listItemLayout.setOnTouchListener(
+ (view, motionEvent) -> {
+ int action = motionEvent.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ break;
+ }
+ return false;
+ });
+ }
+ }
+
+ /** 添加 OnItemClickListener 回调 * */
+ public interface OnItemClickListener {
+ void onItemClick(View view, int position);
+ }
+
+ private OnItemClickListener mOnItemClickListener;
+
+ public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
+ this.mOnItemClickListener = mOnItemClickListener;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.java b/app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.java
index 0298adcb34..6c571bb427 100644
--- a/app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.java
+++ b/app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.java
@@ -12,6 +12,7 @@
import com.osfans.trime.R;
import com.osfans.trime.core.Rime;
import com.osfans.trime.data.Config;
+import com.osfans.trime.data.db.CollectionDao;
import com.osfans.trime.data.db.DbBean;
import com.osfans.trime.data.db.clipboard.ClipboardDao;
import com.osfans.trime.data.db.draft.DraftDao;
@@ -31,10 +32,11 @@ public class LiquidKeyboard {
private RecyclerView keyboardView;
private LinearLayout parentView;
private ClipboardAdapter mClipboardAdapter;
+ private CollectionAdapter mCollectionAdapter;
private DraftAdapter mDraftAdapter;
private SimpleAdapter simpleAdapter;
private CandidateAdapter candidateAdapter;
- private List clipboardBeanList, draftBeanList;
+ private List clipboardBeanList, collectionBeanList, draftBeanList;
private final List simpleKeyBeans;
private List historyBeans;
private int margin_x, margin_top, single_width, parent_width, clipboard_max_size, draft_max_size;
@@ -60,6 +62,9 @@ public LiquidKeyboard(Context context, int clipboard_max_size, int draft_max_siz
clipboardBeanList = ClipboardDao.get().getAllSimpleBean(clipboard_max_size);
Timber.d("clipboardBeanList.size=%s", clipboardBeanList.size());
+ collectionBeanList = CollectionDao.get().getAllSimpleBean();
+ Timber.d("collectionBeanList.size=%s", collectionBeanList.size());
+
draftBeanList = DraftDao.get().getAllSimpleBean(draft_max_size);
Timber.d("draftBeanList.size=%s", draftBeanList.size());
@@ -75,6 +80,13 @@ public void addClipboardData(String text) {
if (mClipboardAdapter != null) mClipboardAdapter.notifyItemInserted(0);
}
+ public void addCollectionData(String text) {
+ DbBean bean = new DbBean(text);
+ CollectionDao.get().add(bean);
+ collectionBeanList.add(0, bean);
+ if (mCollectionAdapter != null) mCollectionAdapter.notifyItemInserted(0);
+ }
+
public void addDraftData(String text) {
DbBean bean = new DbBean(text);
DraftDao.get().add(bean);
@@ -91,6 +103,10 @@ public SymbolKeyboardType select(int i) {
TabManager.get().select(i);
initClipboardData();
break;
+ case COLLECTION:
+ TabManager.get().select(i);
+ initCollectionData();
+ break;
case DRAFT:
TabManager.get().select(i);
initDraftData();
@@ -197,6 +213,7 @@ private void calcPadding(SymbolKeyboardType type) {
public void initFixData(int i) {
keyboardView.removeAllViews();
mClipboardAdapter = null;
+ mCollectionAdapter = null;
mDraftAdapter = null;
// 设置布局管理器
FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(context);
@@ -275,6 +292,7 @@ public void initFixData(int i) {
public void initClipboardData() {
keyboardView.removeAllViews();
simpleAdapter = null;
+ mCollectionAdapter = null;
// 设置布局管理器
FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(context);
@@ -307,6 +325,39 @@ public void initClipboardData() {
});
}
+ public void initCollectionData() {
+ keyboardView.removeAllViews();
+ simpleAdapter = null;
+ mClipboardAdapter = null;
+ // 设置布局管理器
+ FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(context);
+ // flexDirection 属性决定主轴的方向(即项目的排列方向)。类似 LinearLayout 的 vertical 和 horizontal。
+ flexboxLayoutManager.setFlexDirection(FlexDirection.ROW); // 主轴为水平方向,起点在左端。
+ // flexWrap 默认情况下 Flex 跟 LinearLayout 一样,都是不带换行排列的,但是flexWrap属性可以支持换行排列。
+ flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP); // 按正常方向换行
+ // justifyContent 属性定义了项目在主轴上的对齐方式。
+ flexboxLayoutManager.setJustifyContent(JustifyContent.FLEX_START); // 交叉轴的起点对齐。
+ // flexboxLayoutManager.setAlignItems(AlignItems.BASELINE);
+ keyboardView.setLayoutManager(flexboxLayoutManager);
+
+ collectionBeanList = CollectionDao.get().getAllSimpleBean();
+ mCollectionAdapter = new CollectionAdapter(context, collectionBeanList);
+
+ mCollectionAdapter.configStyle(margin_x, margin_top);
+
+ keyboardView.setAdapter(mCollectionAdapter);
+ // 调用ListView的setSelected(!ListView.isSelected())方法,这样就能及时刷新布局
+ keyboardView.setSelected(true);
+
+ mCollectionAdapter.setOnItemClickListener(
+ (view, position) -> {
+ InputConnection ic = Trime.getService().getCurrentInputConnection();
+ if (ic != null) {
+ ic.commitText(collectionBeanList.get(position).getText(), 1);
+ }
+ });
+ }
+
public void initDraftData() {
keyboardView.removeAllViews();
simpleAdapter = null;
@@ -347,6 +398,7 @@ public void initCandidateAdapter() {
simpleAdapter = null;
mClipboardAdapter = null;
mDraftAdapter = null;
+ mCollectionAdapter = null;
if (candidateAdapter == null) candidateAdapter = new CandidateAdapter(context);
diff --git a/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt b/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt
new file mode 100644
index 0000000000..f95ce75c6e
--- /dev/null
+++ b/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt
@@ -0,0 +1,135 @@
+package com.osfans.trime.ui.main
+
+import android.os.Build
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.widget.AdapterView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import com.blankj.utilcode.util.BarUtils
+import com.osfans.trime.R
+import com.osfans.trime.data.db.CollectionDao
+import com.osfans.trime.data.db.clipboard.ClipboardDao
+import com.osfans.trime.data.db.draft.DraftDao
+import com.osfans.trime.databinding.LiquidKeyboardActivityBinding
+import com.osfans.trime.ime.symbol.CheckableAdatper
+import com.osfans.trime.ime.symbol.SimpleKeyBean
+import timber.log.Timber
+
+class LiquidKeyboardActivity : AppCompatActivity() {
+ val CLIPBOARD = "clipboard"
+ val COLLECTION = "collection"
+ val DRAFT = "draft"
+ lateinit var binding: LiquidKeyboardActivityBinding
+ var type: String = CLIPBOARD
+ var beans: List = ArrayList()
+ lateinit var mAdapter: CheckableAdatper
+ override fun onCreate(savedInstanceState: Bundle?) {
+
+ super.onCreate(savedInstanceState)
+ binding = LiquidKeyboardActivityBinding.inflate(layoutInflater)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ BarUtils.setNavBarColor(
+ this,
+ getColor(R.color.windowBackground)
+ )
+ } else
+ BarUtils.setNavBarColor(
+ this,
+ @Suppress("DEPRECATION")
+ resources.getColor(R.color.windowBackground)
+ )
+ setContentView(binding.root)
+
+ val toolbar = findViewById(R.id.toolbar)
+ setSupportActionBar(toolbar)
+
+ type = intent.getStringExtra("type").toString()
+ if (type.equals(COLLECTION)) {
+ setTitle(R.string.other__list_collection_title)
+ } else if (type.equals(DRAFT)) {
+ setTitle(R.string.other__list_draft_title)
+ } else {
+ type = CLIPBOARD
+ setTitle(R.string.other__list_clipboard_title)
+ }
+
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ getDbData()
+
+ binding.btnDel.setOnClickListener {
+
+ var position: Int =
+ binding.listWord.getPositionForView(binding.listWord.getChildAt(0))
+ if (position > 0) position++
+ val r: List = mAdapter.remove(position)
+ if (r.isNotEmpty()) {
+ if (type.equals(COLLECTION))
+ CollectionDao.get().delete(r)
+ else if (type.equals(DRAFT))
+ DraftDao.get().delete(r)
+ else
+ ClipboardDao.get().delete(r)
+
+ Timber.d("delete " + r.size)
+ }
+ }
+
+ binding.btnCollect.setOnClickListener {
+
+ Timber.d("collect")
+ mAdapter.collectSelected()
+ }
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ if (supportFragmentManager.popBackStackImmediate()) {
+ return true
+ }
+ return super.onSupportNavigateUp()
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ return when (item.itemId) {
+ android.R.id.home -> {
+ onBackPressed()
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ return true
+ }
+
+ fun getDbData() {
+ binding.progressBar.setVisibility(View.VISIBLE)
+
+ if (type.equals(COLLECTION)) {
+ beans = CollectionDao.get().allSimpleBean
+ binding.btnCollect.setVisibility(View.GONE)
+ } else if (type.equals(DRAFT)) {
+ beans = DraftDao.get().getAllSimpleBean(1000)
+ } else {
+ beans = ClipboardDao.get().getAllSimpleBean(1000)
+ }
+
+ mAdapter = CheckableAdatper(
+ this,
+ R.layout.checkable_item,
+ beans
+ )
+ binding.listWord.setAdapter(mAdapter)
+
+ binding.listWord.setOnItemClickListener({ parent: AdapterView<*>?, view: View?, i: Int, l: Long ->
+ mAdapter.clickItem(
+ i
+ )
+ })
+ binding.progressBar.setVisibility(View.GONE)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt b/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
index d115495c9c..417536e701 100644
--- a/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
+++ b/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
@@ -2,17 +2,21 @@ package com.osfans.trime.settings.fragments
import android.content.ComponentName
import android.content.Context
+import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.Menu
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.forEach
+import androidx.preference.Preference
import androidx.preference.ListPreference
+import com.blankj.utilcode.util.ToastUtils
import androidx.preference.PreferenceFragmentCompat
import com.osfans.trime.R
import com.osfans.trime.data.AppPrefs
import com.osfans.trime.data.Config
+import com.osfans.trime.ui.main.LiquidKeyboardActivity
import com.osfans.trime.ime.core.Trime
class OtherFragment :
@@ -69,6 +73,24 @@ class OtherFragment :
}
}
+ override fun onPreferenceTreeClick(preference: Preference?): Boolean {
+ val key = preference?.key
+ if (key == "other__list_clipboard" ||
+ key == "other__list_collection" ||
+ key == "other__list_draft"
+ ) {
+ if (Trime.getService() == null)
+ ToastUtils.showShort(R.string.setup__select_ime_hint)
+ else {
+ val intent = Intent(this.context, LiquidKeyboardActivity::class.java)
+ intent.putExtra("type", key.replace("other__list_", ""))
+ startActivity(intent)
+ }
+ return true
+ }
+ return super.onPreferenceTreeClick(preference)
+ }
+
override fun onResume() {
super.onResume()
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
diff --git a/app/src/main/res/layout/checkable_item.xml b/app/src/main/res/layout/checkable_item.xml
new file mode 100644
index 0000000000..b869056c76
--- /dev/null
+++ b/app/src/main/res/layout/checkable_item.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/liquid_keyboard_activity.xml b/app/src/main/res/layout/liquid_keyboard_activity.xml
new file mode 100644
index 0000000000..769d40ae4d
--- /dev/null
+++ b/app/src/main/res/layout/liquid_keyboard_activity.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 471bb55851..f07b2cd8d1 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -121,6 +121,12 @@
剪贴板去重规则(每行为一条正则表达式)
剪贴板过滤规则(每行为一条正则表达式)
保存剪贴板内容的数量
+ 剪贴板内容
+ 草稿箱内容
+ 收藏夹内容
+ 删除
+ 收藏
+ 搜索(暂未实现)
- 停用
- 20
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index ebedcfad60..59770fd159 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -122,6 +122,12 @@
剪貼板去重規則(每行爲一條正則規則)
剪貼板過濾規則(每行爲一條正則規則)
保存剪貼板內容的數量
+ 剪貼板內容
+ 草稿箱內容
+ 收藏夾內容
+ 刪除
+ 收藏
+ 搜索(暫未實現)
- 停用
- 20
diff --git a/app/src/main/res/xml/other_preference.xml b/app/src/main/res/xml/other_preference.xml
index 8e74bbbbfb..2e636b71ed 100644
--- a/app/src/main/res/xml/other_preference.xml
+++ b/app/src/main/res/xml/other_preference.xml
@@ -25,6 +25,17 @@
app:iconSpaceReserved="false"
android:title="@string/other__destroy_on_quit_title" />
+
+
+
+
+
Date: Fri, 1 Sep 2023 13:40:38 +0800
Subject: [PATCH 07/14] fix: check error
---
app/src/main/java/com/osfans/trime/data/db/CollectionDao.java | 2 +-
.../main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java | 2 +-
.../java/com/osfans/trime/ime/symbol/CollectionAdapter.java | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java b/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java
index 62cb4cf9cb..1ddc5fa4e6 100644
--- a/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java
+++ b/app/src/main/java/com/osfans/trime/data/db/CollectionDao.java
@@ -89,4 +89,4 @@ public List getAllSimpleBean() {
Timber.d("getAllSimpleBean() size=%s", list.size());
return list;
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java b/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java
index 1680022f60..37894d2557 100644
--- a/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java
+++ b/app/src/main/java/com/osfans/trime/ime/symbol/CheckableAdatper.java
@@ -106,4 +106,4 @@ public View getView(int position, View convertView, ViewGroup parent) {
holder.checkBox.setChecked(checked.contains(position));
return convertView;
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java b/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java
index 0d6723fa20..376d6d0ee1 100644
--- a/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java
+++ b/app/src/main/java/com/osfans/trime/ime/symbol/CollectionAdapter.java
@@ -156,4 +156,4 @@ public interface OnItemClickListener {
public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
-}
\ No newline at end of file
+}
From 1948037655b5283b7904eb0f8b0cc53f9034fe6b Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 14:03:17 +0800
Subject: [PATCH 08/14] fix: check error
---
.../java/com/osfans/trime/settings/LiquidKeyboardActivity.kt | 2 +-
.../java/com/osfans/trime/settings/fragments/OtherFragment.kt | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt b/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt
index f95ce75c6e..e3759fb398 100644
--- a/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt
+++ b/app/src/main/java/com/osfans/trime/settings/LiquidKeyboardActivity.kt
@@ -132,4 +132,4 @@ class LiquidKeyboardActivity : AppCompatActivity() {
})
binding.progressBar.setVisibility(View.GONE)
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt b/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
index 417536e701..f17c6e7383 100644
--- a/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
+++ b/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
@@ -9,10 +9,10 @@ import android.os.Bundle
import android.view.Menu
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.forEach
-import androidx.preference.Preference
import androidx.preference.ListPreference
-import com.blankj.utilcode.util.ToastUtils
+import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
+import com.blankj.utilcode.util.ToastUtils
import com.osfans.trime.R
import com.osfans.trime.data.AppPrefs
import com.osfans.trime.data.Config
From 20550e7b395b7a1e4d027fd2b868a2c2c482af53 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 14:11:09 +0800
Subject: [PATCH 09/14] fix: check error2
---
.../java/com/osfans/trime/settings/fragments/OtherFragment.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt b/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
index f17c6e7383..d5497390d5 100644
--- a/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
+++ b/app/src/main/java/com/osfans/trime/settings/fragments/OtherFragment.kt
@@ -16,8 +16,8 @@ import com.blankj.utilcode.util.ToastUtils
import com.osfans.trime.R
import com.osfans.trime.data.AppPrefs
import com.osfans.trime.data.Config
-import com.osfans.trime.ui.main.LiquidKeyboardActivity
import com.osfans.trime.ime.core.Trime
+import com.osfans.trime.ui.main.LiquidKeyboardActivity
class OtherFragment :
PreferenceFragmentCompat(),
From 5c6a2a6496257d44095fd08b9eb5092e7f935543 Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 14:35:24 +0800
Subject: [PATCH 10/14] fix: xml files error
---
app/src/main/res/values/strings.xml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0db50594bf..8e2aadc9df 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -122,6 +122,12 @@
Clipboard Compare Rules
Clipboard Output Rules
Number of clipboard saved items
+ Clipboard Data
+ Draft Data
+ Collection Data
+ Delete
+ Collect
+ Search ( comming soon )
- Disable
- 20
From bc87342212fba0daac7126984d3f5e99abeaa8ea Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 14:50:25 +0800
Subject: [PATCH 11/14] feat: config apps not save draft, increase save draft
frequency by @tumuyan
---
app/src/main/AndroidManifest.xml | 8 ++++----
app/src/main/java/com/osfans/trime/data/AppPrefs.kt | 4 ++++
.../main/java/com/osfans/trime/ime/core/Trime.java | 11 ++++++++++-
app/src/main/res/values-zh-rCN/strings.xml | 1 +
app/src/main/res/values-zh-rTW/strings.xml | 1 +
app/src/main/res/values/strings.xml | 1 +
app/src/main/res/xml/other_preference.xml | 7 +++++++
7 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 938d25a3cd..e563bed7bb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -64,6 +64,10 @@
android:launchMode="singleTask"
android:parentActivityName=".settings.PrefMainActivity" />
+
-
diff --git a/app/src/main/java/com/osfans/trime/data/AppPrefs.kt b/app/src/main/java/com/osfans/trime/data/AppPrefs.kt
index 5ca530effc..0a178a3f9d 100644
--- a/app/src/main/java/com/osfans/trime/data/AppPrefs.kt
+++ b/app/src/main/java/com/osfans/trime/data/AppPrefs.kt
@@ -386,6 +386,7 @@ class AppPrefs(
const val CLIPBOARD_COMPARE_RULES = "other__clipboard_compare"
const val CLIPBOARD_OUTPUT_RULES = "other__clipboard_output"
const val DRAFT_OUTPUT_RULES = "other__draft_output"
+ const val DRAFT_EXCLUDE_APP = "other__draft_exclude_app"
const val DRAFT_LIMIT = "other__draft_limit"
const val CLIPBOARD_LIMIT = "other__clipboard_limit"
}
@@ -416,5 +417,8 @@ class AppPrefs(
var draftLimit: String
get() = prefs.getPref(DRAFT_LIMIT, "20")
set(v) = prefs.setPref(DRAFT_LIMIT, v)
+ var draftExcludeApp: String
+ get() = prefs.getPref(DRAFT_EXCLUDE_APP, "")
+ set(v) = prefs.setPref(DRAFT_EXCLUDE_APP, v)
}
}
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index 9fa55a48d9..2b9ac053c8 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -58,6 +58,7 @@
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import com.blankj.utilcode.util.BarUtils;
+import com.osfans.trime.BuildConfig;
import com.osfans.trime.R;
import com.osfans.trime.core.Rime;
import com.osfans.trime.data.AppPrefs;
@@ -866,7 +867,12 @@ public void onStartInputView(EditorInfo attribute, boolean restarting) {
if ((attribute.imeOptions & EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING)
== EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING) {
// 应用程求以隐身模式打开键盘应用程序
+ normalTextEditor = false;
Timber.i("EditorInfo: normal -> private, IME_FLAG_NO_PERSONALIZED_LEARNING");
+ } else if (attribute.packageName.equals(BuildConfig.APPLICATION_ID)
+ || getPrefs().getOther().getDraftExcludeApp().contains(attribute.packageName)) {
+ normalTextEditor = false;
+ Timber.i("EditorInfo: normal -> exclude, packageName=" + attribute.packageName);
} else {
normalTextEditor = true;
activeEditorInstance.cacheDraft();
@@ -877,7 +883,10 @@ public void onStartInputView(EditorInfo attribute, boolean restarting) {
@Override
public void onFinishInputView(boolean finishingInput) {
- if (normalTextEditor) addDraft();
+ if (normalTextEditor) {
+ activeEditorInstance.cacheDraft();
+ addDraft();
+ }
super.onFinishInputView(finishingInput);
// Dismiss any pop-ups when the input-view is being finished and hidden.
mainKeyboardView.closing();
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index f07b2cd8d1..e8540e73de 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -127,6 +127,7 @@
删除
收藏
搜索(暂未实现)
+ 不自动保存草稿的应用(包名)
- 停用
- 20
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 59770fd159..ffc1945fd1 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -128,6 +128,7 @@
刪除
收藏
搜索(暫未實現)
+ 不自動保存草稿的應用(包名)
- 停用
- 20
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8e2aadc9df..a683ff6538 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -128,6 +128,7 @@
Delete
Collect
Search ( comming soon )
+ Apps not save draft (package name)
- Disable
- 20
diff --git a/app/src/main/res/xml/other_preference.xml b/app/src/main/res/xml/other_preference.xml
index 2e636b71ed..097a6d9c89 100644
--- a/app/src/main/res/xml/other_preference.xml
+++ b/app/src/main/res/xml/other_preference.xml
@@ -71,4 +71,11 @@
android:title="@string/other__draft_output_title"
android:defaultValue=""
app:useSimpleSummaryProvider="true"/>
+
+
+
\ No newline at end of file
From 2dad42a5c932634bf63cf6e14a41572bb3fb4f4e Mon Sep 17 00:00:00 2001
From: mokapsing <39441028+mokapsing@users.noreply.github.com>
Date: Fri, 1 Sep 2023 15:03:51 +0800
Subject: [PATCH 12/14] feat: floating window for liquid keyboard by tumuyan
---
app/src/main/assets/rime/trime.yaml | 7 ++++-
.../java/com/osfans/trime/ime/core/Trime.java | 17 +++++------
.../trime/ime/keyboard/KeyboardView.java | 2 +-
.../osfans/trime/ime/text/Composition.java | 30 ++++++++++++++++++-
4 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/app/src/main/assets/rime/trime.yaml b/app/src/main/assets/rime/trime.yaml
index c3d5d70aca..d77517a55f 100644
--- a/app/src/main/assets/rime/trime.yaml
+++ b/app/src/main/assets/rime/trime.yaml
@@ -57,6 +57,11 @@ style:
- {start: "", move: 'ㄓ ', end: ""}
- {start: "", composition: "%s", end: "", letter_spacing: 0} #letter_spacing需要>=Android5.0。TODO: 不爲0時,會導致不換行的問題
- {start: "\n", label: "%s.", candidate: "%s", comment: " %s", end: "", sep: " "}
+ liquid_keyboard_window: #液态键盘模式下显示的悬浮窗口組件
+ - {start: "", click: "space", label: " 空格 "}
+ - {start: "", click: "BackSpace", label: " 删除 "}
+ - {start: "", click: "Return", label: " 回车 "}
+ - {start: "", click: "liquid_keyboard_exit", label: " 返回 "}
key_font: symbol.ttf #鍵盤字型
key_height: 44 #鍵高
key_long_text_size: 14 #長標籤字號
@@ -918,7 +923,7 @@ preset_keys:
Keyboard_default: {label: 返回, send: Eisu_toggle, select: .default}
Keyboard_switch: {label: 鍵盤, send: Eisu_toggle, select: .next}
liquid_keyboard_switch: { label: 更多, send: function, command: liquid_keyboard, option: "特殊" }
- liquid_keyboard_switch2: { toggle: _liquid_keyboard, send: Mode_switch, states: [ 更多, 更多 ] }
+ liquid_keyboard_exit: {label: 返回, send: function, command: liquid_keyboard, option: "-1"} #退出liquidkeyboard
liquid_keyboard_emoji: { label: 🙂, send: function, command: liquid_keyboard, option: "emoji" }
liquid_keyboard_clipboard: { label: 剪贴, send: function, command: liquid_keyboard, option: "剪贴" }
# trime設定
diff --git a/app/src/main/java/com/osfans/trime/ime/core/Trime.java b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
index 2b9ac053c8..4d906fdff3 100644
--- a/app/src/main/java/com/osfans/trime/ime/core/Trime.java
+++ b/app/src/main/java/com/osfans/trime/ime/core/Trime.java
@@ -474,7 +474,7 @@ public void selectLiquidKeyboard(final int tabIndex) {
// 按键需要通过tab name来打开liquidKeyboard的指定tab
public void selectLiquidKeyboard(@NonNull String name) {
- if (name.matches("\\d+")) selectLiquidKeyboard(Integer.parseInt(name));
+ if (name.matches("-?\\d+")) selectLiquidKeyboard(Integer.parseInt(name));
else if (name.matches("[A-Z]+")) selectLiquidKeyboard(SymbolKeyboardType.valueOf(name));
else selectLiquidKeyboard(TabManager.getTagIndex(name));
}
@@ -512,8 +512,8 @@ private void hideCompositionView() {
}
}
- private void showCompositionView() {
- if (TextUtils.isEmpty(Rime.getCompositionText())) {
+ private void showCompositionView(boolean isCandidate) {
+ if (TextUtils.isEmpty(Rime.getCompositionText()) && isCandidate) {
hideCompositionView();
return;
}
@@ -707,7 +707,7 @@ public void onUpdateCursorAnchorInfo(CursorAnchorInfo cursorAnchorInfo) {
cursorAnchorInfo.getMatrix().mapRect(mPopupRectF);
}
if (mCandidateRoot != null) {
- showCompositionView();
+ showCompositionView(true);
}
}
@@ -1230,14 +1230,15 @@ public int updateComposing() {
Timber.d("updateComposing() SymbolKeyboardType=%s", symbolKeyboardType.toString());
if (symbolKeyboardType != SymbolKeyboardType.NO_KEY
&& symbolKeyboardType != SymbolKeyboardType.CANDIDATE) {
- mComposition.getRootView().setVisibility(View.GONE);
+ mComposition.setWindow();
+ showCompositionView(false);
+ return 0;
} else {
- mComposition.getRootView().setVisibility(View.VISIBLE);
startNum = mComposition.setWindow(minPopupSize, minPopupCheckSize, Integer.MAX_VALUE);
mCandidate.setText(startNum);
// if isCursorUpdated, showCompositionView will be called in onUpdateCursorAnchorInfo
// otherwise we need to call it here
- if (!isCursorUpdated) showCompositionView();
+ if (!isCursorUpdated) showCompositionView(true);
}
} else {
mCandidate.setText(0);
@@ -1253,8 +1254,6 @@ public int updateComposing() {
if (symbolKeyboardType == SymbolKeyboardType.CANDIDATE) {
if (isComposing()) {
liquidKeyboard.updateCandidates();
- } else {
- selectLiquidKeyboard(-1);
}
}
diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.java b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.java
index afc293c8ef..6b5868df3e 100644
--- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.java
+++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.java
@@ -897,7 +897,7 @@ private void onBufferDraw() {
int[] drawableState = key.getCurrentDrawableState();
keyBackground = key.getBackColorForState(drawableState);
if (keyBackground == null) {
- Timber.i("onBufferDraw() keyBackground==null, key=%s", key.getLabel());
+ Timber.d("onBufferDraw() keyBackground==null, key=%s", key.getLabel());
try {
final int index = (int) findStateDrawableIndex.invoke(mKeyBackColor, drawableState);
keyBackground = (Drawable) getStateDrawable.invoke(mKeyBackColor, index);
diff --git a/app/src/main/java/com/osfans/trime/ime/text/Composition.java b/app/src/main/java/com/osfans/trime/ime/text/Composition.java
index 4975d8ccd6..41a2c70bfe 100644
--- a/app/src/main/java/com/osfans/trime/ime/text/Composition.java
+++ b/app/src/main/java/com/osfans/trime/ime/text/Composition.java
@@ -46,6 +46,7 @@
import com.osfans.trime.ime.core.Trime;
import com.osfans.trime.ime.keyboard.Event;
import com.osfans.trime.util.ConfigGetter;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import timber.log.Timber;
@@ -211,7 +212,14 @@ public void setShowComment(boolean value) {
public void reset(Context context) {
final Config config = Config.get(context);
- windows_comps = (List