Skip to content

Commit da36fa0

Browse files
WhiredPlanckBambooin
authored andcommitted
refactor(text): Optimize how to recompute tab geometry
- full scope: TabView, TabTag, TabManager - fix: mistouch caused by too large response area
1 parent 3f8824d commit da36fa0

File tree

3 files changed

+50
-61
lines changed

3 files changed

+50
-61
lines changed

app/src/main/java/com/osfans/trime/ime/symbol/TabManager.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
public class TabManager {
1111
private int selected;
1212
private final List<SimpleKeyBean> keyboard;
13-
private final List<TabTag> tabTags;
13+
private final ArrayList<TabTag> tabTags;
1414
private final List<List<SimpleKeyBean>> keyboards;
1515
private static TabManager self;
1616
private final List<SimpleKeyBean> notKeyboard = new ArrayList<>();
@@ -123,7 +123,7 @@ public int getSelected() {
123123
return selected;
124124
}
125125

126-
public TabTag[] getTabCandidates() {
126+
public ArrayList<TabTag> getTabCandidates() {
127127
boolean addExit = true;
128128
for (TabTag tag : tabTags) {
129129
if (tag.command == KeyCommandType.EXIT) {
@@ -135,6 +135,6 @@ public TabTag[] getTabCandidates() {
135135
tabTags.add(tagExit);
136136
keyboards.add(notKeyboard);
137137
}
138-
return tabTags.toArray(new TabTag[0]);
138+
return tabTags;
139139
}
140140
}

app/src/main/java/com/osfans/trime/ime/symbol/TabTag.java

+3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
// Tab是滑动键盘顶部的标签按钮(包含返回键)。
44
// 为了公用候选栏的皮肤参数以及外观,保持了和普通键盘布局相似的代码。此类相当于原键盘布局的Rime.RimeCandidate
55

6+
import android.graphics.Rect;
7+
68
import com.osfans.trime.ime.enums.KeyCommandType;
79
import com.osfans.trime.ime.enums.SymbolKeyboardType;
810

911
public class TabTag {
1012
String text; // text for tab
13+
Rect geometry; // position and size info of tab
1114
String comment; // not used
1215
SymbolKeyboardType type; //
1316
KeyCommandType command; // command for tag without key

app/src/main/java/com/osfans/trime/ime/symbol/TabView.java

+44-58
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import com.osfans.trime.setup.Config;
3636
import com.osfans.trime.util.GraphicUtils;
3737

38+
import java.util.ArrayList;
39+
3840
import timber.log.Timber;
3941

4042
// 这是滑动键盘顶部的view,展示了键盘布局的多个标签。
@@ -45,7 +47,7 @@ public class TabView extends View {
4547
private static final int CANDIDATE_TOUCH_OFFSET = -12;
4648

4749
private int highlightIndex;
48-
private TabTag[] tabTags;
50+
private ArrayList<TabTag> tabTags;
4951
private final GraphicUtils graphicUtils;
5052

5153
private PaintDrawable candidateHighlight;
@@ -57,8 +59,7 @@ public class TabView extends View {
5759
private final boolean shouldShowComment = true;
5860
private boolean isCommentOnTop;
5961
private boolean shouldCandidateUseCursor;
60-
61-
private final Rect[] tabGeometries = new Rect[MAX_CANDIDATE_COUNT + 2];
62+
// private final Rect[] tabGeometries = new Rect[MAX_CANDIDATE_COUNT + 2];
6263

6364
public void reset(Context context) {
6465
Config config = Config.get(context);
@@ -107,65 +108,58 @@ private boolean isHighlighted(int i) {
107108
return shouldCandidateUseCursor && i >= 0 && i == highlightIndex;
108109
}
109110

110-
private void drawHighlight(Canvas canvas) {
111-
if (isHighlighted(highlightIndex)) {
112-
candidateHighlight.setBounds(tabGeometries[highlightIndex]);
113-
candidateHighlight.draw(canvas);
114-
}
115-
}
116-
117111
public int getHightlightLeft() {
118-
return tabGeometries[highlightIndex].left;
112+
return tabTags.get(highlightIndex).geometry.left;
119113
}
120114

121115
public int getHightlightRight() {
122-
return tabGeometries[highlightIndex].right;
116+
return tabTags.get(highlightIndex).geometry.right;
123117
}
124118

125-
private void drawCandidates(Canvas canvas) {
119+
@Override
120+
protected void onDraw(Canvas canvas) {
121+
if (canvas == null) return;
126122
if (tabTags == null) return;
123+
super.onDraw(canvas);
127124

128-
float y = tabGeometries[0].centerY() - (candidatePaint.ascent() + candidatePaint.descent()) / 2;
129-
if (shouldShowComment && isCommentOnTop) y += (float) commentHeight / 2;
130-
131-
int i = 0;
132-
while (i < tabTags.length) {
125+
// Draw highlight background
126+
if (isHighlighted(highlightIndex)) {
127+
candidateHighlight.setBounds(tabTags.get(highlightIndex).geometry);
128+
candidateHighlight.draw(canvas);
129+
}
130+
// Draw tab text
131+
float tabY = (shouldShowComment && isCommentOnTop)
132+
? tabTags.get(0).geometry.centerY() - (candidatePaint.ascent() + candidatePaint.descent()) / 2.0f
133+
+ commentHeight / 2.0f
134+
: tabTags.get(0).geometry.centerY() - (candidatePaint.ascent() + candidatePaint.descent()) / 2.0f;
135+
136+
for (TabTag computedTab: tabTags) {
137+
int i = tabTags.indexOf(computedTab);
133138
// Calculate a position where the text could be centered in the rectangle.
134-
float x = tabGeometries[i].centerX();
139+
float tabX = computedTab.geometry.centerX();
135140

136141
candidatePaint.setColor(
137-
isHighlighted(i) ? hilitedCandidateTextColor : candidateTextColor);
138-
graphicUtils.drawText(canvas, getTabText(i), x, y,candidatePaint, candidateFont);
142+
isHighlighted(i) ? hilitedCandidateTextColor : candidateTextColor);
143+
graphicUtils.drawText(canvas, computedTab.text, tabX, tabY, candidatePaint, candidateFont);
139144
// Draw the separator at the right edge of each candidate.
140145
canvas.drawRect(
141-
tabGeometries[i].right - candidateSpacing,
142-
tabGeometries[i].top,
143-
tabGeometries[i].right + candidateSpacing,
144-
tabGeometries[i].bottom,
146+
computedTab.geometry.right - candidateSpacing,
147+
computedTab.geometry.top,
148+
computedTab.geometry.right + candidateSpacing,
149+
computedTab.geometry.bottom,
145150
separatorPaint
146151
);
147-
i++;
148-
}
149-
}
150-
151-
@Override
152-
protected void onDraw(Canvas canvas) {
153-
if (canvas == null) {
154-
return;
155152
}
156-
super.onDraw(canvas);
157-
158-
drawHighlight(canvas);
159-
drawCandidates(canvas);
160153
}
161154

162155
public void updateCandidateWidth() {
163156
tabTags = TabManager.get().getTabCandidates();
164157
highlightIndex = TabManager.get().getSelected();
165158

166159
int x = 0;
167-
for (int i = 0; i < tabTags.length; i++) {
168-
tabGeometries[i] = new Rect(x, 0, x += getTabWidth(i), getHeight());
160+
for (TabTag computedTab: tabTags) {
161+
int i = tabTags.indexOf(computedTab);
162+
computedTab.geometry = new Rect(x, 0, x += getTabWidth(i), getHeight());
169163
x += candidateSpacing;
170164
}
171165
LayoutParams params = getLayoutParams();
@@ -219,7 +213,6 @@ public boolean onTouchEvent(@NonNull MotionEvent me) {
219213
case EXIT:
220214
Trime.getService().selectLiquidKeyboard(-1);
221215
break;
222-
223216
// TODO liquidKeyboard中除返回按钮外,其他按键均未实装
224217
case DEL_LEFT:
225218
case DEL_RIGHT:
@@ -232,7 +225,7 @@ public boolean onTouchEvent(@NonNull MotionEvent me) {
232225
invalidate();
233226
Trime.getService().selectLiquidKeyboard(i);
234227
}
235-
Timber.d("index=" + i + " length=" + tabTags.length);
228+
Timber.d("index=" + i + " length=" + tabTags.size());
236229
}
237230
break;
238231
}
@@ -247,28 +240,21 @@ public boolean onTouchEvent(@NonNull MotionEvent me) {
247240
* @return {@code >=0}: 觸摸點 (x, y) 處候選項序號,從0開始編號; {@code -1}: 觸摸點 (x, y) 處無候選項;
248241
*/
249242
private int getTabIndex(int x, int y) {
250-
Rect r = new Rect();
251-
252-
int j = 0;
253-
for (int i = 0; i < tabTags.length; i++) {
254-
// Enlarge the rectangle to be more responsive to user clicks.
255-
r.set(tabGeometries[j++]);
256-
r.inset(0, CANDIDATE_TOUCH_OFFSET);
257-
if (r.contains(x, y)) {
258-
// Returns -1 if there is no candidate in the hitting rectangle.
259-
return (i < tabTags.length) ? i : -1;
243+
//Rect r = new Rect();
244+
int retIndex = -1; // Returns -1 if there is no tab in the hitting rectangle.
245+
for (TabTag computedTab: tabTags) {
246+
/* Enlarge the rectangle to be more responsive to user clicks.
247+
// r.set(tabGeometries[j++]);
248+
//r.inset(0, CANDIDATE_TOUCH_OFFSET); */
249+
if (computedTab.geometry.contains(x, y)) {
250+
retIndex = tabTags.indexOf(computedTab);
260251
}
261252
}
262-
return -1;
263-
}
264-
265-
private String getTabText(int i) {
266-
if (tabTags != null && i >= 0) return tabTags[i].text;
267-
return "-1";
253+
return retIndex;
268254
}
269255

270256
private float getTabWidth(int i) {
271-
String s = getTabText(i);
257+
String s = tabTags.get(i).text;
272258
return s != null ? 2 * candidatePadding + graphicUtils.measureText(candidatePaint, s, candidateFont) : 2 * candidatePadding;
273259
}
274260
}

0 commit comments

Comments
 (0)