简体   繁体   中英

How to make a button focusable in an item in RecyclerView

On Android TV, I have a problem trying to get focus of a button that is on a row of a RecyclerView . I already set the button to focusable but still does not get the focus. I added a focus handler on the view of the row but I am not if this is what's causing the problem:

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type)
{
    final FriendsListViewItem.ItemType itemType = FriendsListViewItem.ItemType.FromInt(type);

    LinearLayout cellLayout = new LinearLayout(m_context);
    cellLayout.setOrientation(LinearLayout.VERTICAL);
    RecyclerView.LayoutParams cellParams = new  RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,   RecyclerView.LayoutParams.WRAP_CONTENT);
    cellLayout.setLayoutParams(cellParams);

    // create cell data view
    View cellData = new CellView(m_context);
    LinearLayout.LayoutParams params = new      LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,       LinearLayout.LayoutParams.WRAP_CONTENT);
    cellData.setLayoutParams(params);
    cellData.setFocusable(true);
    cellLayout.addView(cellData);
    cellLayout.setOnFocusChangeaListener(new OnFocusChangeaListener)
    {  
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
        if(hasFocus)
        {
            v.setBackgroundColor(ContextCompat.getColor(m_context, R.color.friend_cell_highlight_color));
        }
        else
        {
            v.setBackgroundColor(Color.TRANSPARENT);
        }
    }
    return new ViewHolder(cellLayout);
}

CellView is the class that contains the button.

It looks like you might be building your lists from scratch, but I'd highly recommend using the Leanback library from the Android team (at very least for lists). They provide a nice example which includes video playback, navigation, and lists in their sample app .

For your issue specifically, this is solved via their RowsFragment . The RowsFragment is responsible for drawing items in a row and broadcasting out "selection" (or focus) events and "click" events. You can see an exact example here .

Instead of calling setOnItemClickedListener(...) on the RowsFragment , you'd use setOnItemSelectedListener(...) like below:

        setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
            @Override
            public void onItemSelected(ViewHolder itemViewHolder, Object item,
                                       RowPresenter.ViewHolder rowViewHolder, Row row) {
                // Do what you want to the itemViewHolder or item
            }
        });

Another approach would be to subclass BaseCardView then you could override the setSelected() method to update it however you'd like - this should most likely take place in your Presenter . A Presenter in Leanback basically replaces Adapters you'd use for a RecyclerView. The presenter is responsible for binding your data model to your list item.

@Override
final protected BaseCardView onCreateView(Context context) {
    final BaseCardView cardView = new BaseCardView(context, null, R.style.YourCardStyle) {
        @Override
        public void setSelected(boolean selected) {
            updateCardBackgroundColor(this, selected);
            super.setSelected(selected);
        }
    };

    cardView.addView(LayoutInflater.from(context).inflate(R.layout.your_card_layout, null));
    initCardView(cardView);
    return cardView;
}

I highly recommend opening up their example app in Android Studio and get it running. Then poke around a little bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM