如何让电视项目在被选中时可以展开,比如首页的推荐?

How to make TV item expandable when be selected, like homepage's recommendation?

在AndroidTV的主页中,当用户选择推荐视频时,该项目会自行展开并显示比其他未选择项目更多的信息。

屏幕截图在这里:

在我的电视应用程序中,我将 VerticalGridFragment 扩展为 GridFragment 以显示电视节目。并且还扩展了 Presenter 以设置项目布局。但是选中item后,item只是变大了,并没有像主页推荐那样显示更多信息。

如何在我的 TV 应用程序的 Presenter 中获得这种效果?

也许我找到了解决方案:在 Presenter 中,我们将创建一个 ViewHolder 来显示,可能是这样的:

public class GridItemPresenter extends Presenter {
......

public GridItemPresenter(Fragment fragment) {
    this.mainFragment = fragment;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
    // Here is the view we want to show.
    final RichCardView cardView = new RichCardView(parent.getContext());

    // We should change something when the view is focused: show more information.
    cardView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, final boolean isFocused) {
            updateCardBackgroundColor(cardView, isFocused);
            cardView.setSelected(isFocused);
        }
    });
    cardView.setFocusable(true);
    cardView.setFocusableInTouchMode(true);
    ......
    return new ViewHolder(cardView);
}

private static void updateCardBackgroundColor(RichCardView view, boolean selected) {
    ......
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
    RichCardView cardView = (RichCardView) viewHolder.view;
    ......
}

@Override
public void onUnbindViewHolder(ViewHolder viewHolder) {
    RichCardView cardView = (RichCardView) viewHolder.view;
    ......
}
}

ViewHolder是一个容器,用来存放显示视图,在代码中,视图是RichCardView。以下是一些 RichCardView 代码:

public class RichCardView extends RelativeLayout {

public RichCardView(Context context) {
    this(context, null);
}

public RichCardView(Context context, AttributeSet attrs) {
    this(context, attrs, android.support.v17.leanback.R.attr.imageCardViewStyle);
}

public RichCardView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    LayoutInflater inflater = LayoutInflater.from(context);
    View v = inflater.inflate(R.layout.lb_rich_card_view, this);

   ......
}

@Override
public void setSelected(boolean selected) {
    super.setSelected(selected);
    if (selected) {
        // when be selected, set some views Visible to show more information.
        mContentView.setVisibility(View.VISIBLE);
        mEpisodeView.setVisibility(View.VISIBLE);
    } else {
        // when not be selected, hide those views.
        mContentView.setVisibility(View.GONE);
        mEpisodeView.setVisibility(View.GONE);
    }
}
}

选择视图后,我们会显示更多视图以显示更多信息。否则,我们隐藏一些视图来隐藏一些信息。

是的,RichCardView 只是扩展了 RelativeLayout。您还可以根据需要扩展任何 ViewGroup。如果你想改变生动,只需在改变视图的可见性时添加一些动画。

您可以参考ImageCardView的实现。它有一个方法 setInfoVisibilitysetExtraVisibility 来控制可扩展 CardView 的行为。当 CARD_REGION_VISIBLE_ACTIVATED 设置为参数时,当用户选择 header 时区域不会出现,当用户移动到 RowsFragment.

时区域会出现

更新(2015.10.26)

当你想扩展卡片时只有选中CARD_REGION_VISIBLE_SELECTED才可以使用。

下面是示例代码(已更新),应在 Presenter 中实现 class。

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
    Log.d(TAG, "onCreateViewHolder");
    mContext = parent.getContext();

    ImageCardView cardView = new ImageCardView(mContext);
    cardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER);
    cardView.setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_SELECTED);
    cardView.setFocusable(true);
    cardView.setFocusableInTouchMode(true);
    cardView.setBackgroundColor(mContext.getResources().getColor(R.color.fastlane_background));
    return new ViewHolder(cardView);
}

详情在this tutorial底部说明。