第一次开发androidTV端,虽然页面很简单,但心中还是难免有些忐忑呢!还好有众多大神帮助,现已见成效啦!androidTV端与android手机端整体上是一致的,唯一不同的地方在于TV端存在焦点,视图的选取需要先将焦点移到这个view上,当界面出现的时候,焦点是默认在电视端的最上方的,当然首先你需要在xml中设置focusable=true,这样这个view才有获取焦点的能力:
android:id="@+id/login"
android:layout_width="@dimen/width_login_iv"
android:layout_height="@dimen/height_login_iv"
android:layout_marginLeft="@dimen/marginLeft_login_iv"
android:layout_marginTop="@dimen/marginTop_login_iv"
android:background="@drawable/login_selector"
android:focusable="true"
android:onClick="logIn1"/>
所以大家没必要太惧怕哈!闲话不说先上效果图:
这次我使用图片的根布局是recyclerview,item的根布局是cardview,究其原因主要是我在开发前期不知从哪听来的电视端recyclerview和cardview是标配,其实用什么都好啦,毕竟时间有限,速速码字哈!
险些跑题,我是来将获取焦点突出,放大,加item边框的好么!
首先一定要在recyclerview中设置focusable=true!这样你里面的item才有能力获取焦点,下面问题来了,当获取焦点时,效果怎么出来呢?首先讲一下放大效果:
在android5.0以后才出现的Z轴的概念,所以我直接一步到位,在recyclerview的adapter中onBindViewHolder下:
holder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
//获取焦点时变化
if (hasFocus) {
if(Build.VERSION.SDK_INT>=21){
ViewCompat.animate(v).scaleX(1.17f).scaleY(1.17f).translationZ(1).start();
}这样就可以完美的解决item叠加的问题(我说的是改变z轴)
都怪google出z轴出的太晚了,现在电视端使用的盒子大多都在5.0以下,我在使用5.0以下版本的盒子的时候出现了item叠加的问题,如图(全是泪):
我们知道出现item叠加的愿意是因为系统绘制也是一个一个绘制的先画的左上一,其他在他后面画的,所以当先画的出现放大效果的时候,如果在5.0之前没有z轴的概念且选中item附近有在其之后绘制的情况下,那么该放大item就会在其他item下面展现放大效果,着实蛋疼。说完就打脸,又想到了在网上得到广泛使用的view.bringToFront();试了一下,未果,原因不详。苦苦思寻好久,没办法了,只好改变其绘制顺序了,问题得以解决:
首先在是主界面绑定
rvMain.setChildDrawingOrderCallback(adapter);
rvMain.setAdapter(adapter);随后在主界面实现:public class MainRecyclerViewAdapter extends RecyclerView.Adapter implements RecyclerView.ChildDrawingOrderCallback {随后系统会让你重写一个方法:
@Override
public int onGetChildDrawingOrder(int childCount, int i) {
focusedChild = mainInterface.rvMain.getFocusedChild();
focusViewIndex = mainInterface.rvMain.indexOfChild(focusedChild);
if (focusViewIndex == -1) {
return i;
}
if (focusViewIndex == i) {
focusid = i;
return childCount - 1;
} else if (i == childCount - 1) {
return focusid;
} else {
return i;
}
}
childCount是可见的item数量,i是你要绘制item的序号,里面的逻辑是调换可见childCount里最后绘制的item和焦点选中item的绘制顺序。例如里面有10个item可见的话,childCount是10,i会走10遍(0-9);我写的focusViewIndex就是焦点选中的序号,如果焦点选中第3个,focusViewIndex=2,当i=2传入的时候(我要让这个item最后一个绘制
),此时我换回原本最后绘制的item;而当我传入原本最后绘制item需要的i时,我要返回我焦点所在的item的i。
最后在item获焦事件里写道:
//获取焦点时变化
if (hasFocus) {
if(Build.VERSION.SDK_INT>=21){
ViewCompat.animate(v).scaleX(1.17f).scaleY(1.17f).translationZ(1).start();
}else {
ViewCompat.animate(v).scaleX(1.17f).scaleY(1.17f).start();
ViewGroup parent = (ViewGroup) v.getParent();
parent.requestLayout();
parent.invalidate();
}好了,我所理解的item获取焦点后放大的效果就是这个样子啦,另外那个背景框的问题呢就是我在item根布局里写了一个background,如图:android:background="@drawable/item_bg_focus"
<?xml version="1.0" encoding="utf-8"?>
我想做到的就是尽量简单,一定会有一些地方考虑不周啦!欢迎大家一起讨论呐!