Skip to content

Commit 3870097

Browse files
committed
Allocate space above keyboard for candidates bar etc.
and fix key preview popups clipped for API level 28, which is dumb (see <https://stackoverflow.com/q/52929466>)
1 parent 83eefd1 commit 3870097

3 files changed

Lines changed: 99 additions & 16 deletions

File tree

app/src/main/java/io/github/yawnoc/strokeinput/InputContainer.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@
4444

4545
/*
4646
A container that holds:
47+
- Stroke sequence bar
4748
- Candidates bar
4849
- Keyboard
4950
TODO:
50-
- Candidates
51+
- Stroke sequence bar
52+
- Candidates bar
5153
*/
5254
public class InputContainer
5355
extends View
@@ -80,6 +82,7 @@ public class InputContainer
8082
private OnInputListener inputListener;
8183
private Keyboard keyboard;
8284
private Key[] keyArray;
85+
private int touchableTopY;
8386

8487
// Active key
8588
private Key activeKey;
@@ -226,6 +229,10 @@ public void setKeyboard(final Keyboard keyboard) {
226229
requestLayout();
227230
}
228231

232+
public int getTouchableTopY() {
233+
return touchableTopY;
234+
}
235+
229236
@SuppressLint("RtlHardcoded")
230237
public void showKeyPreviewPlane() {
231238

@@ -300,24 +307,32 @@ public void onMeasure(
300307
{
301308
final int keyboardWidth;
302309
final int keyboardHeight;
310+
final int height;
311+
final int popupBufferZoneHeight;
303312

304313
if (keyboard == null) {
305314
keyboardWidth = 0;
306315
keyboardHeight = 0;
316+
height = 0;
317+
popupBufferZoneHeight = 0;
318+
touchableTopY = 0;
307319
}
308320
else {
309321
keyboardWidth = keyboard.getWidth();
310322
keyboardHeight = keyboard.getHeight();
323+
height = keyboard.getParentInputContainerHeight();
324+
popupBufferZoneHeight = keyboard.getPopupBufferZoneHeight();
325+
touchableTopY = keyboard.getParentInputContainerTouchableTopY();
311326
}
312327

313328
keyboardRectangle.set(
314329
0,
315-
Keyboard.KEYBOARD_GUTTER_HEIGHT_PX,
330+
popupBufferZoneHeight,
316331
keyboardWidth,
317-
Keyboard.KEYBOARD_GUTTER_HEIGHT_PX + keyboardHeight
332+
popupBufferZoneHeight + keyboardHeight
318333
);
319334

320-
setMeasuredDimension(keyboardWidth, keyboardHeight);
335+
setMeasuredDimension(keyboardWidth, height);
321336
}
322337

323338
@Override

app/src/main/java/io/github/yawnoc/strokeinput/Keyboard.java

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import android.content.res.TypedArray;
2626
import android.content.res.XmlResourceParser;
2727
import android.graphics.Color;
28+
import android.os.Build;
2829
import android.util.DisplayMetrics;
2930
import android.util.Log;
3031
import android.util.Xml;
@@ -36,12 +37,20 @@
3637

3738
/*
3839
A container that holds rows of keys, to be declared in a layout XML.
40+
It also determines the vertical placement of the stroke sequence bar
41+
and the candidates bar, which are separate entities to be placed
42+
above the keyboard (in the parent input container).
3943
*/
4044
public class Keyboard {
4145

42-
private static final int DEFAULT_KEYBOARD_FILL_COLOUR = Color.BLACK;
46+
private static final int STROKE_SEQUENCE_BAR_HEIGHT_DP = 24;
47+
private final int strokeSequenceBarHeightPx;
48+
private static final int CANDIDATES_BAR_HEIGHT_DP = 36;
49+
private final int candidatesBarHeightPx;
4350
public static final int KEYBOARD_GUTTER_HEIGHT_PX = 1;
4451

52+
private static final int DEFAULT_KEYBOARD_FILL_COLOUR = Color.BLACK;
53+
4554
private static final float KEYBOARD_HEIGHT_MAX_FRACTION = 0.5f;
4655

4756
private static final float DEFAULT_KEY_WIDTH_FRACTION = 0.1f;
@@ -62,6 +71,11 @@ public class Keyboard {
6271
private static final int DEFAULT_KEY_PREVIEW_MARGIN_Y_DP = 16;
6372
private final int defaultKeyPreviewMarginYPx;
6473

74+
// Parent input container properties
75+
private int popupBufferZoneHeight;
76+
private int parentInputContainerHeight;
77+
private int parentInputContainerTouchableTopY;
78+
6579
// Keyboard properties
6680
private int width;
6781
private int height;
@@ -88,14 +102,23 @@ public class Keyboard {
88102
private final int screenWidth;
89103
private final int screenHeight;
90104

91-
public Keyboard(final Context context, final int layoutResourceId) {
92-
105+
public Keyboard(
106+
final Context context,
107+
final int layoutResourceId,
108+
final boolean isFullscreenMode
109+
)
110+
{
93111
final DisplayMetrics displayMetrics =
94112
context.getResources().getDisplayMetrics();
95113

96114
screenWidth = displayMetrics.widthPixels;
97115
screenHeight = displayMetrics.heightPixels;
98116

117+
strokeSequenceBarHeightPx =
118+
(int) Valuey.pxFromDp(STROKE_SEQUENCE_BAR_HEIGHT_DP, displayMetrics);
119+
candidatesBarHeightPx =
120+
(int) Valuey.pxFromDp(CANDIDATES_BAR_HEIGHT_DP, displayMetrics);
121+
99122
defaultKeyHeightPx =
100123
(int) Valuey.pxFromDp(DEFAULT_KEY_HEIGHT_DP, displayMetrics);
101124
defaultKeyBorderThicknessPx =
@@ -108,13 +131,25 @@ public Keyboard(final Context context, final int layoutResourceId) {
108131
keyList = new ArrayList<>();
109132

110133
loadKeyboard(context, context.getResources().getXml(layoutResourceId));
111-
adjustKeyboardVertically();
134+
adjustKeyboardVertically(isFullscreenMode);
112135
}
113136

114137
public List<Key> getKeyList() {
115138
return keyList;
116139
}
117140

141+
public int getPopupBufferZoneHeight() {
142+
return popupBufferZoneHeight;
143+
}
144+
145+
public int getParentInputContainerHeight() {
146+
return parentInputContainerHeight;
147+
}
148+
149+
public int getParentInputContainerTouchableTopY() {
150+
return parentInputContainerTouchableTopY;
151+
}
152+
118153
public int getWidth() {
119154
return width;
120155
}
@@ -142,7 +177,7 @@ private void loadKeyboard(
142177
boolean inRow = false;
143178

144179
int x = 0;
145-
int y = 0;
180+
int y = KEYBOARD_GUTTER_HEIGHT_PX;
146181
Key key = null;
147182
Row row = null;
148183

@@ -200,20 +235,42 @@ else if (inRow) {
200235
}
201236
}
202237

203-
private void adjustKeyboardVertically() {
238+
private void adjustKeyboardVertically(final boolean isFullscreenMode) {
204239

205240
final float keyboardHeightCorrectionFactor =
206241
Math.min(1, KEYBOARD_HEIGHT_MAX_FRACTION * screenHeight / height);
207242

208243
for (Key key : keyList) {
209244
key.y *= keyboardHeightCorrectionFactor;
210-
key.y += KEYBOARD_GUTTER_HEIGHT_PX;
211245
key.height *= keyboardHeightCorrectionFactor;
212246
key.textOffsetY *= keyboardHeightCorrectionFactor;
213247
key.previewMarginY *= keyboardHeightCorrectionFactor;
214248
}
215-
216249
height *= keyboardHeightCorrectionFactor;
250+
251+
if (Build.VERSION.SDK_INT == 28 && !isFullscreenMode) {
252+
// API level 28 is dumb, see <https://stackoverflow.com/q/52929466>
253+
int popupBufferZoneTopY =
254+
-(strokeSequenceBarHeightPx + candidatesBarHeightPx);
255+
for (Key key : keyList) {
256+
final int keyPreviewHeight =
257+
(int) (key.previewMagnification * key.height);
258+
popupBufferZoneTopY = Math.min(
259+
key.y - keyPreviewHeight - key.previewMarginY,
260+
popupBufferZoneTopY
261+
);
262+
}
263+
popupBufferZoneHeight = -popupBufferZoneTopY;
264+
}
265+
else {
266+
popupBufferZoneHeight = candidatesBarHeightPx;
267+
}
268+
for (Key key : keyList) {
269+
key.y += popupBufferZoneHeight;
270+
}
271+
parentInputContainerHeight = height + popupBufferZoneHeight;
272+
parentInputContainerTouchableTopY =
273+
Math.max(0, popupBufferZoneHeight - candidatesBarHeightPx);
217274
}
218275

219276
private void parseKeyboardAttributes(

app/src/main/java/io/github/yawnoc/strokeinput/StrokeInputService.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ public View onCreateInputView() {
5454
getLayoutInflater().inflate(R.layout.input_container, null);
5555

5656
strokesKeyboard =
57-
new Keyboard(this, R.xml.keyboard_strokes);
57+
new Keyboard(this, R.xml.keyboard_strokes, isFullscreenMode());
5858
strokesSymbolsKeyboard =
59-
new Keyboard(this, R.xml.keyboard_strokes_symbols);
59+
new Keyboard(this, R.xml.keyboard_strokes_symbols, isFullscreenMode());
6060
qwertyKeyboard =
61-
new Keyboard(this, R.xml.keyboard_qwerty);
61+
new Keyboard(this, R.xml.keyboard_qwerty, isFullscreenMode());
6262
qwertySymbolsKeyboard =
63-
new Keyboard(this, R.xml.keyboard_qwerty_symbols);
63+
new Keyboard(this, R.xml.keyboard_qwerty_symbols, isFullscreenMode());
6464

6565
nameFromKeyboard = new HashMap<>();
6666
nameFromKeyboard.put(strokesKeyboard, "STROKES");
@@ -82,6 +82,17 @@ public void onStartInputView(EditorInfo editorInfo, boolean isRestarting) {
8282
inputContainer.showKeyPreviewPlane();
8383
}
8484

85+
@Override
86+
public void onComputeInsets(InputMethodService.Insets insets) {
87+
super.onComputeInsets(insets);
88+
// API level 28 is dumb, see <https://stackoverflow.com/a/53326786>
89+
final int touchableTopY = inputContainer.getTouchableTopY();
90+
if (touchableTopY > 0) {
91+
insets.visibleTopInsets = touchableTopY;
92+
insets.contentTopInsets = touchableTopY;
93+
}
94+
}
95+
8596
@Override
8697
public void onKey(final String valueText) {
8798

0 commit comments

Comments
 (0)