Android TV开发:设置全局焦点框及listview中item的焦点获取

1、设置全局焦点框

创建一个FocusLayout.java文件

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;
/**
* Created by LCN_Louis on 2017/9/5.
*/
public classFocusLayoutextendsRelativeLayoutimplementsViewTreeObserver.OnGlobalFocusChangeListener{
private LayoutParamsmFocusLayoutParams;
private View mFocusView;
public FocusLayout(Contextcontext) {
super(context);
init(context);
}
public FocusLayout(Contextcontext,AttributeSet attrs) {
super(context,attrs);
init(context);
}
public FocusLayout(Contextcontext,AttributeSet attrs,int defStyle) {
super(context,attrs,defStyle);
init(context);
}
private void init(Contextcontext) {
this.mFocusLayoutParams= newRelativeLayout.LayoutParams(0,0);
this.mFocusView = new View(context);
this.mFocusView.setBackgroundResource(R.drawable.default_focus);
this.addView(this.mFocusView,this.mFocusLayoutParams);
}
@Override
public voidonGlobalFocusChanged(ViewoldFocus,View newFocus) {
try {
Rect viewRect = new Rect();
newFocus.getGlobalVisibleRect(viewRect);
correctLocation(viewRect);
this.setFocusLocation(
viewRect.left- this.mFocusView.getPaddingLeft(),
viewRect.top- this.mFocusView.getPaddingTop(),
viewRect.right+ this.mFocusView.getPaddingRight(),
viewRect.bottom+ this.mFocusView.getPaddingBottom());
}catch (NullPointerExceptione){
e.printStackTrace();
}
}
/**
* 由于getGlobalVisibleRect获取的位置是相对于全屏的,所以需要减去FocusLayout本身的左与上距离,变成相对于FocusLayout
*@paramrect
*/
private voidcorrectLocation(Rectrect) {
Rect layoutRect = new Rect();
this.getGlobalVisibleRect(layoutRect);
rect.left-=layoutRect.left;
rect.right-=layoutRect.left;
rect.top-=layoutRect.top;
rect.bottom-=layoutRect.top;
}
/**
* 设置焦点view的位置,计算焦点框的大小
*
* @paramleft
*@paramtop
*@paramright
*@parambottom
*/
protected voidsetFocusLocation(intleft,int top,int right,int bottom) {
int width =right-left;
int height = bottom - top;
this.mFocusLayoutParams.width=width;
this.mFocusLayoutParams.height=height;
this.mFocusLayoutParams.leftMargin=left;
this.mFocusLayoutParams.topMargin=top;
this.mFocusView.layout(left,top,right, bottom);
}
}

default_focus

在Activity中添加 

FocusLayout mFocusLayout;//焦点层 实现OnGlobalFocusChangeListener接口

@Override
public void setContentView(int layoutResID) {
    super.setContentView(layoutResID);
    mFocusLayout = new FocusLayout(this);
    bindListener();//绑定焦点变化事件
    addContentView(mFocusLayout,
            new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT));//添加焦点层
}

private void bindListener() {
    //获取根元素
    View mContainerView = this.getWindow().getDecorView();//.findViewById(android.R.id.content);
    //得到整个view树的viewTreeObserver
    ViewTreeObserver viewTreeObserver = mContainerView.getViewTreeObserver();
    //给观察者设置焦点变化监听
    viewTreeObserver.addOnGlobalFocusChangeListener(mFocusLayout);
}



2、listview中item的焦点获取

activity中
mPoseLV = (ListView) findViewById(R.id.lv_pose_view);
mPoseLV.setItemsCanFocus(true);  //关键代码
mPoseLV.setFocusable(false);	//将listview设置为不可获取焦点,不然listview会最外层会有焦点框
mPoseList = new ArrayList<LectureQuestion>();
mPoseAdapter = new MyListViewAdapter<LectureQuestion>(this, mPoseList, mHandler);
mPoseLV.setAdapter(mPoseAdapter);
mPoseLV.setOnItemClickListener(new AdapterView.OnItemClickListener() 

进入MyListViewAdapter

public class MyListViewAdapter<T> extends BaseAdapter

getview中

给item的布局设置为可获取焦点,同时设置点击事件用来代替原本listview的点击事件(因为原本的listview被设置为了不可获取焦点所以下面这个点击item

mPoseLV.setOnItemClickListener
点击事件就没用了)

LinearLayout mquestion_layout = ViewHolder.get(convertView, R.id.question_layout);
mquestion_layout.setFocusable(true);
mquestion_layout.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Message msg = new Message();
        msg.what = SHOWPOSE;
        msg.arg1 = position;
        mHandler.sendMessage(msg);
    }
});

传Message到Activity中进行handler处理

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
case SHOWPOSE:
    chooseItemPosition = msg.arg1;
  /*
***
***
***
***
*/
    break;
 }
};

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值