mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-23 15:49:09 +00:00
Avoid hiding the toolbar and pinned keys during inline autofill (#474)
This commit is contained in:
parent
ea2e2b301b
commit
abc23d23be
3 changed files with 137 additions and 14 deletions
|
@ -1346,8 +1346,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
final View inlineSuggestionView = InlineAutofillUtils.createView(inlineSuggestions, mDisplayContext);
|
final View inlineSuggestionView = InlineAutofillUtils.createView(inlineSuggestions, mDisplayContext);
|
||||||
|
|
||||||
|
// Without this function the inline autofill suggestions will not be visible
|
||||||
mHandler.cancelResumeSuggestions();
|
mHandler.cancelResumeSuggestions();
|
||||||
mHandler.cancelUpdateSuggestionStrip();
|
|
||||||
mSuggestionStripView.setInlineSuggestionsView(inlineSuggestionView);
|
mSuggestionStripView.setInlineSuggestionsView(inlineSuggestionView);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -112,6 +112,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
|
|
||||||
private final SuggestionStripLayoutHelper mLayoutHelper;
|
private final SuggestionStripLayoutHelper mLayoutHelper;
|
||||||
private final StripVisibilityGroup mStripVisibilityGroup;
|
private final StripVisibilityGroup mStripVisibilityGroup;
|
||||||
|
private boolean isInlineAutofillSuggestionsVisible = false; // Required to disable the more suggestions if inline autofill suggestions are visible
|
||||||
|
|
||||||
private static class StripVisibilityGroup {
|
private static class StripVisibilityGroup {
|
||||||
private final View mSuggestionStripView;
|
private final View mSuggestionStripView;
|
||||||
|
@ -259,7 +260,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
: km.isKeyguardLocked();
|
: km.isKeyguardLocked();
|
||||||
mToolbarExpandKey.setOnClickListener(hideToolbarKeys ? null : this);
|
mToolbarExpandKey.setOnClickListener(hideToolbarKeys ? null : this);
|
||||||
mPinnedKeys.setVisibility(hideToolbarKeys ? GONE : VISIBLE);
|
mPinnedKeys.setVisibility(hideToolbarKeys ? GONE : VISIBLE);
|
||||||
mToolbarExpandKey.setVisibility(VISIBLE);
|
isInlineAutofillSuggestionsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRtl(final boolean isRtlLanguage) {
|
public void setRtl(final boolean isRtlLanguage) {
|
||||||
|
@ -278,8 +279,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
|
|
||||||
public void setInlineSuggestionsView(final View view) {
|
public void setInlineSuggestionsView(final View view) {
|
||||||
clear();
|
clear();
|
||||||
mToolbarExpandKey.setVisibility(GONE);
|
isInlineAutofillSuggestionsVisible = true;
|
||||||
mPinnedKeys.setVisibility(GONE);
|
|
||||||
mSuggestionsStrip.addView(view);
|
mSuggestionsStrip.addView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +552,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
public boolean onInterceptTouchEvent(final MotionEvent me) {
|
public boolean onInterceptTouchEvent(final MotionEvent me) {
|
||||||
|
|
||||||
// Disable More Suggestions if inline autofill suggestions is visible
|
// Disable More Suggestions if inline autofill suggestions is visible
|
||||||
if(mToolbarExpandKey.getVisibility() != VISIBLE && mPinnedKeys.getVisibility() != VISIBLE) {
|
if(isInlineAutofillSuggestionsVisible) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,32 @@ package helium314.keyboard.latin.utils;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.AttributeSet;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
|
import android.view.Choreographer;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.inputmethod.InlineSuggestion;
|
import android.view.inputmethod.InlineSuggestion;
|
||||||
import android.view.inputmethod.InlineSuggestionsRequest;
|
import android.view.inputmethod.InlineSuggestionsRequest;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.HorizontalScrollView;
|
import android.widget.HorizontalScrollView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.inline.InlineContentView;
|
||||||
import android.widget.inline.InlinePresentationSpec;
|
import android.widget.inline.InlinePresentationSpec;
|
||||||
|
|
||||||
|
import androidx.annotation.AttrRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.autofill.inline.UiVersions;
|
import androidx.autofill.inline.UiVersions;
|
||||||
import androidx.autofill.inline.UiVersions.StylesBuilder;
|
import androidx.autofill.inline.UiVersions.StylesBuilder;
|
||||||
|
@ -28,14 +43,14 @@ import androidx.autofill.inline.common.ViewStyle;
|
||||||
import androidx.autofill.inline.v1.InlineSuggestionUi;
|
import androidx.autofill.inline.v1.InlineSuggestionUi;
|
||||||
import androidx.autofill.inline.v1.InlineSuggestionUi.Style;
|
import androidx.autofill.inline.v1.InlineSuggestionUi.Style;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import helium314.keyboard.latin.R;
|
import helium314.keyboard.latin.R;
|
||||||
import helium314.keyboard.latin.common.ColorType;
|
import helium314.keyboard.latin.common.ColorType;
|
||||||
import helium314.keyboard.latin.common.Colors;
|
import helium314.keyboard.latin.common.Colors;
|
||||||
import helium314.keyboard.latin.settings.Settings;
|
import helium314.keyboard.latin.settings.Settings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.R)
|
@RequiresApi(api = Build.VERSION_CODES.R)
|
||||||
public class InlineAutofillUtils {
|
public class InlineAutofillUtils {
|
||||||
|
|
||||||
|
@ -49,7 +64,7 @@ public class InlineAutofillUtils {
|
||||||
new ViewStyle.Builder()
|
new ViewStyle.Builder()
|
||||||
.setBackground(
|
.setBackground(
|
||||||
Icon.createWithResource(context,
|
Icon.createWithResource(context,
|
||||||
androidx.autofill.R.drawable.autofill_inline_suggestion_chip_background)
|
androidx.autofill.R.drawable.autofill_inline_suggestion_chip_background)
|
||||||
.setTint(colors.get(ColorType.AUTOFILL_BACKGROUND_CHIP)))
|
.setTint(colors.get(ColorType.AUTOFILL_BACKGROUND_CHIP)))
|
||||||
.setPadding(0, 0, 0, 0)
|
.setPadding(0, 0, 0, 0)
|
||||||
.build())
|
.build())
|
||||||
|
@ -57,7 +72,7 @@ public class InlineAutofillUtils {
|
||||||
new ViewStyle.Builder()
|
new ViewStyle.Builder()
|
||||||
.setBackground(
|
.setBackground(
|
||||||
Icon.createWithResource(context,
|
Icon.createWithResource(context,
|
||||||
androidx.autofill.R.drawable.autofill_inline_suggestion_chip_background)
|
androidx.autofill.R.drawable.autofill_inline_suggestion_chip_background)
|
||||||
.setTint(colors.get(ColorType.AUTOFILL_BACKGROUND_CHIP)))
|
.setTint(colors.get(ColorType.AUTOFILL_BACKGROUND_CHIP)))
|
||||||
.build())
|
.build())
|
||||||
.setStartIconStyle(new ImageViewStyle.Builder().setLayoutMargin(0, 0, 0, 0).build())
|
.setStartIconStyle(new ImageViewStyle.Builder().setLayoutMargin(0, 0, 0, 0).build())
|
||||||
|
@ -80,6 +95,7 @@ public class InlineAutofillUtils {
|
||||||
final Size min = new Size(100, height);
|
final Size min = new Size(100, height);
|
||||||
final Size max = new Size(740, height);
|
final Size max = new Size(740, height);
|
||||||
|
|
||||||
|
// Three InlinePresentationSpec are required for some password managers
|
||||||
final ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
|
final ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
|
||||||
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
||||||
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
||||||
|
@ -90,8 +106,7 @@ public class InlineAutofillUtils {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HorizontalScrollView createView(List<InlineSuggestion> inlineSuggestions, Context context) {
|
public static InlineContentClipView createView(List<InlineSuggestion> inlineSuggestions, Context context) {
|
||||||
|
|
||||||
final int totalSuggestionsCount = inlineSuggestions.size();
|
final int totalSuggestionsCount = inlineSuggestions.size();
|
||||||
|
|
||||||
LinearLayout container = new LinearLayout(context);
|
LinearLayout container = new LinearLayout(context);
|
||||||
|
@ -108,8 +123,115 @@ public class InlineAutofillUtils {
|
||||||
|
|
||||||
HorizontalScrollView inlineSuggestionView = new HorizontalScrollView(context);
|
HorizontalScrollView inlineSuggestionView = new HorizontalScrollView(context);
|
||||||
inlineSuggestionView.setHorizontalScrollBarEnabled(false);
|
inlineSuggestionView.setHorizontalScrollBarEnabled(false);
|
||||||
|
inlineSuggestionView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||||
|
|
||||||
inlineSuggestionView.addView(container);
|
inlineSuggestionView.addView(container);
|
||||||
|
|
||||||
return inlineSuggestionView;
|
InlineContentClipView mScrollableSuggestionsClip = new InlineContentClipView(context);
|
||||||
|
mScrollableSuggestionsClip.addView(inlineSuggestionView);
|
||||||
|
|
||||||
|
return mScrollableSuggestionsClip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a container for showing {@link InlineContentView}s for cases
|
||||||
|
* where you want to ensure they appear only in a given area in your app. An
|
||||||
|
* example is having a scrollable list of items. Note that without this container
|
||||||
|
* the InlineContentViews' surfaces would cover parts of your app as these surfaces
|
||||||
|
* are owned by another process and always appearing on top of your app.
|
||||||
|
*/
|
||||||
|
private static class InlineContentClipView extends FrameLayout {
|
||||||
|
@NonNull
|
||||||
|
private final ViewTreeObserver.OnDrawListener mOnDrawListener =
|
||||||
|
this::clipDescendantInlineContentViews;
|
||||||
|
@NonNull
|
||||||
|
private final Rect mParentBounds = new Rect();
|
||||||
|
@NonNull
|
||||||
|
private final Rect mContentBounds = new Rect();
|
||||||
|
@NonNull
|
||||||
|
private final SurfaceView mBackgroundView;
|
||||||
|
private int mBackgroundColor;
|
||||||
|
public InlineContentClipView(@NonNull Context context) {
|
||||||
|
this(context, /*attrs*/ null);
|
||||||
|
}
|
||||||
|
public InlineContentClipView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
this(context, attrs, /*defStyleAttr*/ 0);
|
||||||
|
}
|
||||||
|
public InlineContentClipView(@NonNull Context context, @Nullable AttributeSet attrs,
|
||||||
|
@AttrRes int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
mBackgroundView = new SurfaceView(context);
|
||||||
|
mBackgroundView.setZOrderOnTop(true);
|
||||||
|
mBackgroundView.getHolder().setFormat(PixelFormat.TRANSPARENT);
|
||||||
|
mBackgroundView.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
mBackgroundView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
||||||
|
drawBackgroundColorIfReady();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
|
||||||
|
int height) { /*do nothing*/ }
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
||||||
|
/*do nothing*/
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addView(mBackgroundView);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
getViewTreeObserver().addOnDrawListener(mOnDrawListener);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setBackgroundColor(int color) {
|
||||||
|
mBackgroundColor = color;
|
||||||
|
Choreographer.getInstance().postFrameCallback((frameTimeNanos) ->
|
||||||
|
drawBackgroundColorIfReady());
|
||||||
|
}
|
||||||
|
private void drawBackgroundColorIfReady() {
|
||||||
|
final Surface surface = mBackgroundView.getHolder().getSurface();
|
||||||
|
if (surface.isValid()) {
|
||||||
|
final Canvas canvas = surface.lockCanvas(null);
|
||||||
|
try {
|
||||||
|
canvas.drawColor(mBackgroundColor);
|
||||||
|
} finally {
|
||||||
|
surface.unlockCanvasAndPost(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clipDescendantInlineContentViews() {
|
||||||
|
mParentBounds.right = getWidth();
|
||||||
|
mParentBounds.bottom = getHeight();
|
||||||
|
clipDescendantInlineContentViews(this);
|
||||||
|
}
|
||||||
|
private void clipDescendantInlineContentViews(@Nullable View root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (root instanceof InlineContentView inlineContentView) {
|
||||||
|
mContentBounds.set(mParentBounds);
|
||||||
|
offsetRectIntoDescendantCoords(inlineContentView, mContentBounds);
|
||||||
|
inlineContentView.setClipBounds(mContentBounds);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (root instanceof ViewGroup rootGroup) {
|
||||||
|
final int childCount = rootGroup.getChildCount();
|
||||||
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
final View child = rootGroup.getChildAt(i);
|
||||||
|
clipDescendantInlineContentViews(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue