Leanback.DetailsFragment not scrolling as expected - android

I have a details fragment that is using a DetailsOverviewRow and FullWidthDetailsOverviewRowPresenter. When the page first loads the action buttons are selected. When I press down once, focus leaves the buttons and nothing else happens. When I press down a second time focus moves to a ListRow that is further down the page. I'm trying to figure out why the overview, or body as it's called in the presenter, section doesn't focus.
Should there not be a second 'state' between the two screenshots where the overview/body is readable?
Possibly of note. The DetailsFragment isn't declared in an activities xml, I'm changing fragments manually using FragmentTransactions. Also, the Fragment is instantiated using a static create method (source below).
Thanks in advance.
Activity xml
DetailsFragment java

I haven't tried this example in particular, but from my time spent with Leanback support library, I learned that even though a lot of helpful stuff is indeed provided, a lot is not :D
So I would try these things:
1) Make sure that something in the area you want visible is focusable. (Clickable elements should be focusable by default, but better check too) What I mean is that on the screenshot, there is just text, no buttons or editable content in that area. So when you press down, there is nothing to focus. What happens if you make the body TextView focusable?
(Yes, one would expect that the support library would take care of that, but that might not be the case.)
2) Find out what actually gets focused when you press down, since as you said, the focus leaves the buttons - but where does it go? (How to find out which view is focused?) You might have a "direction problem" somewhere. That is - the focus travels based on the view hierarchy tree, not based on what we see on the screen. In some cases, it is possible to skip some elements or get stuck somewhere by moving focus through an unexpected part of the view tree, that makes sense for the algorithm, but isn't logical from the human perspective.

The details presenter focus works this way :
1) First focus is given to Action buttons. Right/left nav press shifts the focus right/left between action buttons.
2) Down nav press from actions row shifts the focus from actions row to details row (individual details items itself are not focusable), this is achieved by shifting the Thumbnail anchoring position to further south.
3) Down nav press from details row shifts the focus from details row to related row.
So the details row gains focus by changing the anchoring position of Thumbnail image. Is your thumbnail image changing its anchoring position when pressing down from actions row?

Hate to answer my own question. This was due to my failure to RTFM. I was creating the fragment UI after a network request completes. For the FullWidthDetailsPresenter to work properly it and the ClassPresenterSelector() should be initialized in the fragments onCreate() method.

Related

Android Accessibility setting (Talkback) focus

I have a horizontal recycler view (having most recent item at the right most position and the oldest item at the left most position) below a textview. Once the accessibility control reaches textview, on making right swipe it focuses on the left most item of the recycler view (i.e. 1st item). Is there a way we can set the default focus to the rightmost item.
My answer would be.... don't do this.
Focus order should follow reading order. In left to right languages, independent of how your data is organized, this means left to right.
Picture this: Someone is swiping right through your application, and happily going... next, next, next, next... etc. Then suddenly they swipe onto your control and SKIP over a bunch of content. A blind person is going to assume that "Swiping Right" is moving to the next thing. Now, they have just swiped right onto the right most element of your Recycler View. Are they going to know that they skipped over a bunch of content??? NO. From a blind person's point of view this content is lost, unless somehow they know to swipe right and then swipe left to go backwards... NOT LIKELY.
UNLESS....
Are you going to have "right swipe" move left and manage focus over every element of your container. PLEASE, PLEASE don't do this, getting it correct for all relevant technologies (TalkBack, SpeakBack, Switch Control, BrailleBack, etc) is more difficult than you'd think.
Let's say that you don't go through the pain of managing focus on ALL elements of your Recycler container. From a blind person's point of view, your app looks very different swiping right all the way through it, vs swiping left all the way through it.
To summarize... don't do this!
Notably this is also a duplicate question, as there are many TalkBack focus management questions out there.

Alternative to ListView that avoids EditText focus issues?

Situation
Need to present text files as a list of editable sentences or phrases as shown in the example below, for the purpose of a speech therapy tool. This was relatively easy.
The colored flags can be added, removed, or dragged to new positions as needed, and can be set to snap-to-character or snap-to-word (they will also eventually display data).
This was achieved by sub-classing EditText, to take advantage of all the in-built features like word-wrapping, spell-checking, text-selection etc.
Problem
The number of phrases or sentences in a document can be large, so using a simple LinearLayout in a ScrollView to display them is no good in this case.
To efficiently display my FlaggedEditText widgets the solution needs to take advantage of view recycling, so ListView is an obvious consideration. But as shown by the number of S.O. questions out there, ListView and EditText don't play nice together.
The requirements of the list are that:
FlaggedEditText widgets get focused when touched (the item containing the FlaggedEditText also gets selected).
Notification when an item in the list has been edited (including which item).
Standard gestures such as fling.
I've tried out numerous approaches suggested in the many S.O. questions over the past few days, to try and bend ListView to my requirements, but all seem to have their own short comings and result in hacky, messy code.
Questions
Does anyone know of any existing alternatives to the standard Android ListView out there, that are more EditText friendly?
Alternatively, does anyone have a clean, efficient, definitive approach to getting EditText working as desired in the standard ListView?
Finally, I'm considering sub-classing AdapterView to make my own FlaggedEditText specific ListView alternative. But if the issues stem from AdapterView of which ListView is also an indirect subclass, then I'd be wasting my time. Has anyone already been down this path?
Edit
Jim's excellent response below, and a recent viewing of Romain Guy and Adam Powell's old Google I/O 2010 presentation The world of ListView have suggested a possible solution.
In the I/O talk I was reminded that they convert views to bitmaps for some of their optimizations. Since only one EditText at a time can ever be focused for editing, I'm thinking I can sub-class ListView to provide an interface which, if ChoiceMode is single, will give the Rect of the selected Item and bitmaps of the ListView regions above and below the selected item. This could then be used to temporarily overlay the ListView with a vertical LinearLayout containing the "above" bitmap, an active FlaggedEditText and the "below" bitmap.
In this way, the FlaggedEditText widgets can effectively act as non-focusable EditText's in the ListView, but when an Item is selected, interaction is with the temporary overlay.
The "above" and "below" bitmaps could also easily be tinted to suggest inactivity.
Additional
In fact, I've just realized I probably don't even need the Rect of the selected Item from the interface. The "above" and "below" bitmaps and a FlaggedEditText using the same LayoutParams as per the ListView should be enough.
Many of the answers out there do not seem to describe the core issues surrounding this "problem" and why it is not "solved." The "problem" you face is that an EditText can expand and/or scroll, along with your ListView. Also, the expanding soft keyboard forces the ListView to redraw causing problems with keeping track of the focused item. And when an item is focused and has dynamic content, UX confusion can occur with touch gestures (e.g. if you touch an item in an EditText like the cursor and then swipe, did you want the cursor to move? Or the entire list?) It can lead to a lot of user frustration.
I'm sure you've seen this post:
Issues focusing EditTexts in a ListView (Android)
This creates problems in correctly displaying the elements within the ListView, problems with recycling properly (the redraw) and problems with gaining focus correctly. It is possible that creating a custom class that extends AdapterView will work, but it will probably still feel like a hack, and probably will not work as you want it to or it will be a large effort.
You will need to do a lot of backend measuring of the fonts, images and "visible" (or partially visible) items in the custom object that also account for the keyboard animation and dual scrolling (the ListView can scroll and so can the EditText - or the EditText will change in size, forcing the parent custom AdapterView to determine if it should also scroll and whether views have become visible or invisible as a result of adding or removing text/images from the focused object).
If you make assumptions like "the EditText will never be larger than X height" then you may get it to work, but obviously that is a very customized solution, which is why it is not easily implemented and isn't supported generically.
Also, you will need to make UX decisions about how to handle a focused item that has scrolled off the screen (you can track it easily, but if it scrolls back onto the screen, but it can interrupt user expectations about how swipe and touch gestures are handled - for example, does the cursor in the EditText move or does the entire list? if an image is touched, does a swipe move the image or does it scroll the list? You can assume it is not focused, but then a "redraw" event can make it lose focus unexpectedly, like the current ListView implementation.) In other words, you are likely to end up with many unanticipated odd UX issues...
Your best solution will probably be to use a dialog pop-up as mentioned in the post I referenced above. Or, when an item is tapped to be edited, you could have a layout appear above or below the ListView. You may possibly get the ListView to scroll and lock to it - to have it appear as if it were in the ListView - but again, that would be hard with the soft keyboard changing the usable portion of the screen - you can expect "drag" or a slow feel to the "snap" effect. And you will need a "done" button...
To get your custom EditText to work with this suggestion, in the ListView you could disable it and make it non-focusable, then place an empty layout over the entire EditText that captures and processes the touch/fling/swipe events. This "invisible" layout may be the only option you really have.
In other words, you should probably plan to change your UI/UX rather than try to force Android to figure out how to handle several dynamic, and possibly conflicting or unpredictable, aspects of the UX interaction of these layouts.

Change default navigation of gridview - android

I'm having some problems to navigate on a gridView using the keyboard (with up, down, left and right keys).
I'm new in Android and maybe this question has a simple answer. I looked for a solution and anything could help me.
The problem is that I would like to change the way of navigation among items of a grid view. I would like to do it due to two reasons.
The first reason is related to the fact that some itens have clickable subitens (and consequently the entire item is not clickable). When the focus is changed from a item i to the item i+1, for example, the item i+1 must be checked if has subitens. If yes, the focus is changed to one of the subitens depending on direction (ie. if left to right, the first subitem on the left is focused).
The second reason is that in my application, the up arrow should works in the same way as the left arrow and the down arrow in the same way of the right arrow. So, I just need see if the keyCode of a onKey event is UP or DOWN and convert it to LEFT and RIGHT, respectively.
I thought that would be a simple task: override the onKeyDown method and treat these specificities, but I observed that my implementation of onKeyDown was invoked just in two cases: (1) when other keys are pressed (with exception of the aforementioned arrows and (2) when the grid view lost the focus. For example, if the item C1 is the current item selected and the user click to the left or down, the onKey is not invoked. Otherwise, if the right or up are typed, my method is invoked.
Is there any way to cancel this internal mechanism of grid view? I tried different ways, as follows:
(1) Implementation of OnKeyListener directly on the gridview and on the item (on the adapter) as well.
(2) Implementation of different callbacks to see which one would be called before this internal mechanism (like OnFocusChangeListener, OnKeyListener, OnItemSelectedListener). I tried both for the grid view and each item on the adapter.
(3) Instantiation of the gridview with the selector setted to a transparent image. When the desired item is reached on my keyEvent, I added a visible selector. It worked on the first event but when the visible selector is setted it does not back to the invisible selector.
I tried to be clear and I hope to anyone of you could help =)
Thank you so much
How are you?
You could try use onKeyUp instead of onKeyDown, see the answer below:
https://stackoverflow.com/a/20171618/1408986
And Android documentation:
http://developer.android.com/training/keyboard-input/commands.html
Hope this help.. bye!
I solved this problem by implementing both listeners: onKey and OnItemSelected. The focus was everytime running of the grid used and jusing those listeners solved my problem. Thanks a lot.

Android Animation reset on BasicAdapter sort

This has been bugging me for a few days now. I have a FrameLayout and one of the elements within the layout moves to reveal a menu. I can paste the code if requested, it's a bit long since it's my play code and I haven't used any styles. I digress...
When the user presses a particular button it calls a startAnimation on a custom LinearLayout which is layered on top of another stock LinearLayout. Pushing the button again will put the custom LinearLayout back to it's original location, thus hiding the menu.
I had to create a custom LinearLayout to override onAnimationEnd so the layout would stop and stay at the final animated position (I found this based on some other questions asked here on StackOverflow).
The problem arises when the user actually presses one of the visible menu items. One of the items, for example, sorts or reverse sorts the displayed list. It appears that right after I call notifyDataSetChanged on my BasicAdapter the screen redraws itself and my menu is hidden. I have no code that closes the menu, it's almost like the entire Activity is re-created or reset when the list is told to redraw.
I should also point out that I'm extending an Activity not a ListActivity. I'm targeting API 10 (Gingerbread, 2.3) and up.
If any one has any pointers, I would greatly appreciate it. I've been wracking my brain on this for days now and it's driving me crazy. Please let me know if I can provide any more info.
EDIT:
Here's the SO post about overriding the onAnimationEnd method.
Android TranslateAnimation resets after animation
Do you record which item's menu has been opened yourself? If not, then it means that you let the UI system do the remembering for you, which would mean that this information would be lost or rendered useless (since you have changed the item ordering), so all the items reverts to their initial states.
The solution is to associate the menu opened/closed state with each data in the list, then when the adapter's getView method is called, you can rebuild the correct UI state.

One touch event puts all child views into pressed state

Doubtless this is caused by my decidedly unorthodox layout - I have buttons in a LinearLayout in an Activity which is placed by an ActivityGroup into a Gallery. The ActivityGroup is also the adapter implementation and the over-all effect is full-screen sliding, snapping panels.
This is working (a treat, actually) except that a touch event on the parent layout puts all the buttons into the pressed state (and any release removes the state). A touch on an individual button is only delivered to that button.
The buttons are not receiving any events, they're only changing state.
Have I done something obviously wrong? Is this a known bug and is there a work-around?
Any insights would be very much appreciated.
As obscure as this problem is its solution may be of use to someone else, so I'll answer my own question.
As mentioned, I'm (mis)using the Gallery to provide a slidey-panel à la iPhone. I do this by returning the top level window of an Activity when the Gallery asks its Adapter implementation for a view.
Typical use of a Gallery would result in small Views to which it's desirable for the press event to be applied - it's more like a button then it is a panel. Our use means that there are many buttons in a single view and we don't want the press event to ever be applied globally.
So the work-around was very easy. I extended Gallery and deliberately broke pointToPosition(int x, int y), returning INVALID_POSITION every time. The Gallery still does everything else expected of it but skips trying to apply the touch down event to any elements but itself (to prepare itself to scroll or fling).
I hope this is of value to someone.

Categories

Resources