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);
}
}
在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的焦点获取
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;
} };