11

I'm working on a Leanback app and I've implemented the rows and everything via RowsFragment and its all working great.

As for now when I go left and right within the items in the row the focused item moves to the middle of the screen and gains the focus.

Example -

enter image description here

I want the focused item to stay at the beginning of the row and not at the middle.

Example -

enter image description here

Couldn't find anything on this on the web. Would really appreciate any information regarding this.

Itay Feldman
  • 846
  • 10
  • 23
  • Try to check the documentation on how to effectively [ create TV navigation](https://developer.android.com/training/tv/start/navigation). "The Android framework automatically applies a directional navigation scheme based on the relative position of focusable elements in your layouts". These are the available [navigation attributes](https://developer.android.com/training/tv/start/navigation#modify-d-pad-nav) for Android user interface widgets: `nextFocusDown`, `nextFocusLeft`, `nextFocusRight`, `nextFocusUp`. – MαπμQμαπkγVπ.0 Nov 29 '18 at 11:17
  • hey @MαπμQμαπkγVπ.0 thanks for your comment but i have no problem with the navigation of the items. I need the focused items to always come to the first item position (start of row) like shown in the second image. – Itay Feldman Nov 29 '18 at 11:48

3 Answers3

10

If you also want the last item of the row to appear at the beginning, use this ListRowPresenter:

class FocusedItemAtStartListRowPresenter(focusZoomFactor: Int) : ListRowPresenter(focusZoomFactor) {
    override fun createRowViewHolder(parent: ViewGroup): RowPresenter.ViewHolder {
        val viewHolder = super.createRowViewHolder(parent)

        with((viewHolder.view as ListRowView).gridView) {
            windowAlignment = BaseGridView.WINDOW_ALIGN_LOW_EDGE
            windowAlignmentOffsetPercent = 0f
            windowAlignmentOffset = parent.resources.getDimensionPixelSize(R.dimen.lb_browse_padding_start)
            itemAlignmentOffsetPercent = 0f
        }

        return viewHolder
    }
}

This is similar to what the Leanback Launcher does.

user3210008
  • 766
  • 6
  • 7
  • Thank you very much for your reply, It's been a while since I asked and am not in a place to check it out now but hope it works and will help future seekers :) – Itay Feldman May 13 '19 at 11:25
  • Thank you! It works :) But could you add some explanation? – Sabin Bajracharya May 14 '19 at 17:47
  • @user3210008 After finding some time to try this out it really did the job kinda perfectly! changed this to the correct answer. – Itay Feldman Dec 05 '19 at 15:44
  • 1
    @user3210008 How to do the same for the row, like when we scroll down, 2nd row move to the 1st-row position. Thanks a lot. – Akhilesh Dhar Dubey Feb 07 '22 at 15:35
  • 1
    @Akhilesh Dhar Dubey You can use RowsSupportFragment.setAlignment() to do that. – user3210008 Feb 08 '22 at 17:58
  • @user3210008 Thanks a ton. It solves my biggest problem with UI. Thanks again for your quick response. How did you learn this in-depth thing, any suggestions? – Akhilesh Dhar Dubey Feb 08 '22 at 19:39
  • 2
    @Akhilesh Dhar Dubey You're welcome :) I found out the answer to the original question by decompiling the Leanback launcher. As for the answer to your question, I don't really remember how I discovered it, but I think I just stumbled upon it when I was looking at RowsSupportFragment's available methods. – user3210008 Feb 09 '22 at 11:55
  • @user3210008 That's great, I will try to learn more about it. Thanks. – Akhilesh Dhar Dubey Feb 09 '22 at 17:56
  • Using `BaseGridView.WINDOW_ALIGN_BOTH_EDGE` instead of `BaseGridView.WINDOW_ALIGN_LOW_EDGE` may produce a better behavior, since in this case last item is is aligned with the end of viewport. – mahdi Feb 20 '22 at 10:55
  • @user3210008 setAlignment thank you for that. – Mikkel Larsen Sep 30 '22 at 07:41
1

Faced the same issue and solved it by using a custom ListRowPresenter:

override fun createRowViewHolder(parent: ViewGroup): RowPresenter.ViewHolder {
        val viewHolder = super.createRowViewHolder(parent)

        val itemWidth = parent.resources.getDimensionPixelSize(R.dimen.epg_program_width)

        with((viewHolder as ListRowPresenter.ViewHolder).gridView) {
            itemAlignmentOffset = parent.width / 2 - itemWidth / 2 - paddingLeft
        }

        return viewHolder
    }
1

To be complete as tvlauncher you need also set this:

fadingLeftEdge = true // to fade previous item out

But better is to use their FadingEdgeContainer, as fading edge is not really the same.

Something like this: https://github.com/bosphere/Android-FadingEdgeLayout

Milan Jurkulak
  • 557
  • 3
  • 6