Scroll to given position in Android Leanback ListRow
Asked Answered
B

5

18

I'm using the Google Leanback widgets in an Android TV application. It utilizes a RowsFragment with ListRows in it.

What I'm trying to determine is if there is any way to programmatically scroll to a particular object within one of the rows. I've dug into the docs for the Leanback widgets but cannot find what I'm looking for.

Burnet answered 1/5, 2015 at 21:20 Comment(0)
B
17

I had a similar necessity: I needed to set the initial selected item in a ListRow. I ended up subclassing the ListRowPresenter like this:

import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.RowPresenter;

public class CustomPresenter extends ListRowPresenter {

    private int mInitialSelectedPosition;

    public CustomPresenter(int position) {
        this.mInitialSelectedPosition = position;
    }

    @Override
    protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) {
        super.onBindRowViewHolder(holder, item);

        ViewHolder vh = (ListRowPresenter.ViewHolder) holder;
        vh.getGridView().setSelectedPosition(mInitialSelectedPosition);
    }

}

Hopefully this will help you.

Behind answered 12/6, 2015 at 14:27 Comment(2)
Thanks, I think that gives me the information I'll need to do what I wanted.Burnet
The example is really good, it is also possible to modify the logic behind the first item to select. ThanksStedt
T
11

In the latest version of Leanback (think v23.3.0+), you can now specify not only the row position but also perform optional tasks on the row. In your case, the task would be programmatic selection like so:

BrowseFragment.setSelectedPosition(0, true, new ListRowPresenter.SelectItemViewHolderTask(2));

No need to implement custom list row presenters or anything

Townsville answered 17/6, 2016 at 9:33 Comment(1)
Same line of code in my onActivityResult gives: IllegalStateException: Cannot start headers transition; any help?Madcap
G
6

I've done it when I needed to implement "Return to the first item in a Row by pressing Back".

I was calling this method from Activity's onBackPressed().

If this method returns false we call Activity.super.onBackPressed(). If true - we don't.

    public boolean onBackPressed(){
        boolean consumeBack;

        int selectedRowPosition = getRowsFragment().getSelectedPosition();

        ListRowPresenter.ViewHolder selectedRow = (ListRowPresenter.ViewHolder) getRowsFragment().getRowViewHolder(selectedRowPosition);
        int selectedItemPosition = selectedRow.getSelectedPosition();

        if(selectedItemPosition == 0){
            consumeBack = false;
        } else {
            consumeBack = true;
            getRowsFragment().setSelectedPosition(selectedRowPosition, true, new ListRowPresenter.SelectItemViewHolderTask(0));
        }
        return consumeBack;
}

Instead of "0" you can set any position you need.

Gemstone answered 26/7, 2016 at 14:42 Comment(0)
E
0

This answer is suggesting the usage of the latest androidx.leanback library.

In your BrowseSupportFragment create a class variable of type HeadersSupportFragment. After creating your ArrayObjectAdapter and using it by setAdapter(), call the getHeadersSupportFragment(). Then call getSelectedPosition() to get the current selected position and store it in Preferences. Later, use setSelectedPosition() to set the previous position.

Here is an example:


private HeadersSupportFragment hsp;  
private ArrayObjectAdapter mRowsAdapter;

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
        setAdapter(mRowsAdapter);

        hsp = getHeadersSupportFragment();

        int lastPosition = getSharedPreferences(CONTEXT).getInt(LAST_NUMBER, 0);
        hsp.setSelectedPosition(lastPosition);

}

  @Override
    public void onPause() {
        super.onPause();

        if(hsp != null){
            getSharedPreferences(CONTEXT).edit().putInt(LAST_NUMBER, hsp.getSelectedPosition()).commit();
         
        }

    }

Elderly answered 2/2, 2021 at 8:18 Comment(0)
U
0

If your headersState is enabled, use

SelectItemViewHolderTask task = new SelectItemViewHolderTask(positionX)
boolean isSmoothScroll = false // If you need to ignore the animation
task.setSmoothScroll(isSmothScroll)  
setSelectedPosition(positionY, isSmothScroll, task)

However, if your headersState is disabled, then using this code will cause an exception: IllegalStateException: Cannot start headers transition.
In this case you need to use this instead:

getRowsSupportFragment().setSelectedPosition(positionY, isSmothScroll, task)

The difference between them is whether the HeadersSupportFragment is updated or not.

Urata answered 19/8, 2021 at 3:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.