Android: support lambda expressions in Java code

use -classpath instead of -bootclasspath param to allow
javac to use the default boot class path to support
building lambdas, pass the user Android class via -classpath.

Task-number: QTBUG-118077
Change-Id: I1ba8274d57e1bd528a1d5b7d779191e7f1412184
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
Assam Boudjelthia 2023-11-16 20:18:49 +02:00
parent 323cf718f6
commit 64fe6d836c
10 changed files with 466 additions and 629 deletions

View File

@ -19,7 +19,8 @@ function(qt_internal_add_jar target)
set(javac_source_version "8") set(javac_source_version "8")
endif() endif()
set(CMAKE_JAVA_COMPILE_FLAGS -source "${javac_source_version}" -target "${javac_target_version}" -Xlint:unchecked -bootclasspath "${QT_ANDROID_JAR}") set(CMAKE_JAVA_COMPILE_FLAGS -source "${javac_source_version}" -target "${javac_target_version}"
-Xlint:unchecked -classpath "${QT_ANDROID_JAR}")
add_jar(${ARGV}) add_jar(${ARGV})
foreach(f IN LISTS arg_SOURCES) foreach(f IN LISTS arg_SOURCES)

View File

@ -63,12 +63,7 @@ public class QtActivityDelegate
setActionBarVisibility(false); setActionBarVisibility(false);
QtInputDelegate.KeyboardVisibilityListener keyboardVisibilityListener = QtInputDelegate.KeyboardVisibilityListener keyboardVisibilityListener =
new QtInputDelegate.KeyboardVisibilityListener() { () -> m_displayManager.updateFullScreen(m_activity);
@Override
public void onKeyboardVisibilityChange() {
m_displayManager.updateFullScreen(m_activity);
}
};
m_inputDelegate = new QtInputDelegate(m_activity, keyboardVisibilityListener); m_inputDelegate = new QtInputDelegate(m_activity, keyboardVisibilityListener);
try { try {
@ -98,13 +93,10 @@ public class QtActivityDelegate
@UsedFromNativeCode @UsedFromNativeCode
public void setSystemUiVisibility(int systemUiVisibility) public void setSystemUiVisibility(int systemUiVisibility)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override m_displayManager.setSystemUiVisibility(m_activity, systemUiVisibility);
public void run() { m_layout.requestLayout();
m_displayManager.setSystemUiVisibility(m_activity, systemUiVisibility); QtNative.updateWindow();
m_layout.requestLayout();
QtNative.updateWindow();
}
}); });
} }
@ -160,16 +152,13 @@ public class QtActivityDelegate
if (m_surfaces != null) if (m_surfaces != null)
return; return;
Runnable startApplication = new Runnable() { Runnable startApplication = () -> {
@Override try {
public void run() { QtNative.startApplication(appParams, mainLib);
try { m_started = true;
QtNative.startApplication(appParams, mainLib); } catch (Exception e) {
m_started = true; e.printStackTrace();
} catch (Exception e) { m_activity.finish();
e.printStackTrace();
m_activity.finish();
}
} }
}; };
@ -224,27 +213,24 @@ public class QtActivityDelegate
: m_activity.getDisplay().getRefreshRate(); : m_activity.getDisplay().getRefreshRate();
QtDisplayManager.handleRefreshRateChanged(refreshRate); QtDisplayManager.handleRefreshRateChanged(refreshRate);
m_layout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { m_layout.getViewTreeObserver().addOnPreDrawListener(() -> {
@Override if (!m_inputDelegate.isKeyboardVisible())
public boolean onPreDraw() { return true;
if (!m_inputDelegate.isKeyboardVisible())
return true;
Rect r = new Rect(); Rect r = new Rect();
m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
final int kbHeight = metrics.heightPixels - r.bottom; final int kbHeight = metrics.heightPixels - r.bottom;
if (kbHeight < 0) { if (kbHeight < 0) {
m_inputDelegate.setKeyboardVisibility(false, System.nanoTime()); m_inputDelegate.setKeyboardVisibility(false, System.nanoTime());
return true;
}
final int[] location = new int[2];
m_layout.getLocationOnScreen(location);
QtInputDelegate.keyboardGeometryChanged(location[0], r.bottom - location[1],
r.width(), kbHeight);
return true; return true;
} }
final int[] location = new int[2];
m_layout.getLocationOnScreen(location);
QtInputDelegate.keyboardGeometryChanged(location[0], r.bottom - location[1],
r.width(), kbHeight);
return true;
}); });
m_inputDelegate.setEditPopupMenu(new EditPopupMenu(m_activity, m_layout)); m_inputDelegate.setEditPopupMenu(new EditPopupMenu(m_activity, m_layout));
} }
@ -256,39 +242,36 @@ public class QtActivityDelegate
public void hideSplashScreen(final int duration) public void hideSplashScreen(final int duration)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_splashScreen == null)
public void run() { return;
if (m_splashScreen == null)
return;
if (duration <= 0) { if (duration <= 0) {
m_layout.removeView(m_splashScreen); m_layout.removeView(m_splashScreen);
m_splashScreen = null; m_splashScreen = null;
return; return;
}
final Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(duration);
fadeOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
hideSplashScreen(0);
} }
final Animation fadeOut = new AlphaAnimation(1, 0); @Override
fadeOut.setInterpolator(new AccelerateInterpolator()); public void onAnimationRepeat(Animation animation) {
fadeOut.setDuration(duration); }
fadeOut.setAnimationListener(new Animation.AnimationListener() { @Override
@Override public void onAnimationStart(Animation animation) {
public void onAnimationEnd(Animation animation) { }
hideSplashScreen(0); });
}
@Override m_splashScreen.startAnimation(fadeOut);
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
});
m_splashScreen.startAnimation(fadeOut);
}
}); });
} }
@ -342,13 +325,8 @@ public class QtActivityDelegate
public void initializeAccessibility() public void initializeAccessibility()
{ {
final QtActivityDelegate currentDelegate = this; final QtActivityDelegate currentDelegate = this;
QtNative.runAction(new Runnable() { QtNative.runAction(() -> m_accessibilityDelegate = new QtAccessibilityDelegate(m_activity,
@Override m_layout, currentDelegate));
public void run() {
m_accessibilityDelegate = new QtAccessibilityDelegate(m_activity, m_layout,
currentDelegate);
}
});
} }
void handleUiModeChange(int uiMode) void handleUiModeChange(int uiMode)
@ -381,23 +359,13 @@ public class QtActivityDelegate
@UsedFromNativeCode @UsedFromNativeCode
public void resetOptionsMenu() public void resetOptionsMenu()
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> m_activity.invalidateOptionsMenu());
@Override
public void run() {
m_activity.invalidateOptionsMenu();
}
});
} }
@UsedFromNativeCode @UsedFromNativeCode
public void openOptionsMenu() public void openOptionsMenu()
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> m_activity.openOptionsMenu());
@Override
public void run() {
m_activity.openOptionsMenu();
}
});
} }
private boolean m_contextMenuVisible = false; private boolean m_contextMenuVisible = false;
@ -411,38 +379,22 @@ public class QtActivityDelegate
@UsedFromNativeCode @UsedFromNativeCode
public void openContextMenu(final int x, final int y, final int w, final int h) public void openContextMenu(final int x, final int y, final int w, final int h)
{ {
m_layout.postDelayed(new Runnable() { m_layout.postDelayed(() -> {
@Override m_layout.setLayoutParams(m_inputDelegate.getQtEditText(), new QtLayout.LayoutParams(w, h, x, y), false);
public void run() { PopupMenu popup = new PopupMenu(m_activity, m_inputDelegate.getQtEditText());
m_layout.setLayoutParams(m_inputDelegate.getQtEditText(), new QtLayout.LayoutParams(w, h, x, y), false); QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu());
PopupMenu popup = new PopupMenu(m_activity, m_inputDelegate.getQtEditText()); popup.setOnMenuItemClickListener(menuItem ->
QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu()); m_activity.onContextItemSelected(menuItem));
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popup.setOnDismissListener(popupMenu ->
@Override m_activity.onContextMenuClosed(popupMenu.getMenu()));
public boolean onMenuItemClick(MenuItem menuItem) { popup.show();
return m_activity.onContextItemSelected(menuItem);
}
});
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
@Override
public void onDismiss(PopupMenu popupMenu) {
m_activity.onContextMenuClosed(popupMenu.getMenu());
}
});
popup.show();
}
}, 100); }, 100);
} }
@UsedFromNativeCode @UsedFromNativeCode
public void closeContextMenu() public void closeContextMenu()
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> m_activity.closeContextMenu());
@Override
public void run() {
m_activity.closeContextMenu();
}
});
} }
void setActionBarVisibility(boolean visible) void setActionBarVisibility(boolean visible)
@ -457,117 +409,104 @@ public class QtActivityDelegate
@UsedFromNativeCode @UsedFromNativeCode
public void insertNativeView(int id, View view, int x, int y, int w, int h) { public void insertNativeView(int id, View view, int x, int y, int w, int h) {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_dummyView != null) {
public void run() { m_layout.removeView(m_dummyView);
if (m_dummyView != null) { m_dummyView = null;
m_layout.removeView(m_dummyView); }
m_dummyView = null;
}
if (m_nativeViews.containsKey(id)) if (m_nativeViews.containsKey(id))
m_layout.removeView(m_nativeViews.remove(id)); m_layout.removeView(m_nativeViews.remove(id));
if (w < 0 || h < 0) { if (w < 0 || h < 0) {
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT)); ViewGroup.LayoutParams.MATCH_PARENT));
} else { } else {
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
} }
view.setId(id); view.setId(id);
m_layout.addView(view); m_layout.addView(view);
m_nativeViews.put(id, view); m_nativeViews.put(id, view);
} });
});
} }
@UsedFromNativeCode @UsedFromNativeCode
public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) { public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_surfaces.size() == 0) {
public void run() { TypedValue attr = new TypedValue();
if (m_surfaces.size() == 0) { m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true);
TypedValue attr = new TypedValue(); if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT && attr.type <= TypedValue.TYPE_LAST_COLOR_INT) {
m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true); m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(attr.data));
if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT && attr.type <= TypedValue.TYPE_LAST_COLOR_INT) {
m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(attr.data));
} else {
m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme()));
}
if (m_dummyView != null) {
m_layout.removeView(m_dummyView);
m_dummyView = null;
}
}
if (m_surfaces.containsKey(id))
m_layout.removeView(m_surfaces.remove(id));
QtSurface surface = new QtSurface(m_activity, id, onTop, imageDepth);
if (w < 0 || h < 0) {
surface.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
} else { } else {
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme()));
}
if (m_dummyView != null) {
m_layout.removeView(m_dummyView);
m_dummyView = null;
} }
// Native views are always inserted in the end of the stack (i.e., on top).
// All other views are stacked based on the order they are created.
final int surfaceCount = getSurfaceCount();
m_layout.addView(surface, surfaceCount);
m_surfaces.put(id, surface);
if (!m_splashScreenSticky)
hideSplashScreen();
} }
if (m_surfaces.containsKey(id))
m_layout.removeView(m_surfaces.remove(id));
QtSurface surface = new QtSurface(m_activity, id, onTop, imageDepth);
if (w < 0 || h < 0) {
surface.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
} else {
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
}
// Native views are always inserted in the end of the stack (i.e., on top).
// All other views are stacked based on the order they are created.
final int surfaceCount = getSurfaceCount();
m_layout.addView(surface, surfaceCount);
m_surfaces.put(id, surface);
if (!m_splashScreenSticky)
hideSplashScreen();
}); });
} }
@UsedFromNativeCode @UsedFromNativeCode
public void setSurfaceGeometry(int id, int x, int y, int w, int h) { public void setSurfaceGeometry(int id, int x, int y, int w, int h) {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_surfaces.containsKey(id)) {
public void run() { QtSurface surface = m_surfaces.get(id);
if (m_surfaces.containsKey(id)) { surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
QtSurface surface = m_surfaces.get(id); } else if (m_nativeViews.containsKey(id)) {
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); View view = m_nativeViews.get(id);
} else if (m_nativeViews.containsKey(id)) { view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
View view = m_nativeViews.get(id); } else {
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); Log.e(QtNative.QtTAG, "Surface " + id + " not found!");
} else {
Log.e(QtNative.QtTAG, "Surface " + id + " not found!");
return;
}
} }
}); });
} }
@UsedFromNativeCode @UsedFromNativeCode
public void destroySurface(int id) { public void destroySurface(int id) {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override View view = null;
public void run() {
View view = null;
if (m_surfaces.containsKey(id)) { if (m_surfaces.containsKey(id)) {
view = m_surfaces.remove(id); view = m_surfaces.remove(id);
} else if (m_nativeViews.containsKey(id)) { } else if (m_nativeViews.containsKey(id)) {
view = m_nativeViews.remove(id); view = m_nativeViews.remove(id);
} else { } else {
Log.e(QtNative.QtTAG, "Surface " + id + " not found!"); Log.e(QtNative.QtTAG, "Surface " + id + " not found!");
} }
if (view == null) if (view == null)
return; return;
// Keep last frame in stack until it is replaced to get correct // Keep last frame in stack until it is replaced to get correct
// shutdown transition // shutdown transition
if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) { if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) {
m_dummyView = view; m_dummyView = view;
} else { } else {
m_layout.removeView(view); m_layout.removeView(view);
}
} }
}); });
} }
@ -580,41 +519,35 @@ public class QtActivityDelegate
@UsedFromNativeCode @UsedFromNativeCode
public void bringChildToFront(int id) public void bringChildToFront(int id)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override View view = m_surfaces.get(id);
public void run() { if (view != null) {
View view = m_surfaces.get(id); final int surfaceCount = getSurfaceCount();
if (view != null) { if (surfaceCount > 0)
final int surfaceCount = getSurfaceCount(); m_layout.moveChild(view, surfaceCount - 1);
if (surfaceCount > 0) return;
m_layout.moveChild(view, surfaceCount - 1);
return;
}
view = m_nativeViews.get(id);
if (view != null)
m_layout.moveChild(view, -1);
} }
view = m_nativeViews.get(id);
if (view != null)
m_layout.moveChild(view, -1);
}); });
} }
@UsedFromNativeCode @UsedFromNativeCode
public void bringChildToBack(int id) public void bringChildToBack(int id)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override View view = m_surfaces.get(id);
public void run() { if (view != null) {
View view = m_surfaces.get(id); m_layout.moveChild(view, 0);
if (view != null) { return;
m_layout.moveChild(view, 0); }
return;
}
view = m_nativeViews.get(id); view = m_nativeViews.get(id);
if (view != null) { if (view != null) {
final int index = getSurfaceCount(); final int index = getSurfaceCount();
m_layout.moveChild(view, index); m_layout.moveChild(view, index);
}
} }
}); });
} }

View File

@ -52,12 +52,7 @@ public class QtActivityLoader extends QtLoader {
"fatal_error_msg", "string", packageName); "fatal_error_msg", "string", packageName);
errorDialog.setMessage(resources.getString(id)); errorDialog.setMessage(resources.getString(id));
errorDialog.setButton(Dialog.BUTTON_POSITIVE, resources.getString(android.R.string.ok), errorDialog.setButton(Dialog.BUTTON_POSITIVE, resources.getString(android.R.string.ok),
new DialogInterface.OnClickListener() { (dialog, which) -> finish());
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
errorDialog.show(); errorDialog.show();
} }

View File

@ -35,21 +35,14 @@ public class QtClipboardManager
{ {
if (context != null) { if (context != null) {
final Semaphore semaphore = new Semaphore(0); final Semaphore semaphore = new Semaphore(0);
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override m_clipboardManager =
public void run() { (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
m_clipboardManager = if (m_clipboardManager != null) {
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); m_clipboardManager.addPrimaryClipChangedListener(
if (m_clipboardManager != null) { () -> onClipboardDataChanged(m_nativePointer));
m_clipboardManager.addPrimaryClipChangedListener(
new ClipboardManager.OnPrimaryClipChangedListener() {
public void onPrimaryClipChanged() {
onClipboardDataChanged(m_nativePointer);
}
});
}
semaphore.release();
} }
semaphore.release();
}); });
try { try {
semaphore.acquire(); semaphore.acquire();

View File

@ -188,12 +188,9 @@ public class QtInputDelegate {
{ {
if (m_imm == null) if (m_imm == null)
return; return;
m_editText.postDelayed(new Runnable() { m_editText.postDelayed(() -> {
@Override m_imm.restartInput(m_editText);
public void run() { m_editText.m_optionsChanged = false;
m_imm.restartInput(m_editText);
m_editText.m_optionsChanged = false;
}
}, 5); }, 5);
} }
@ -201,53 +198,47 @@ public class QtInputDelegate {
final int x, final int y, final int width, final int height, final int x, final int y, final int width, final int height,
final int inputHints, final int enterKeyType) final int inputHints, final int enterKeyType)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_imm == null)
public void run() { return;
if (m_imm == null)
return;
if (updateSoftInputMode(activity, height)) if (updateSoftInputMode(activity, height))
return; return;
setEditTextOptions(enterKeyType, inputHints); setEditTextOptions(enterKeyType, inputHints);
// TODO: The editText is added to the QtLayout, but is it ever removed? // TODO: The editText is added to the QtLayout, but is it ever removed?
QtLayout.LayoutParams layoutParams = new QtLayout.LayoutParams(width, height, x, y); QtLayout.LayoutParams layoutParams = new QtLayout.LayoutParams(width, height, x, y);
layout.setLayoutParams(m_editText, layoutParams, false); layout.setLayoutParams(m_editText, layoutParams, false);
m_editText.requestFocus(); m_editText.requestFocus();
m_editText.postDelayed(new Runnable() { m_editText.postDelayed(() -> {
m_imm.showSoftInput(m_editText, 0, new ResultReceiver(new Handler()) {
@Override @Override
public void run() { protected void onReceiveResult(int resultCode, Bundle resultData) {
m_imm.showSoftInput(m_editText, 0, new ResultReceiver(new Handler()) { switch (resultCode) {
@Override case InputMethodManager.RESULT_SHOWN:
protected void onReceiveResult(int resultCode, Bundle resultData) { QtNativeInputConnection.updateCursorPosition();
switch (resultCode) { //FALLTHROUGH
case InputMethodManager.RESULT_SHOWN: case InputMethodManager.RESULT_UNCHANGED_SHOWN:
QtNativeInputConnection.updateCursorPosition(); setKeyboardVisibility(true, System.nanoTime());
//FALLTHROUGH if (m_softInputMode == 0) {
case InputMethodManager.RESULT_UNCHANGED_SHOWN: probeForKeyboardHeight(layout, activity,
setKeyboardVisibility(true, System.nanoTime()); x, y, width, height, inputHints, enterKeyType);
if (m_softInputMode == 0) {
probeForKeyboardHeight(layout, activity,
x, y, width, height, inputHints, enterKeyType);
}
break;
case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
setKeyboardVisibility(false, System.nanoTime());
break;
} }
} break;
}); case InputMethodManager.RESULT_HIDDEN:
if (m_editText.m_optionsChanged) { case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
m_imm.restartInput(m_editText); setKeyboardVisibility(false, System.nanoTime());
m_editText.m_optionsChanged = false; break;
} }
} }
}, 15); });
} if (m_editText.m_optionsChanged) {
m_imm.restartInput(m_editText);
m_editText.m_optionsChanged = false;
}
}, 15);
}); });
} }
@ -392,35 +383,32 @@ public class QtInputDelegate {
private void probeForKeyboardHeight(QtLayout layout, Activity activity, int x, int y, private void probeForKeyboardHeight(QtLayout layout, Activity activity, int x, int y,
int width, int height, int inputHints, int enterKeyType) int width, int height, int inputHints, int enterKeyType)
{ {
layout.postDelayed(new Runnable() { layout.postDelayed(() -> {
@Override if (!m_keyboardIsVisible)
public void run() { return;
if (!m_keyboardIsVisible) DisplayMetrics metrics = new DisplayMetrics();
return; activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
DisplayMetrics metrics = new DisplayMetrics(); Rect r = new Rect();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
Rect r = new Rect(); if (metrics.heightPixels != r.bottom) {
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); if (metrics.widthPixels > metrics.heightPixels) { // landscape
if (metrics.heightPixels != r.bottom) { if (m_landscapeKeyboardHeight != r.bottom) {
if (metrics.widthPixels > metrics.heightPixels) { // landscape m_landscapeKeyboardHeight = r.bottom;
if (m_landscapeKeyboardHeight != r.bottom) { showSoftwareKeyboard(activity, layout, x, y, width, height,
m_landscapeKeyboardHeight = r.bottom; inputHints, enterKeyType);
showSoftwareKeyboard(activity, layout, x, y, width, height,
inputHints, enterKeyType);
}
} else {
if (m_portraitKeyboardHeight != r.bottom) {
m_portraitKeyboardHeight = r.bottom;
showSoftwareKeyboard(activity, layout, x, y, width, height,
inputHints, enterKeyType);
}
} }
} else { } else {
// no luck ? if (m_portraitKeyboardHeight != r.bottom) {
// maybe the delay was too short, so let's make it longer m_portraitKeyboardHeight = r.bottom;
if (m_probeKeyboardHeightDelayMs < 1000) showSoftwareKeyboard(activity, layout, x, y, width, height,
m_probeKeyboardHeightDelayMs *= 2; inputHints, enterKeyType);
}
} }
} else {
// no luck ?
// maybe the delay was too short, so let's make it longer
if (m_probeKeyboardHeightDelayMs < 1000)
m_probeKeyboardHeightDelayMs *= 2;
} }
}, m_probeKeyboardHeightDelayMs); }, m_probeKeyboardHeightDelayMs);
} }
@ -428,29 +416,26 @@ public class QtInputDelegate {
public void hideSoftwareKeyboard() public void hideSoftwareKeyboard()
{ {
m_isKeyboardHidingAnimationOngoing = true; m_isKeyboardHidingAnimationOngoing = true;
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_imm == null)
public void run() { return;
if (m_imm == null)
return;
m_imm.hideSoftInputFromWindow(m_editText.getWindowToken(), 0, m_imm.hideSoftInputFromWindow(m_editText.getWindowToken(), 0,
new ResultReceiver(new Handler()) { new ResultReceiver(new Handler()) {
@Override @Override
protected void onReceiveResult(int resultCode, Bundle resultData) { protected void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) { switch (resultCode) {
case InputMethodManager.RESULT_SHOWN: case InputMethodManager.RESULT_SHOWN:
case InputMethodManager.RESULT_UNCHANGED_SHOWN: case InputMethodManager.RESULT_UNCHANGED_SHOWN:
setKeyboardVisibility(true, System.nanoTime()); setKeyboardVisibility(true, System.nanoTime());
break; break;
case InputMethodManager.RESULT_HIDDEN: case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_UNCHANGED_HIDDEN: case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
setKeyboardVisibility(false, System.nanoTime()); setKeyboardVisibility(false, System.nanoTime());
break; break;
}
} }
}); }
} });
}); });
} }
@ -458,14 +443,11 @@ public class QtInputDelegate {
public void updateSelection(final int selStart, final int selEnd, public void updateSelection(final int selStart, final int selEnd,
final int candidatesStart, final int candidatesEnd) final int candidatesStart, final int candidatesEnd)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_imm == null)
public void run() { return;
if (m_imm == null)
return;
m_imm.updateSelection(m_editText, selStart, selEnd, candidatesStart, candidatesEnd); m_imm.updateSelection(m_editText, selStart, selEnd, candidatesStart, candidatesEnd);
}
}); });
} }
@ -490,13 +472,8 @@ public class QtInputDelegate {
int editX, int editY, int editButtons, int editX, int editY, int editButtons,
int x1, int y1, int x2, int y2, boolean rtl) int x1, int y1, int x2, int y2, boolean rtl)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> updateHandleImpl(activity, layout, mode, editX, editY, editButtons,
@Override x1, y1, x2, y2, rtl));
public void run() {
updateHandleImpl(activity, layout, mode, editX, editY, editButtons,
x1, y1, x2, y2, rtl);
}
});
} }
private void updateHandleImpl(Activity activity, QtLayout layout, int mode, private void updateHandleImpl(Activity activity, QtLayout layout, int mode,

View File

@ -462,13 +462,10 @@ public abstract class QtLoader {
ArrayList<String> oneEntryArray = new ArrayList<>(Collections.singletonList(mainLibName)); ArrayList<String> oneEntryArray = new ArrayList<>(Collections.singletonList(mainLibName));
String mainLibPath = getLibrariesFullPaths(oneEntryArray).get(0); String mainLibPath = getLibrariesFullPaths(oneEntryArray).get(0);
final boolean[] success = {true}; final boolean[] success = {true};
QtNative.getQtThread().run(new Runnable() { QtNative.getQtThread().run(() -> {
@Override m_mainLib = loadLibraryHelper(mainLibPath);
public void run() { if (m_mainLib == null)
m_mainLib = loadLibraryHelper(mainLibPath); success[0] = false;
if (m_mainLib == null)
success[0] = false;
}
}); });
return success[0]; return success[0];
@ -488,15 +485,12 @@ public abstract class QtLoader {
ArrayList<String> fullPathLibs = getLibrariesFullPaths(libraries); ArrayList<String> fullPathLibs = getLibrariesFullPaths(libraries);
final boolean[] success = {true}; final boolean[] success = {true};
QtNative.getQtThread().run(new Runnable() { QtNative.getQtThread().run(() -> {
@Override for (int i = 0; i < fullPathLibs.size(); ++i) {
public void run() { String libName = fullPathLibs.get(i);
for (int i = 0; i < fullPathLibs.size(); ++i) { if (loadLibraryHelper(libName) == null) {
String libName = fullPathLibs.get(i); success[0] = false;
if (loadLibraryHelper(libName) == null) { break;
success[0] = false;
break;
}
} }
} }
}); });

View File

@ -159,177 +159,163 @@ public class QtMessageDialogHelper
public void show(long handler) public void show(long handler)
{ {
m_handler = handler; m_handler = handler;
m_activity.runOnUiThread( new Runnable() { m_activity.runOnUiThread(() -> {
@Override if (m_dialog != null && m_dialog.isShowing())
public void run() { m_dialog.dismiss();
if (m_dialog != null && m_dialog.isShowing())
m_dialog.dismiss();
m_dialog = new AlertDialog.Builder(m_activity).create(); m_dialog = new AlertDialog.Builder(m_activity).create();
m_theme = m_dialog.getWindow().getContext().getTheme(); m_theme = m_dialog.getWindow().getContext().getTheme();
if (m_title != null) if (m_title != null)
m_dialog.setTitle(m_title); m_dialog.setTitle(m_title);
m_dialog.setOnCancelListener( new DialogInterface.OnCancelListener() { m_dialog.setOnCancelListener(dialogInterface -> QtNativeDialogHelper.dialogResult(handler(), -1));
@Override m_dialog.setCancelable(m_buttonsList == null);
public void onCancel(DialogInterface dialogInterface) { m_dialog.setCanceledOnTouchOutside(m_buttonsList == null);
QtNativeDialogHelper.dialogResult(handler(), -1); m_dialog.setIcon(getIconDrawable());
} ScrollView scrollView = new ScrollView(m_activity);
}); RelativeLayout dialogLayout = new RelativeLayout(m_activity);
m_dialog.setCancelable(m_buttonsList == null); int id = 1;
m_dialog.setCanceledOnTouchOutside(m_buttonsList == null); View lastView = null;
m_dialog.setIcon(getIconDrawable()); View.OnLongClickListener copyText = view -> {
ScrollView scrollView = new ScrollView(m_activity); TextView tv = (TextView)view;
RelativeLayout dialogLayout = new RelativeLayout(m_activity); if (tv != null) {
int id = 1; ClipboardManager cm = (ClipboardManager) m_activity.getSystemService(Context.CLIPBOARD_SERVICE);
View lastView = null; cm.setText(tv.getText());
View.OnLongClickListener copyText = new View.OnLongClickListener() { }
@Override return true;
public boolean onLongClick(View view) { };
TextView tv = (TextView)view; if (m_text != null)
if (tv != null) { {
ClipboardManager cm = (android.text.ClipboardManager) m_activity.getSystemService(Context.CLIPBOARD_SERVICE); TextView view = new TextView(m_activity);
cm.setText(tv.getText()); view.setId(id++);
} view.setOnLongClickListener(copyText);
return true; view.setLongClickable(true);
}
};
if (m_text != null)
{
TextView view = new TextView(m_activity);
view.setId(id++);
view.setOnLongClickListener(copyText);
view.setLongClickable(true);
view.setText(m_text); view.setText(m_text);
view.setTextAppearance(m_activity, android.R.style.TextAppearance_Medium); view.setTextAppearance(m_activity, android.R.style.TextAppearance_Medium);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layout.setMargins(16, 8, 16, 8); layout.setMargins(16, 8, 16, 8);
layout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
dialogLayout.addView(view, layout);
lastView = view;
}
if (m_informativeText != null)
{
TextView view= new TextView(m_activity);
view.setId(id++);
view.setOnLongClickListener(copyText);
view.setLongClickable(true);
view.setText(m_informativeText);
view.setTextAppearance(m_activity, android.R.style.TextAppearance_Medium);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layout.setMargins(16, 8, 16, 8);
if (lastView != null)
layout.addRule(RelativeLayout.BELOW, lastView.getId());
else
layout.addRule(RelativeLayout.ALIGN_PARENT_TOP); layout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
dialogLayout.addView(view, layout); dialogLayout.addView(view, layout);
lastView = view; lastView = view;
} }
if (m_informativeText != null) if (m_detailedText != null)
{
TextView view= new TextView(m_activity);
view.setId(id++);
view.setOnLongClickListener(copyText);
view.setLongClickable(true);
view.setText(m_detailedText);
view.setTextAppearance(m_activity, android.R.style.TextAppearance_Small);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layout.setMargins(16, 8, 16, 8);
if (lastView != null)
layout.addRule(RelativeLayout.BELOW, lastView.getId());
else
layout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
dialogLayout.addView(view, layout);
lastView = view;
}
if (m_buttonsList != null)
{
LinearLayout buttonsLayout = new LinearLayout(m_activity);
buttonsLayout.setOrientation(LinearLayout.HORIZONTAL);
buttonsLayout.setId(id++);
boolean firstButton = true;
for (ButtonStruct button: m_buttonsList)
{ {
TextView view= new TextView(m_activity); Button bv;
view.setId(id++);
view.setOnLongClickListener(copyText);
view.setLongClickable(true);
view.setText(m_informativeText);
view.setTextAppearance(m_activity, android.R.style.TextAppearance_Medium);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layout.setMargins(16, 8, 16, 8);
if (lastView != null)
layout.addRule(RelativeLayout.BELOW, lastView.getId());
else
layout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
dialogLayout.addView(view, layout);
lastView = view;
}
if (m_detailedText != null)
{
TextView view= new TextView(m_activity);
view.setId(id++);
view.setOnLongClickListener(copyText);
view.setLongClickable(true);
view.setText(m_detailedText);
view.setTextAppearance(m_activity, android.R.style.TextAppearance_Small);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layout.setMargins(16, 8, 16, 8);
if (lastView != null)
layout.addRule(RelativeLayout.BELOW, lastView.getId());
else
layout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
dialogLayout.addView(view, layout);
lastView = view;
}
if (m_buttonsList != null)
{
LinearLayout buttonsLayout = new LinearLayout(m_activity);
buttonsLayout.setOrientation(LinearLayout.HORIZONTAL);
buttonsLayout.setId(id++);
boolean firstButton = true;
for (ButtonStruct button: m_buttonsList)
{
Button bv;
try {
bv = new Button(m_activity, null, Class.forName("android.R$attr").getDeclaredField("borderlessButtonStyle").getInt(null));
} catch (Exception e) {
bv = new Button(m_activity);
e.printStackTrace();
}
bv.setText(button.m_text);
bv.setOnClickListener(button);
if (!firstButton) // first button
{
View spacer = new View(m_activity);
try {
LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(1,
RelativeLayout.LayoutParams.MATCH_PARENT);
spacer.setBackgroundDrawable(getStyledDrawable("dividerVertical"));
buttonsLayout.addView(spacer, layout);
} catch (Exception e) {
e.printStackTrace();
}
}
LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT, 1.0f);
buttonsLayout.addView(bv, layout);
firstButton = false;
}
try { try {
View horizontalDevider = new View(m_activity); bv = new Button(m_activity, null, Class.forName("android.R$attr").getDeclaredField("borderlessButtonStyle").getInt(null));
horizontalDevider.setId(id++);
horizontalDevider.setBackgroundDrawable(getStyledDrawable("dividerHorizontal"));
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 1);
relativeParams.setMargins(0, 10, 0, 0);
if (lastView != null) {
relativeParams.addRule(RelativeLayout.BELOW, lastView.getId());
}
else
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
dialogLayout.addView(horizontalDevider, relativeParams);
lastView = horizontalDevider;
} catch (Exception e) { } catch (Exception e) {
bv = new Button(m_activity);
e.printStackTrace(); e.printStackTrace();
} }
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
bv.setText(button.m_text);
bv.setOnClickListener(button);
if (!firstButton) // first button
{
View spacer = new View(m_activity);
try {
LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(1,
RelativeLayout.LayoutParams.MATCH_PARENT);
spacer.setBackgroundDrawable(getStyledDrawable("dividerVertical"));
buttonsLayout.addView(spacer, layout);
} catch (Exception e) {
e.printStackTrace();
}
}
LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT, 1.0f);
buttonsLayout.addView(bv, layout);
firstButton = false;
}
try {
View horizontalDevider = new View(m_activity);
horizontalDevider.setId(id++);
horizontalDevider.setBackgroundDrawable(getStyledDrawable("dividerHorizontal"));
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 1);
relativeParams.setMargins(0, 10, 0, 0);
if (lastView != null) { if (lastView != null) {
relativeParams.addRule(RelativeLayout.BELOW, lastView.getId()); relativeParams.addRule(RelativeLayout.BELOW, lastView.getId());
} }
else else
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
relativeParams.setMargins(2, 0, 2, 0); dialogLayout.addView(horizontalDevider, relativeParams);
dialogLayout.addView(buttonsLayout, relativeParams); lastView = horizontalDevider;
} catch (Exception e) {
e.printStackTrace();
} }
scrollView.addView(dialogLayout); RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
m_dialog.setView(scrollView); if (lastView != null) {
m_dialog.show(); relativeParams.addRule(RelativeLayout.BELOW, lastView.getId());
}
else
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
relativeParams.setMargins(2, 0, 2, 0);
dialogLayout.addView(buttonsLayout, relativeParams);
} }
scrollView.addView(dialogLayout);
m_dialog.setView(scrollView);
m_dialog.show();
}); });
} }
@UsedFromNativeCode @UsedFromNativeCode
public void hide() public void hide()
{ {
m_activity.runOnUiThread( new Runnable() { m_activity.runOnUiThread(() -> {
@Override if (m_dialog != null && m_dialog.isShowing())
public void run() { m_dialog.dismiss();
if (m_dialog != null && m_dialog.isShowing()) reset();
m_dialog.dismiss();
reset();
}
}); });
} }

View File

@ -46,12 +46,7 @@ public class QtNative
private static final QtThread m_qtThread = new QtThread(); private static final QtThread m_qtThread = new QtThread();
private static ClassLoader m_classLoader = null; private static ClassLoader m_classLoader = null;
private static final Runnable runPendingCppRunnablesRunnable = new Runnable() { private static final Runnable runPendingCppRunnablesRunnable = QtNative::runPendingCppRunnables;
@Override
public void run() {
runPendingCppRunnables();
}
};
public static boolean isStarted() public static boolean isStarted()
{ {
@ -255,12 +250,7 @@ public class QtNative
@UsedFromNativeCode @UsedFromNativeCode
private static void setViewVisibility(final View view, final boolean visible) private static void setViewVisibility(final View view, final boolean visible)
{ {
runAction(new Runnable() { runAction(() -> view.setVisibility(visible ? View.VISIBLE : View.GONE));
@Override
public void run() {
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}
});
} }
public static boolean startApplication(ArrayList<String> params, String mainLib) public static boolean startApplication(ArrayList<String> params, String mainLib)
@ -269,18 +259,8 @@ public class QtNative
synchronized (m_mainActivityMutex) { synchronized (m_mainActivityMutex) {
String paramsStr = String.join("\t", params); String paramsStr = String.join("\t", params);
final String qtParams = mainLib + "\t" + paramsStr; final String qtParams = mainLib + "\t" + paramsStr;
m_qtThread.run(new Runnable() { m_qtThread.run(() -> res[0] = startQtAndroidPlugin(qtParams));
@Override m_qtThread.post(QtNative::startQtApplication);
public void run() {
res[0] = startQtAndroidPlugin(qtParams);
}
});
m_qtThread.post(new Runnable() {
@Override
public void run() {
startQtApplication();
}
});
waitForServiceSetup(); waitForServiceSetup();
m_started = true; m_started = true;
} }
@ -289,17 +269,14 @@ public class QtNative
public static void quitApp() public static void quitApp()
{ {
runAction(new Runnable() { runAction(() -> {
@Override quitQtAndroidPlugin();
public void run() { if (isActivityValid())
quitQtAndroidPlugin(); m_activity.get().finish();
if (isActivityValid()) if (isServiceValid())
m_activity.get().finish(); m_service.get().stopSelf();
if (isServiceValid())
m_service.get().stopSelf();
m_started = false; m_started = false;
}
}); });
} }

View File

@ -45,12 +45,9 @@ public class QtThread {
public void run(final Runnable runnable) { public void run(final Runnable runnable) {
final Semaphore sem = new Semaphore(0); final Semaphore sem = new Semaphore(0);
synchronized (m_qtThread) { synchronized (m_qtThread) {
m_pendingRunnables.add(new Runnable() { m_pendingRunnables.add(() -> {
@Override runnable.run();
public void run() { sem.release();
runnable.run();
sem.release();
}
}); });
m_qtThread.notify(); m_qtThread.notify();
} }

View File

@ -161,99 +161,83 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
public void notifyScrolledEvent(int viewId) public void notifyScrolledEvent(int viewId)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> sendEventForVirtualViewId(viewId,
@Override AccessibilityEvent.TYPE_VIEW_SCROLLED));
public void run() {
sendEventForVirtualViewId(viewId, AccessibilityEvent.TYPE_VIEW_SCROLLED);
}
});
} }
public void notifyLocationChange(int viewId) public void notifyLocationChange(int viewId)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_focusedVirtualViewId == viewId)
public void run() { invalidateVirtualViewId(m_focusedVirtualViewId);
if (m_focusedVirtualViewId == viewId)
invalidateVirtualViewId(m_focusedVirtualViewId);
}
}); });
} }
public void notifyObjectHide(int viewId, int parentId) public void notifyObjectHide(int viewId, int parentId)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override // If the object had accessibility focus, we need to clear it.
public void run() { // Note: This code is mostly copied from
// If the object had accessibility focus, we need to clear it. // AccessibilityNodeProvider::performAction, but we remove the
// Note: This code is mostly copied from // focus only if the focused view id matches the one that was hidden.
// AccessibilityNodeProvider::performAction, but we remove the if (m_focusedVirtualViewId == viewId) {
// focus only if the focused view id matches the one that was hidden. m_focusedVirtualViewId = INVALID_ID;
if (m_focusedVirtualViewId == viewId) { m_view.invalidate();
m_focusedVirtualViewId = INVALID_ID; sendEventForVirtualViewId(viewId,
m_view.invalidate(); AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
sendEventForVirtualViewId(viewId,
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
}
// When the object is hidden, we need to notify its parent about
// content change, not the hidden object itself
invalidateVirtualViewId(parentId);
} }
// When the object is hidden, we need to notify its parent about
// content change, not the hidden object itself
invalidateVirtualViewId(parentId);
}); });
} }
public void notifyObjectFocus(int viewId) public void notifyObjectFocus(int viewId)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override if (m_view == null)
public void run() { return;
if (m_view == null) m_focusedVirtualViewId = viewId;
return; m_view.invalidate();
m_focusedVirtualViewId = viewId; sendEventForVirtualViewId(viewId,
m_view.invalidate(); AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
sendEventForVirtualViewId(viewId,
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
}
}); });
} }
public void notifyValueChanged(int viewId, String value) public void notifyValueChanged(int viewId, String value)
{ {
QtNative.runAction(new Runnable() { QtNative.runAction(() -> {
@Override // Send a TYPE_ANNOUNCEMENT event with the new value
public void run() {
// Send a TYPE_ANNOUNCEMENT event with the new value
if ((viewId == INVALID_ID) || !m_manager.isEnabled()) { if ((viewId == INVALID_ID) || !m_manager.isEnabled()) {
Log.w(TAG, "notifyValueChanged() for invalid view"); Log.w(TAG, "notifyValueChanged() for invalid view");
return; return;
}
final ViewGroup group = (ViewGroup) m_view.getParent();
if (group == null) {
Log.w(TAG, "Could not announce value because ViewGroup was null.");
return;
}
final AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT);
event.setEnabled(true);
event.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME);
event.setContentDescription(value);
if (event.getText().isEmpty() && TextUtils.isEmpty(event.getContentDescription())) {
Log.w(TAG, "No value to announce for " + event.getClassName());
return;
}
event.setPackageName(m_view.getContext().getPackageName());
event.setSource(m_view, viewId);
if (!group.requestSendAccessibilityEvent(m_view, event))
Log.w(TAG, "Failed to send value change announcement for " + event.getClassName());
} }
final ViewGroup group = (ViewGroup) m_view.getParent();
if (group == null) {
Log.w(TAG, "Could not announce value because ViewGroup was null.");
return;
}
final AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT);
event.setEnabled(true);
event.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME);
event.setContentDescription(value);
if (event.getText().isEmpty() && TextUtils.isEmpty(event.getContentDescription())) {
Log.w(TAG, "No value to announce for " + event.getClassName());
return;
}
event.setPackageName(m_view.getContext().getPackageName());
event.setSource(m_view, viewId);
if (!group.requestSendAccessibilityEvent(m_view, event))
Log.w(TAG, "Failed to send value change announcement for " + event.getClassName());
}); });
} }