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.
Related
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.
I need a component that works like the picture below but I'm having trouble coming up with some kind of decent solution that works.
I want the list to have a center locked selection but being scrollable with the d-pad. This is for an application running on a TV so no need for touch scroll. So when pressing down on the remote d-pad the list will scroll and a new item will size up and the current selected one will size down and the new selection will still be in the middle.
I've tried doing this using a ListView that I extended and programmatically scrolling when pressing down or up. On scroll finished I called notifyDatasetChanged() on the ListView for re-inflating of the childs and in the ListViews adapters getView() I made the animation of the view located at the current selected position.
This is not optimal since I need to call notifyDatasetChanged(), which re-inflates all visible views, for the animation to apply. The UI becomes laggy when doing this and scrolling fast. It's also not possible to make som kind of compress animation when current selected item goes out of selection. There is also some trouble with the end items (read views) such the first or last in the list when doing animation of them, the may sometimes go out of screen.
I think that his must have been done before and maybe I'm missing it when searching for an answer.
Have anyone done something similar or do you have some suggestions of how this can be achieved? Maybe I'm just starting of with the wrong component here..
Regards,
Kristoffer
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.
I have a problem updating android listview items cell.
The listview_item.xml is an ordinary listview item except that it has a hidden panel at the bottom. So the last part of listview_item.xml is LinearLayout that has another button inside it. This whole layout is set to gone until user clicks on a visible button in the list item. This sets the hidden LinearLayout to visible and it displays. So far so good. Now the hidden LinearLayout is open, and showing and I want to close it. So I click on a button that is inside this previously hidden linear layout and set the visibility to GONE which was its previous state. The result is nothing happens right away. The panel remains open until I scroll it out of site and back again. Then it does not show again. I'm sorry I don't have the code to post but thats the whole situation. I just cannot get a list item to refresh on the spot. Opening using a visible button works fine. But closing the same panel from a button within the panel seems to do nothing. I have tried running dataSetChanged() etc from inside the adapter but only scrolling out and into view will close the panel. Does anyone know why closing is different from opening? Why I get an immediate reaction to setting gone to visible but not the other way. The only difference it seems is that I am firing the event from a button on the previously hidden panel. Sorry its wordy, but don't have the code in front of me at the moment.
I think nobody here can help you without a code. notifyDataSetChaged() is the method that must help you, but if it is not - it obvious that you do something wrong. You must save visibility state of element of each list item in associated with this list item object (or model whatever). Check your code one more time and debug it.
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.