NekoX/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/AcceptDeclineView.java

604 lines
25 KiB
Java
Raw Normal View History

2020-08-14 18:58:22 +02:00
package org.telegram.ui.Components.voip;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
2020-08-15 02:01:55 +02:00
import android.os.Build;
2020-08-14 18:58:22 +02:00
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
public class AcceptDeclineView extends View {
private FabBackgroundDrawable acceptDrawable;
private FabBackgroundDrawable declineDrawable;
private Drawable callDrawable;
private Drawable cancelDrawable;
private Paint acceptCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private StaticLayout acceptLayout;
private StaticLayout declineLayout;
private StaticLayout retryLayout;
private AcceptDeclineAccessibilityNodeProvider accessibilityNodeProvider;
private int buttonWidth;
2022-03-24 07:44:40 +01:00
private int currentFocusedVirtualViewId = View.NO_ID;
2020-08-14 18:58:22 +02:00
float smallRadius;
float bigRadius;
boolean expandSmallRadius = true;
boolean expandBigRadius = true;
boolean startDrag;
boolean captured;
long capturedTime;
boolean leftDrag;
float startX;
float startY;
float touchSlop;
float leftOffsetX;
float rigthOffsetX;
float maxOffset;
Rect acceptRect = new Rect();
Rect declineRect = new Rect();
Animator leftAnimator;
Animator rightAnimator;
Listener listener;
boolean retryMod;
Drawable rippleDrawable;
2020-08-22 01:59:49 +02:00
private boolean screenWasWakeup;
Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Drawable arrowDrawable;
float arrowProgress;
2020-08-14 18:58:22 +02:00
public AcceptDeclineView(@NonNull Context context) {
super(context);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
2020-09-30 15:48:47 +02:00
buttonWidth = AndroidUtilities.dp(60);
2020-08-14 18:58:22 +02:00
acceptDrawable = new FabBackgroundDrawable();
2020-09-30 15:48:47 +02:00
acceptDrawable.setColor(0xFF40C749);
2020-08-14 18:58:22 +02:00
declineDrawable = new FabBackgroundDrawable();
2020-09-30 15:48:47 +02:00
declineDrawable.setColor(0xFFF01D2C);
2020-08-14 18:58:22 +02:00
declineDrawable.setBounds(0, 0, buttonWidth, buttonWidth);
acceptDrawable.setBounds(0, 0, buttonWidth, buttonWidth);
TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(AndroidUtilities.dp(11));
textPaint.setColor(Color.WHITE);
String acceptStr = LocaleController.getString("AcceptCall", R.string.AcceptCall);
String declineStr = LocaleController.getString("DeclineCall", R.string.DeclineCall);
String retryStr = LocaleController.getString("RetryCall", R.string.RetryCall);
acceptLayout = new StaticLayout(acceptStr, textPaint, (int) textPaint.measureText(acceptStr), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
declineLayout = new StaticLayout(declineStr, textPaint, (int) textPaint.measureText(declineStr), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
retryLayout = new StaticLayout(retryStr, textPaint, (int) textPaint.measureText(retryStr), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
callDrawable = ContextCompat.getDrawable(context, R.drawable.calls_decline).mutate();
cancelDrawable = ContextCompat.getDrawable(context, R.drawable.ic_close_white).mutate();
cancelDrawable.setColorFilter(new PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY));
acceptCirclePaint.setColor(0x3f45bc4d);
rippleDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(52), 0, ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * 0.3f)));
rippleDrawable.setCallback(this);
2020-08-22 01:59:49 +02:00
arrowDrawable = ContextCompat.getDrawable(context, R.drawable.call_arrow_right);
2020-08-14 18:58:22 +02:00
}
2020-08-22 01:59:49 +02:00
2020-08-14 18:58:22 +02:00
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
maxOffset = getMeasuredWidth() / 2f - (buttonWidth / 2f + AndroidUtilities.dp(46));
int padding = (buttonWidth - AndroidUtilities.dp(28)) / 2;
callDrawable.setBounds(padding, padding, padding + AndroidUtilities.dp(28), padding + AndroidUtilities.dp(28));
cancelDrawable.setBounds(padding, padding, padding + AndroidUtilities.dp(28), padding + AndroidUtilities.dp(28));
2020-08-22 01:59:49 +02:00
linePaint.setStrokeWidth(AndroidUtilities.dp(3));
linePaint.setColor(Color.WHITE);
2020-08-14 18:58:22 +02:00
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
if (leftAnimator == null && declineRect.contains((int) event.getX(), (int) event.getY())) {
2020-09-30 15:48:47 +02:00
rippleDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(52), 0, 0xFFFF3846);
2020-08-14 18:58:22 +02:00
captured = true;
leftDrag = true;
setPressed(true);
return true;
}
if (rightAnimator == null && acceptRect.contains((int) event.getX(), (int) event.getY())) {
2020-09-30 15:48:47 +02:00
rippleDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(52), 0, 0xFF4DD156);
2020-08-14 18:58:22 +02:00
captured = true;
leftDrag = false;
setPressed(true);
if (rightAnimator != null) {
rightAnimator.cancel();
}
return true;
}
break;
case MotionEvent.ACTION_MOVE:
if (captured) {
float dx = event.getX() - startX;
if (!startDrag && Math.abs(dx) > touchSlop) {
if (!retryMod) {
startX = event.getX();
dx = 0;
startDrag = true;
setPressed(false);
getParent().requestDisallowInterceptTouchEvent(true);
} else {
setPressed(false);
captured = false;
}
}
if (startDrag) {
if (leftDrag) {
leftOffsetX = dx;
if (leftOffsetX < 0) {
leftOffsetX = 0;
} else if (leftOffsetX > maxOffset) {
leftOffsetX = maxOffset;
dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
}
} else {
rigthOffsetX = dx;
if (rigthOffsetX > 0) {
rigthOffsetX = 0;
} else if (rigthOffsetX < -maxOffset) {
rigthOffsetX = -maxOffset;
dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
}
}
}
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
float dy = event.getY() - startY;
if (captured) {
if (leftDrag) {
ValueAnimator animator = ValueAnimator.ofFloat(leftOffsetX, 0);
animator.addUpdateListener(valueAnimator -> {
leftOffsetX = (float) valueAnimator.getAnimatedValue();
invalidate();
leftAnimator = null;
});
animator.start();
leftAnimator = animator;
if (listener != null) {
2020-08-22 01:59:49 +02:00
if ((!startDrag && Math.abs(dy) < touchSlop && !screenWasWakeup) || leftOffsetX > maxOffset * 0.8f) {
2022-02-12 06:22:45 +01:00
listener.onDecline();
2020-08-14 18:58:22 +02:00
}
}
} else {
ValueAnimator animator = ValueAnimator.ofFloat(rigthOffsetX, 0);
animator.addUpdateListener(valueAnimator -> {
rigthOffsetX = (float) valueAnimator.getAnimatedValue();
invalidate();
rightAnimator = null;
});
animator.start();
rightAnimator = animator;
if (listener != null) {
2020-08-22 01:59:49 +02:00
if ((!startDrag && Math.abs(dy) < touchSlop && !screenWasWakeup) || -rigthOffsetX > maxOffset * 0.8f) {
2020-08-14 18:58:22 +02:00
listener.onAccept();
}
}
}
}
getParent().requestDisallowInterceptTouchEvent(false);
captured = false;
startDrag = false;
setPressed(false);
break;
}
return false;
}
@Override
protected void onDraw(Canvas canvas) {
if (!retryMod) {
if (expandSmallRadius) {
smallRadius += AndroidUtilities.dp(2) * 0.04f;
if (smallRadius > AndroidUtilities.dp(4)) {
smallRadius = AndroidUtilities.dp(4);
expandSmallRadius = false;
}
} else {
smallRadius -= AndroidUtilities.dp(2) * 0.04f;
if (smallRadius < 0) {
smallRadius = 0;
expandSmallRadius = true;
}
}
if (expandBigRadius) {
bigRadius += AndroidUtilities.dp(4) * 0.03f;
if (bigRadius > AndroidUtilities.dp(10)) {
bigRadius = AndroidUtilities.dp(10);
expandBigRadius = false;
}
} else {
bigRadius -= AndroidUtilities.dp(5) * 0.03f;
if (bigRadius < AndroidUtilities.dp(5)) {
bigRadius = AndroidUtilities.dp(5);
expandBigRadius = true;
}
}
invalidate();
}
2020-08-22 01:59:49 +02:00
float k = 0.6f;
if (screenWasWakeup && !retryMod) {
arrowProgress += 16 / 1500f;
if (arrowProgress > 1) {
arrowProgress = 0;
}
int cY = (int) (AndroidUtilities.dp(40) + buttonWidth / 2f);
float startX = AndroidUtilities.dp(46) + buttonWidth + AndroidUtilities.dp(8);
float endX = getMeasuredWidth() / 2f - AndroidUtilities.dp(8);
float lineLength = AndroidUtilities.dp(10);
float stepProgress = (1f - k) / 3f;
for (int i = 0; i < 3; i++) {
int x = (int) (startX + (endX - startX - lineLength) / 3 * i);
float alpha = 0.5f;
float startAlphaFrom = i * stepProgress;
if (arrowProgress > startAlphaFrom && arrowProgress < startAlphaFrom + k) {
float p = (arrowProgress - startAlphaFrom) / k;
if (p > 0.5) p = 1f - p;
alpha = 0.5f + p;
}
canvas.save();
canvas.clipRect(leftOffsetX + AndroidUtilities.dp(46) + buttonWidth / 2,0,getMeasuredHeight(),getMeasuredWidth() >> 1);
arrowDrawable.setAlpha((int) (255 * alpha));
arrowDrawable.setBounds(x, cY - arrowDrawable.getIntrinsicHeight() / 2, x + arrowDrawable.getIntrinsicWidth(), cY + arrowDrawable.getIntrinsicHeight() / 2);
arrowDrawable.draw(canvas);
canvas.restore();
x = (int) (getMeasuredWidth() - (startX + (endX - startX - lineLength) / 3 * i));
canvas.save();
canvas.clipRect(getMeasuredWidth() >> 1, 0, rigthOffsetX + getMeasuredWidth() - AndroidUtilities.dp(46) - buttonWidth / 2, getMeasuredHeight());
canvas.rotate(180, x - arrowDrawable.getIntrinsicWidth() / 2f, cY);
arrowDrawable.setBounds(x - arrowDrawable.getIntrinsicWidth(), cY - arrowDrawable.getIntrinsicHeight() / 2, x, cY + arrowDrawable.getIntrinsicHeight() / 2);
arrowDrawable.draw(canvas);
canvas.restore();
}
invalidate();
}
2020-08-14 18:58:22 +02:00
bigRadius += AndroidUtilities.dp(8) * 0.005f;
canvas.save();
canvas.translate(0, AndroidUtilities.dp(40));
canvas.save();
canvas.translate(leftOffsetX + AndroidUtilities.dp(46), 0);
declineDrawable.draw(canvas);
canvas.save();
canvas.translate(buttonWidth / 2f - declineLayout.getWidth() / 2f, buttonWidth + AndroidUtilities.dp(8));
declineLayout.draw(canvas);
declineRect.set(AndroidUtilities.dp(46), AndroidUtilities.dp(40), AndroidUtilities.dp(46) + buttonWidth, AndroidUtilities.dp(40) + buttonWidth);
canvas.restore();
if (retryMod) {
cancelDrawable.draw(canvas);
} else {
callDrawable.draw(canvas);
}
if (leftDrag) {
rippleDrawable.setBounds(AndroidUtilities.dp(4), AndroidUtilities.dp(4), buttonWidth - AndroidUtilities.dp(4), buttonWidth - AndroidUtilities.dp(4));
rippleDrawable.draw(canvas);
}
canvas.restore();
canvas.save();
canvas.translate(rigthOffsetX + getMeasuredWidth() - AndroidUtilities.dp(46) - buttonWidth, 0);
if (!retryMod) {
canvas.drawCircle(buttonWidth / 2f, buttonWidth / 2f, buttonWidth / 2f - AndroidUtilities.dp(4) + bigRadius, acceptCirclePaint);
canvas.drawCircle(buttonWidth / 2f, buttonWidth / 2f, buttonWidth / 2f - AndroidUtilities.dp(4) + smallRadius, acceptCirclePaint);
}
acceptDrawable.draw(canvas);
acceptRect.set(getMeasuredWidth() - AndroidUtilities.dp(46) - buttonWidth, AndroidUtilities.dp(40), getMeasuredWidth() - AndroidUtilities.dp(46), AndroidUtilities.dp(40) + buttonWidth);
if (retryMod) {
canvas.save();
canvas.translate(buttonWidth / 2f - retryLayout.getWidth() / 2f, buttonWidth + AndroidUtilities.dp(8));
retryLayout.draw(canvas);
canvas.restore();
} else {
canvas.save();
canvas.translate(buttonWidth / 2f - acceptLayout.getWidth() / 2f, buttonWidth + AndroidUtilities.dp(8));
acceptLayout.draw(canvas);
canvas.restore();
}
canvas.save();
2020-09-30 15:48:47 +02:00
canvas.translate(-AndroidUtilities.dp(1), AndroidUtilities.dp(1));
canvas.rotate(-135, callDrawable.getBounds().centerX(), callDrawable.getBounds().centerY());
2020-08-14 18:58:22 +02:00
callDrawable.draw(canvas);
canvas.restore();
2020-09-30 15:48:47 +02:00
if (!leftDrag) {
rippleDrawable.setBounds(AndroidUtilities.dp(4), AndroidUtilities.dp(4), buttonWidth - AndroidUtilities.dp(4), buttonWidth - AndroidUtilities.dp(4));
rippleDrawable.draw(canvas);
}
2020-08-14 18:58:22 +02:00
canvas.restore();
canvas.restore();
}
public void setListener(Listener listener) {
this.listener = listener;
}
public interface Listener {
void onAccept();
2020-08-22 01:59:49 +02:00
2022-02-12 06:22:45 +01:00
void onDecline();
2020-08-14 18:58:22 +02:00
}
public void setRetryMod(boolean retryMod) {
this.retryMod = retryMod;
if (retryMod) {
declineDrawable.setColor(Color.WHITE);
2020-08-22 01:59:49 +02:00
screenWasWakeup = false;
2020-08-14 18:58:22 +02:00
} else {
declineDrawable.setColor(0xFFe61e44);
}
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
rippleDrawable.setState(getDrawableState());
}
@Override
public boolean verifyDrawable(Drawable drawable) {
return rippleDrawable == drawable || super.verifyDrawable(drawable);
}
@Override
public void jumpDrawablesToCurrentState() {
super.jumpDrawablesToCurrentState();
if (rippleDrawable != null) {
rippleDrawable.jumpToCurrentState();
}
}
@Override
2022-03-24 07:44:40 +01:00
public boolean dispatchHoverEvent(MotionEvent event) {
if (accessibilityNodeProvider != null && accessibilityNodeProvider.dispatchHoverEvent(event)) {
2020-08-14 18:58:22 +02:00
return true;
}
2022-03-24 07:44:40 +01:00
return super.dispatchHoverEvent(event);
}
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) currentFocusedVirtualViewId = NO_ID;
return super.performAccessibilityAction(action, arguments);
2020-08-14 18:58:22 +02:00
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (accessibilityNodeProvider == null) {
accessibilityNodeProvider = new AcceptDeclineAccessibilityNodeProvider(this, 2) {
private static final int ACCEPT_VIEW_ID = 0;
private static final int DECLINE_VIEW_ID = 1;
private final int[] coords = {0, 0};
@Override
protected CharSequence getVirtualViewText(int virtualViewId) {
if (virtualViewId == ACCEPT_VIEW_ID) {
if (retryMod) {
if (retryLayout != null) {
return retryLayout.getText();
}
} else {
if (acceptLayout != null) {
return acceptLayout.getText();
}
}
} else if (virtualViewId == DECLINE_VIEW_ID) {
if (declineLayout != null) {
return declineLayout.getText();
}
}
return null;
}
@Override
protected void getVirtualViewBoundsInScreen(int virtualViewId, Rect outRect) {
getVirtualViewBoundsInParent(virtualViewId, outRect);
getLocationOnScreen(coords);
outRect.offset(coords[0], coords[1]);
}
@Override
protected void getVirtualViewBoundsInParent(int virtualViewId, Rect outRect) {
if (virtualViewId == ACCEPT_VIEW_ID) {
outRect.set(acceptRect);
} else if (virtualViewId == DECLINE_VIEW_ID) {
outRect.set(declineRect);
} else {
outRect.setEmpty();
}
}
2021-01-28 15:15:51 +01:00
@Override
protected void onVirtualViewClick(int virtualViewId) {
if (listener != null) {
if (virtualViewId == ACCEPT_VIEW_ID) {
listener.onAccept();
} else if (virtualViewId == DECLINE_VIEW_ID) {
2022-02-12 06:22:45 +01:00
listener.onDecline();
2021-01-28 15:15:51 +01:00
}
}
}
2020-08-14 18:58:22 +02:00
};
}
return accessibilityNodeProvider;
}
2020-08-22 01:59:49 +02:00
public void setScreenWasWakeup(boolean screenWasWakeup) {
this.screenWasWakeup = screenWasWakeup;
}
2022-03-24 07:44:40 +01:00
private abstract class AcceptDeclineAccessibilityNodeProvider extends AccessibilityNodeProvider {
2020-08-14 18:58:22 +02:00
private final View hostView;
private final int virtualViewsCount;
private final Rect rect = new Rect();
private final AccessibilityManager accessibilityManager;
private AcceptDeclineAccessibilityNodeProvider(View hostView, int virtualViewsCount) {
this.hostView = hostView;
this.virtualViewsCount = virtualViewsCount;
this.accessibilityManager = ContextCompat.getSystemService(hostView.getContext(), AccessibilityManager.class);
}
@Override
public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
2020-08-15 02:01:55 +02:00
AccessibilityNodeInfo nodeInfo;
2020-08-14 18:58:22 +02:00
if (virtualViewId == HOST_VIEW_ID) {
nodeInfo = AccessibilityNodeInfo.obtain(hostView);
nodeInfo.setPackageName(hostView.getContext().getPackageName());
for (int i = 0; i < virtualViewsCount; i++) {
nodeInfo.addChild(hostView, i);
}
} else {
nodeInfo = AccessibilityNodeInfo.obtain(hostView, virtualViewId);
nodeInfo.setPackageName(hostView.getContext().getPackageName());
2020-08-15 02:01:55 +02:00
if (Build.VERSION.SDK_INT >= 21) {
nodeInfo.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
}
2020-08-14 18:58:22 +02:00
nodeInfo.setText(getVirtualViewText(virtualViewId));
nodeInfo.setClassName(Button.class.getName());
2020-08-15 02:01:55 +02:00
if (Build.VERSION.SDK_INT >= 24) {
nodeInfo.setImportantForAccessibility(true);
}
2020-08-14 18:58:22 +02:00
nodeInfo.setVisibleToUser(true);
nodeInfo.setClickable(true);
nodeInfo.setEnabled(true);
nodeInfo.setParent(hostView);
getVirtualViewBoundsInScreen(virtualViewId, rect);
nodeInfo.setBoundsInScreen(rect);
}
return nodeInfo;
}
@Override
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
if (virtualViewId == HOST_VIEW_ID) {
return hostView.performAccessibilityAction(action, arguments);
} else {
if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) {
2022-03-24 07:44:40 +01:00
currentFocusedVirtualViewId = virtualViewId;
2020-08-14 18:58:22 +02:00
sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
2021-01-28 15:15:51 +01:00
} else if (action == AccessibilityNodeInfo.ACTION_CLICK) {
onVirtualViewClick(virtualViewId);
2020-08-14 18:58:22 +02:00
}
}
2022-03-24 07:44:40 +01:00
return true;// For action accessibilityFocus should be return true too,because in other case screenreader will consider,what it's the last node on the screen,and we will hear sound fron it,which announce about it.
2020-08-14 18:58:22 +02:00
}
2022-03-24 07:44:40 +01:00
public boolean dispatchHoverEvent(MotionEvent event) {
2020-08-14 18:58:22 +02:00
final int x = (int) event.getX();
final int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) {
for (int i = 0; i < virtualViewsCount; i++) {
getVirtualViewBoundsInParent(i, rect);
if (rect.contains(x, y)) {
if (i != currentFocusedVirtualViewId) {
currentFocusedVirtualViewId = i;
sendAccessibilityEventForVirtualView(i, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
}
return true;
}
}
} else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
2022-03-24 07:44:40 +01:00
if (currentFocusedVirtualViewId != -1) {
currentFocusedVirtualViewId = -1;
2020-08-14 18:58:22 +02:00
return true;
}
}
return false;
}
private void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) {
if (accessibilityManager.isTouchExplorationEnabled()) {
final ViewParent parent = hostView.getParent();
if (parent != null) {
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.setPackageName(hostView.getContext().getPackageName());
event.setSource(hostView, virtualViewId);
parent.requestSendAccessibilityEvent(hostView, event);
}
}
}
protected abstract CharSequence getVirtualViewText(int virtualViewId);
2020-08-22 01:59:49 +02:00
2020-08-14 18:58:22 +02:00
protected abstract void getVirtualViewBoundsInScreen(int virtualViewId, Rect outRect);
2020-08-22 01:59:49 +02:00
2020-08-14 18:58:22 +02:00
protected abstract void getVirtualViewBoundsInParent(int virtualViewId, Rect outRect);
2021-01-28 15:15:51 +01:00
protected abstract void onVirtualViewClick(int virtualViewId);
2020-08-14 18:58:22 +02:00
}
}