在Android Leanback ListRow中滚动到指定位置

18
我正在使用Google的Leanback小部件在Android TV应用程序中。它利用了一个包含ListRows的RowsFragment。
我尝试确定是否有任何方法可以编程方式滚动到一行中特定对象的位置。我已经查阅了Leanback小部件的文档,但没有找到我要找的内容。
5个回答

17

我有类似的需求:我需要设置ListRow中最初选定的项目。最终,我通过以下方式对ListRowPresenter进行了子类化:

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);
    }

}

希望这可以帮助你。


1
谢谢,我认为这给了我所需的信息来完成我想做的事情。 - ebr
1
这个例子非常好,也可以修改选择第一个项目背后的逻辑。谢谢。 - Massimo

11
在最新版本的Leanback(即v23.3.0+)中,您现在不仅可以指定行位置,还可以在行上执行可选任务。在您的情况下,任务将是程序化选择,如下所示:
BrowseFragment.setSelectedPosition(0, true, new ListRowPresenter.SelectItemViewHolderTask(2));
无需实现自定义列表行呈现器或任何其他内容。

3
在我的onActivityResult中相同的代码行会出现:IllegalStateException: Cannot start headers transition; 有什么帮助吗?请问需要怎样处理? - uniruddh

6

当我需要实现“按下返回键返回到行中的第一个项目”时,我已经完成了这个任务。

我是从Activity的onBackPressed()方法中调用这个方法的。

如果这个方法返回false,我们就会调用Activity.super.onBackPressed()。 如果返回true,我们就不会调用。

    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;
}

你可以将"0"替换为任何需要的位置。


0

这个答案建议使用最新的androidx.leanback库。

在你的BrowseSupportFragment中创建一个HeadersSupportFragment类型的类变量。在创建了你的ArrayObjectAdapter并通过setAdapter()使用它后,调用getHeadersSupportFragment()。然后调用getSelectedPosition()来获取当前选定的位置并将其存储在Preferences中。稍后,使用setSelectedPosition()来设置先前的位置。

以下是一个例子:


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();
         
        }

    }


0
如果您的headersState已启用,请使用。
SelectItemViewHolderTask task = new SelectItemViewHolderTask(positionX)
boolean isSmoothScroll = false // If you need to ignore the animation
task.setSmoothScroll(isSmothScroll)  
setSelectedPosition(positionY, isSmothScroll, task)

然而,如果你的headersState已经被禁用了,那么使用这段代码会导致异常:IllegalStateException: Cannot start headers transition
在这种情况下,你需要使用以下代码替代:

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

它们之间的区别在于是否更新HeadersSupportFragment

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接