Android|Android TV 开发(4)

本文来自网易云社区
作者:孙有军


最后我们再来看看好友界面,改界面本地是没有xml的,因此我们直接来看看代码:

这里将使用到数据bean,与数据源的代码也贴出来如下:

public class Contact implements Parcelable {private String phone; private int headResId; private String name; public String getPhone() { return phone; }public void setPhone(String phone) { this.phone = phone; }public int getHeadResId() { return headResId; }public void setHeadResId(int headResId) { this.headResId = headResId; }public String getName() { return name; }public void setName(String name) { this.name = name; }public Contact() {}public Contact(Parcel in) { phone = in.readString(); headResId = in.readInt(); name = in.readString(); }public int describeContents() { return 0; }@Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(phone); dest.writeInt(headResId); dest.writeString(name); }@Override public String toString() { StringBuilder sb = new StringBuilder(200); sb.append("Contact{"); sb.append("phone='" + phone + '\''); sb.append(", headResId='" + headResId + '\''); sb.append(", name='" + name + '\''); sb.append('}'); return sb.toString(); }public static final Creator CREATOR = new Creator() { public Contact createFromParcel(Parcel in) { return new Contact(in); }public Contact[] newArray(int size) { return new Contact[size]; } }; }// public class ContactProvider {private static List contactList; private static Context sContext; private static int[] head = {R.drawable.avater1, R.drawable.avater2, R.drawable.avater3, R.drawable.avater4, R .drawable.avater5, R.drawable.avater6, R.drawable.avater7, R.drawable.avater8, R.drawable.avater9, R .drawable.avater10, R.drawable.avater11, R.drawable.avater12}; private static String[] names = {"梦洁", "雅静", "韵寒", "莉姿", "沛玲", "欣妍", "歆瑶", "凌菲", "靖瑶", "瑾萱", "芳蕤", "若华"}; private static String[] phones = {"18618188630", "18158103936", "18620145337", "15116333186", "18618188630", "18158103936", "18620145337", "15116333186", "18618188630", "18158103936", "18620145337", "18767106408"}; public static void setContext(Context context) { if (sContext == null) sContext = context; }public static List getContactList() { buildContact(); return contactList; }public static List buildContact() { if (null != contactList) { return contactList; } contactList = new ArrayList(); for (int i = 0; i < 12; ++i) { contactList.add(buildContactInfo(phones[i], names[i], head[i])); } return contactList; }private static Contact buildContactInfo(String phone, String name, int resId) { Contact contact = new Contact(); contact.setPhone(phone); contact.setName(name); contact.setHeadResId(resId); return contact; } }

/* * VerticalGridFragment shows a grid of videos */ public class VerticalGridFragment extends android.support.v17.leanback.app.VerticalGridFragment { private static final String TAG = "VerticalGridFragment"; private static final int DEFAULT_COLUMNS = 4; private int numColumns = DEFAULT_COLUMNS; private ArrayObjectAdapter mAdapter; @Override public void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); //setTitle(getString(R.string.vertical_grid_title)); getParams(); setupFragment(); }@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = super.onCreateView(inflater, container, savedInstanceState); return root; }private void setupFragment() { VerticalGridPresenter gridPresenter = new VerticalGridPresenter(FocusHighlight.ZOOM_FACTOR_NONE); gridPresenter.setNumberOfColumns(numColumns); //gridPresenter.setShadowEnabled(false); setGridPresenter(gridPresenter); mAdapter = new ArrayObjectAdapter(new ContactPresenter()); List contacts = ContactProvider.getContactList(); mAdapter.addAll(0, contacts); setAdapter(mAdapter); setOnItemViewClickedListener(new ItemViewClickedListener()); setOnItemViewSelectedListener(new ItemViewSelectedListener()); }public void getParams() { if (getArguments() != null) { numColumns = getArguments().getInt(Extra.COLUMNS); } }private final class ItemViewClickedListener implements OnItemViewClickedListener { @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {if (item instanceof Contact) { Contact contact = (Contact) item; // TODO } } }private final class ItemViewSelectedListener implements OnItemViewSelectedListener { @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { } }}

在Fragment中我们自己实现了一个ContactPresenter,该Presenter是仿照官方的CardPresenter,但是CardPresenter中使用的ImageCardView是系统support包中提供的控件,而ContactPresenter中使用的是自己自定义的控件, 代码如下:
public class ContactPresenter extends Presenter { private static final String TAG = "CardPresenter"; private static int sSelectedBackgroundColor; private static int sDefaultBackgroundColor; @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { Log.d(TAG, "onCreateViewHolder"); sDefaultBackgroundColor = parent.getResources().getColor(R.color.white_35_transparent); sSelectedBackgroundColor = parent.getResources().getColor(R.color.white_60_transparent); ContactView contactView = new ContactView(parent.getContext()) { @Override public void setSelected(boolean selected) { updateCardBackgroundColor(this, selected); super.setSelected(selected); } }; contactView.setFocusable(true); contactView.setFocusableInTouchMode(true); updateCardBackgroundColor(contactView, false); return new ViewHolder(contactView); }private static void updateCardBackgroundColor(ContactView view, boolean selected) { int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor; view.setBackgroundColor(color); //view.findViewById(R.id.info_field).setBackgroundColor(color); }@Override public void onBindViewHolder(ViewHolder viewHolder, Object item) { Contact contact = (Contact) item; ContactView contactView = (ContactView) viewHolder.view; Log.d(TAG, "onBindViewHolder"); contactView.setHead(contact.getHeadResId()); contactView.setName(contact.getName()); contactView.setPhone(contact.getPhone()); }@Override public void onUnbindViewHolder(ViewHolder viewHolder) { Log.d(TAG, "onUnbindViewHolder"); ContactView contactView = (ContactView) viewHolder.view; // Remove references to images so that the garbage collector can free up memory contactView.setHead(0); } }

ContactView是一个继承自LinearLayout的自定义控件,包含了一个ImageView和两个TextView。

到此整个界面的代码就完成了,接下来我们来看看遇到的问题。

问题列表

问题1:控件遥控器不能选中,不能导航
出现这种问题往往是控件没有设置android:focusable="true"属性,只有默认能够选中焦点的才不需要设置改属性,比如Button,EditText。

问题2:控件选中后,看不出选中效果
由于默认选中是没有视觉效果的,因此你需要对控件设置选中效果,比如说背景图片,以前在手机上可能只需要设置selector中的pressed属性,或者selected属性,现在针对TV你必须要设置focused属性,比如拨号键盘选中后会出现一个圆形的选中背景框,

要实现上述效果,因此对每一键盘输入按钮添加如下的selector。
key_board_hover.xml





网易云免费体验馆,0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区


【Android|Android TV 开发(4)】相关文章:
【推荐】 数据迁移的应用场景与解决方案Hamal

    推荐阅读