AndroidTv Leanback Correct way of updating rows and headers - android

In light of this article on medium Which works perfectly fine when using PageRows in a BrowseSupportFragment. Things get ugly when ListRow is used instead of PageRows and the whole list and headers start to blink on every data update/set and the focus position is lost.
I've done some debugging and it looks like the payload generated by the DiffUtil in the BrowseSupportFragment is picked up by the HeaderPresenter and not the ListRowPresenter. Now the question is if this is a bug or normal behavior. And if the latter, what's the correct way of updating data inside a BrowseSupportFragment without blinks and focus losses?
The code to reproduce this issue can be found here
What I've found is that in this function at the beginning the ListRow type gets associated with androidx.leanback.widget.RowHeaderPresenter and this is maybe the cause the payload gets picked up by this Presenter.
Another clue could be the payload is picked up by the ItemBridgeAdapter in the onBindViewHolder but only for the HeaderRowPresenter and for the following ListRowPresenter binding the payload is just empty.

Related

In Android TV leanback UI BrowseFragment how could I find when HeadersFragment is put away?

I'm writing a POC Android TV app for my company based on our existing mobile OTT product and backend.
I'm modifying the PageAndListRowFragment example from Google's Leanback Showcase code.
When a header option is selected (with OK or right arrow) I want the RowsFragment side to popup an AlertDialog to let me filter the content displayed ('all', 'latest', etc).
My problem is that I have the AlertDialog in the RowsFragment onCreate So, It displays as soon as the HeadersFragment is highlighted. This stops the user from scrolling down the header smoothly and is confusing because you still have to select the header item after the dialog.
Most advice on the web seems to point to overriding the OnItemViewClickedListener function on the HeadersFragment but I can't find a way to do this. (The leanback showcase uses the deprecated BrowseFragement code, Not BrowseSupportFragment and if I try to change up I get into FragmentFactory errors I'm not experienced enough to resolve).
I've also tried implementing isShowingHeaders() in the RowsFragment.
I've tried to find a stage of the fragment lifecycle in either HeadersFragment or RowsFragment that will let me popup the dialog when the RowsFragment is full screen without success.
I'm already using the PageRowFragmentFactory code in the leanback showcase code to send an EventBus message containing the header option chosen and was hoping to send a similar message to trigger the dialog.
I've tried setting up a setOnHeaderViewSelectedListener on the BrowseFragment but can't seem to successfully get it invoked.
I'm new to Android programming so apologies for my ignorance, but I'm determined to make this work somehow.
Any suggestions on the approach would be very much appreciated, thanks.

What's the proper way to return a result from an activity to a specific view?

New to Android. Trying to understand the technical downside of a design.
I have an ItemSelectorView which has both an availableItems collection as well as a selectedItem property. The latter is displayed at runtime along with a chevron letting the user know they can change it.
Functionality-wise, it's similar to a spinner except rather than showing a pop-up with the choices, it launches a second activity called ItemSelectorActivity which shows all of the available items from the ItemSelectorView which launched it, as well as helpful information about what each option means as well as the ability to search and filter.
When a user selects one, their choice is then returned back to the originating ItemSelectorView via a trip through MainActivity's onActivityResult override. The override then figures out which ItemSelectorView it's responding to and forwards it along.
However, I really didn't like the way MainActivity had to insert itself into the process just to get the result from ItemSelectorActivity. Plus, if ItemSelectorView was used in a fragment, things become more complex trying to forward the information to the correct view.
Because of this, I instead changed ItemSelectorView to ItemSelectorFragment which can override its own onActivityResult making it, not its owning activity, responsible for updating itself with the selected result. This means it's essentially completely self-contained now.
While this seems to work wonderfully--with this change a user only needs to place the ItemSelectorFragment somewhere in their layout and set the available and selected items--a veteran Android developer here said using a fragment like that was wrong and I should have stayed with a view because of the overhead of fragments.
But going back to a view means I'm back to having to get MainActivity involved again, making this much more complex to actually use.
So what is the technical down-side for using fragments like this? I thought that was the entire point of why they exist. And if I am supposed to use a view, is there an easier way to get a result from ItemSelectorActivity?
If I understand you correctly, your view is starting an activity (ItemSelectorView starts ItemSelectorActivity). But views should be dump in Android. They should display, nothing more.
So a view should never start an activity. A view can contain a list of items maybe, but these items should be views and nothing else. Usually we use an Adapter for that: a middle man between the items to be displayed and the views that are created to represent them on the screen.
You could look into MVP to do this in a proper way. Or maybe MVVM and android architecture, if you like that better.
To answer your question, using a fragment for your use case is a better approach then a view and there is not that much overhead at all.

MvxListView in Android with MvvmCross

I'm using MvvmCross v3 and I have a little problem with list in Android.
I actually have a Mvx.MvxListView who works well, but I'm working on tablet, and ListView is a little bit inapropriate. So I want to have a control like WrapPannel in XAML to have more than one item in a row.
How can I have this kind of control?
Thanks
There are two challenges here:
1. Find or make the control you want
The first is really up to you and your UX/design team to do - although people might be able to suggest apps and projects which might help. When choosing a control always be careful to understand it's memory use - especially:
whether it virtualises the UI reusing cells (like a list does)
or whether it creates a cell for every item even if the item is not visible (like a SL WrapPanel does?)
2. Add data-binding to it
This second step is generally quite simple to do - take a look at one of the Mvx layout controls and see how it is converted for databinding - e.g. https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Binding.Droid/Views/MvxLinearLayout.cs
You can generally just cut-and-paste this code over to your new type.
For more on subclassing existing types, also see N=18 in the video series - http://slodge.blogspot.co.uk/2013/05/n18-android-custom-controls-n1-days-of.html - this shows subclassing of a TextView
For a wrappanel, I did previously adapt and use one of #CheeseBaron's ports - FlowLayout - see http://slodge.blogspot.co.uk/2013/01/an-mono-for-android-wrappanelflowlayout.html. However, this has not been updated for v3 - if you do update it, it'd be great if you shared the results back.

Android overlapping text on adapter

On some phones, mainly a Galaxy S2 I am having an issue where the results in a custom adapter overlap on each other. This is an example where user searched for the word "vaginal" in a search field, it is a medical app.
I am not sure the best way to describe this and the code is pretty convoluted at this point. The user types in a word, and database results come in showing matches. These results are in a List object and displayed via adapter.
On most phones this works as expected, with results being sequential. On at least one device, the above screenshot happens.
Is this is a known error and how can I fix it?
This looks rather like How often can you update a textview without mess , possibly caused by View reuse in the list adapter. The solution to that issue is to force the background to a fully opaque colour.

How to implement Android 4.0 like swipe to dismiss functionality in ListView?

I'm working on an app in which I would like to implement swipe-to-dismiss functionality in the ListView - similar to what we see in Android 4.0's notification bar, recent apps list or browser tabs. I want to run the app on the devices running Android 2.2+. See the following image. I also want to change the transparency of the item being swiped-away - just like in ICS.
I checked the source of the ICS web browser on http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.1_r1/com/android/browser/TabScrollView.java?av=f but couldn't figure out which class is particularly responsible for implementing this functionality.
Can anyone point me in the right direction here? Can we do this using Android Compatibility Library? Please let me know. Many thanks.
I've thought about implementing such a feature as well, but I haven't done it yet. So the only thing I can provide are some ideas on how I would approach that problem. If I've eventually written some code I will post it here.
The main class needed is a custom Adapter which extends a ListAdapter (ArrayAdapter, SimpleCursorAdapter etc.).
The adapter applies a View.OnTouchListener to all of its Views.
Whenever that listener detects a horizontal scroll dx, it calls concernedView.offsetLeftAndRight(dx) (which will make the view draggable). Of course the adapter has to save the current horizontal offset for the view. If the user was dragging a view and removes his/her finger from the screen, the touchListener will detect this as well and start a slide back animation. Using the current offset we can also calculate an alpha value, so the view will fade out when it approaches the screen borders.
If one list entry is eventually dismissed by the user, it becomes a bit tricky, and I'm still not sure how I would implement the following action: The list content has to be updated (or the adapter has to ignore the dismissed entries) and the views that were below the one that was dismissed must hover upwards in order to fill the gap. I think it might work to let the ListView load the new content, but that would fill the gap instantly. In order to avoid that, I would then start an animation that lets all the concerned views hover from their old position (where we still had the gap) back to their current position (where the gap is filled).
These are just some of my thoughts on the issue that might help some people getting started on working on the problem. Like I said, I'm probably going to implement that sometime in the future and of course I will post the code here.
I would appreciate any feedback in the comments, but I don't want to thorougly explain every single aspect of my idea, that would take me too much time ;)
I know this is quite an old question, but for anyone still searching for this, you can have a look at Roman Nurik's library here: https://github.com/romannurik/Android-SwipeToDismiss
This shows how to create the required behavior for list-view as well as for normal views.

Categories

Resources