I'm running my app on an Android 4.4.2 (KitKat) device.
My app has a ListView.
When I add the last item to the list view, it shows some content, and about 5 seconds later, it changes (loads a different view to that specific list item).
While TalkBack is on -
If, in that 5 seconds window, I click on the last item - the TalkBack marks it, reads it, and does not let the view change.
I do not have this issue on previous Android version.
Anyone knows why this happens? and if I can override this behavior?
Thanks!
PB
I did not find a direct solution.
I have solved the issue by overriding accessibility default behavior.
I removed the mark around the view and kept only the reading part.
This is the code I used:
view.setAccessibilityDelegate(new AccessibilityDelegate() {
#Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
//call super to perform the action
boolean ret = super.performAccessibilityAction(host, action, args);
//call super with remove-focus action to remove the mark around the view
super.performAccessibilityAction(host, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, args);
return ret;
}
});
Related
I have the following code to introduce menu items into the system context menu upon text selection on a Label.
public override void OnActionModeStarted(ActionMode mode)
{
IMenu menu = mode.Menu;
menu.Add("MItem1");
menu.Add("MItem2");
menu.Add("MItem3");
menu.GetItem(0).SetOnMenuItemClickListener(new MenuItemOnMenuItemClickListener(this, 0));
menu.GetItem(1).SetOnMenuItemClickListener(new MenuItemOnMenuItemClickListener(this, 1));
menu.GetItem(2).SetOnMenuItemClickListener(new MenuItemOnMenuItemClickListener(this, 2));
//test code -> this works fine
menu.Add(0, 999, 0, "test");
//item is found, item.IsEnabled == true, item.IsVisible == true
IMenuItem item = menu.FindItem(999);
base.OnActionModeStarted(mode);
}
It works fine on a Lenovo device and was previously working on a Samsung device, but over time due to, I suspect, one or two Samsung system updates, the method no longer has any effect.
I've run the code through the debugger and the code can be stepped through line by line, but the system menu is completed unaffected by the added menuitems and continues as if my code hasn't been called at all.
Any ideas?
I have both a workaround and a solution.
Workaround
I added:
mode.Hide(1);
to the above code. It helps refresh the menu and the correct menu items appear.
Solution
I did another Samsung OS upgrade and the problem has disappeared. Seems like it was an OS problem after all.
I am writing here about an issue that was introduced when we migrated from the AppCompat library to the AndroidX library. While doing so, we switched from android.support.design.widget.NavigationView to com.google.android.material.navigation.NavigationView and that’s when the following issue started.
In our NavigationView design, in order to save space, we implemented an expandable menu, so that when users clicks on the “more” button, the menu expands to show more options. It starts off with only some options visible, and the rest are not visible, as follows;
Option 1
Option 2
More…
Upon clicking on the “More...” button, the menu expands to;
Option 1
Option 2
Option 3
Option 4
Option 5
Option 6
To do this we used following code;
#Override
public boolean onNavigationItemSelected(MenuItem item)
{
....
if (item.getItemId() == R.id.nav_more)
{
item.setVisible(false); // hide the “More” item
getMenu().findItem(R.id.nav_option_3).setVisible(true);
getMenu().findItem(R.id.nav_option_4).setVisible(true);
getMenu().findItem(R.id.nav_option_5).setVisible(true);
getMenu().findItem(R.id.nav_option_6).setVisible(true);
return true;
}
.......
return false;
}
Well, this code has worked in the past, but when we migrated to using the androidx library, poof, it stopped working. Well, it did work a bit. The “More...” button got hidden, but the previously hidden options, were not being displayed.
As, it took me many hours to solve this issue, and to save others this headache, I will explain the issue and the solution.
The first thing to do in such cases, is to look at the source code. As the code is open source, I was able to get it at github. At first glance I didn’t get smarter. I found that the NavigationView has a NavigationMenuPresenter object field (called presenter), that has a method called updateMenuView() which calls adapter.update(), which calls prepareMenuItems() and notifyDataSetChanged(). This sounded like the needed fix, so using reflection, we accessed and called the updateMenuView() method, but surprisingly, it did not help!
So, I decided to take it to the extreme, and see what happens if I call getMenu().clear(), and believe it or not, nothing happened. It seems that any changes made to Menu after the NavigationView is shown, are ignored. But a quick look through source code, I could not see any reason for that.
So how do I solve this issue? I tried using the latest alpha version of the library, but I still have the same issue.
Well, after much work, I found the solution. It's actually simple. Just hold on for the answer.
Lionscribe
So I was back to the source code, searching for some clue, when I fell upon a method called setUpdateSuspended(boolean updateSuspended). Well, that sounded suspicious! I searched for usage of this method, and found it being called in the onClick callback. Here is a minimized version of the code;
#Override
public void onClick(View view) {
NavigationMenuItemView itemView = (NavigationMenuItemView) view;
setUpdateSuspended(true);
MenuItemImpl item = itemView.getItemData();
boolean result = menu.performItemAction(item, NavigationMenuPresenter.this, 0);
setUpdateSuspended(false);
}
Bingo! It seems that while handling clicks, the NavigationView suspends and will not recognize any changes done to menu. I am not sure the reason for this, but as we were updating the menu in the onNavigationItemSelected callback, which is called by the onClick method, the menu updates are ignored.
Well, once I understood the issue, the solution was simple and clean. I just wrapped the code in a Runnable, and posted it, so that it runs after the onClick method returns, and setUpdateSuspended is set back to false. Here is the updated code;
#Override
public boolean onNavigationItemSelected(MenuItem item)
{
....
if (item.getItemId() == R.id.nav_more)
{
final MenuItem itemFinal = item;
post(new Runnable()
{
#Override
public void run()
{
getMenu().findItem(R.id.nav_option_3).setVisible(true);
getMenu().findItem(R.id.nav_option_4).setVisible(true);
getMenu().findItem(R.id.nav_option_5).setVisible(true);
getMenu().findItem(R.id.nav_option_6).setVisible(true);
itemFinal.setVisible(false); // hide the “More” item
}
});
return true;
}
.......
return false;
}
Viola! The expandable menu now works like it used to, the hidden items are now being shown!
I hope this will be of help to others with same issue.
Lionscribe
I am trying to implement some hints when a user is hovering a button or another view, I see that android have support for onHoverListener but I don't understand how it really works. However I did try to find a solution how to make a floating editText on a button hover but I didn't find any ideas.
I am thinking that hover in android is the same think with long click because you can't hover with finger without clicking the view.
OnHoverListener is only implemented in 2 specific situations: a) when a Bluetooth or USB mouse is plugged into the device, or b) on Galaxy Note devices, when the S-Pen (stylus) is hovering over the object.
In specific setups/situations this can be a very neat feature, but unfortunately, most users will never even know it exists. For your situation, you may want to implement an OnLongClickListener for showing hints/tips as that is pretty standard in Android.
This example will show a TextView or ImageView hint for 5 seconds when a long-click is initiated:
btn.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
findViewById(R.id.hint).setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
findViewById(R.id.hint).setVisibility(View.GONE);
}
}, 5000);
return true;
}
});
Hope this helps,
I want to add up on Aaron's answer.
Some devices with sensitive screens - Samsung S5 comes to mind - don't even need an s-pen.
Just need to hold your finger 1/2 inch over the screen and it would trigger it.
I'm having an issue with the ActionBar in my app; In certain scenarios the ActionBar appears to go "under" the notifications/title bar. It's reproducible each time and i can't figure out why it's happening. I use the ZXING application with Intents to scan barcodes and return them to my app, and it's at some point during this process the issue occurs.
I thought it'd be best to show you the issue with pictures.
1: The app home screen, all is normal.
2: Use the menu item to scan a barcode. This appears as expected.
3: The product page for the scanned item appears normal. If i click 'Cancel' however...
4: The ActionBar has now gone under the notifications/title bar.
The only other mention of a bug such of this (that i can find) is in this GitHub issue for ActionBarSherlock (which i'm using): https://github.com/JakeWharton/ActionBarSherlock/issues/602
I have checked and i'm not doing anything weird with configChanges as Jake mentions.
This issue is seen on my 4.2.2 device, i'm unable to test on a pre-ICS device unfortunately.
Any thoughts or suggestions are welcome!
I'm guessing it not getting reset back when you come back from the zxing screen. In your Activity for "Best Before", try reseting the window flags for fullscreen something like:
#Override
protected void onResume() {
super.onResume();
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setSystemUiVisibility(this, View.SYSTEM_UI_FLAG_VISIBLE /* SYSTEM_UI_FLAG_VISIBLE=0 */);
}
private static void setSystemUiVisibility(final Activity activity, final int newValue){
if (activity.getWindow() != null){
View v = activity.getWindow().getDecorView();
if (v != null) {
try {
Method methodSetSystemUIVisibility = v.getClass().getMethod("setSystemUiVisibility", int.class);
methodSetSystemUIVisibility.invoke(v, newValue);
} catch (Exception noop) {
}
}
}
}
I'm currently fighting against the OnLongClickListener on Android Api Lvl 8.
Take this code:
this.webView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
System.out.println("long click");
return true;
}
});
It works perfectly. I can press anywhere on the WebView and the event triggers every time.
Now take a look at this one:
this.webView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final EditText editText = getUrlTextField();
switch (editText.getVisibility()) {
case View.VISIBLE:
editText.setVisibility(View.GONE);
return true;
case View.GONE:
editText.setVisibility(View.VISIBLE);
return true;
default:
return false;
}
}
});
Assuming the URL EditText components is currently visible, it gets gone from the display and should be shown again when another long click event is triggered.
But if you run this, the event just works once (!) when one performs a long click on any position on the WebView. To make things complicated, the long click works again when it is performed on a link on the website...
Can anyone explain if it is a bug in the sdk and/or if there is a mistake in my thinking how the OnLongClickListener is working?!? :/
EDIT:
I've run now several different scenarios on a Nexus One and come to following conclussion: Changing the layout on runtime more or less kills the OnLongClickListener... I haven't found a way to get it work reliably at all...
I would really appreciate if anyone could give me a hint... I'm at my wits end :(
Personnally, I ended up by re-setting the listener after each relayout.
I've run into this issue as well. It seems that if the view layout changes in a way that child view bounds need to be modified (i.e. TextView is wrap_content width and you set its text to something longer/shorter than it was before), views in the hierarchy will have their onStartTemporaryDetach method called (most likely due to a layout pass, although I haven't dug deep enough to find out for sure). If you look at the source for View that onStartTemporaryDetach ultimately unsets the pressed state of the view.
Changing the views in your layout that will be updated periodically to have bounds that will not change regardless of the value you set, will fix the issue. Although, that is still not awesome.