package com.wasu.widgets.focuswidget; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import com.wasu.cs.widget.MainPageLiveVideoView; import com.wasu.widgets.tools.AnimTools; import com.wasu.widgets.tools.UIUtil; import cn.com.wasu.main.R; /** * @Description: FocusRelativeLayout * @Author: Danxingxi * @CreateDate: 2016/9/2 9:33 */ public class FocusRelativeLayout extends RelativeLayout { private int focusedItemIndex = -1; /** * 实时焦点itemView **/ private View focusItem = null; private int childCount = -1; private onItemFocusChangeListener itemFocusChangeListener; /** * 焦点框 **/ Drawable focusShadowDrawable = null; //用于防止用户快速点击 private long mLastKeyDownTime = 0; public FocusRelativeLayout(Context context) { super(context); init(context); } public FocusRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public FocusRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { setChildrenDrawingOrderEnabled(true); setClipChildren(false); setClipToPadding(false); } @Override protected void onFinishInflate() { super.onFinishInflate(); /**对子控件做焦点监听**/ childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View childView = getChildAt(i); if (childView instanceof View) { final int finalI = i; childView.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { setFocusedItemIndex(v, finalI, hasFocus); } }); } if (childView instanceof ViewGroup) { ((ViewGroup) childView).setClipChildren(false); ((ViewGroup) childView).setClipToPadding(false); int childChildViewConut = ((ViewGroup) childView).getChildCount(); for (int j = 0; j < childChildViewConut; j++) { View childChildView = ((ViewGroup) childView).getChildAt(j); if (childChildView instanceof View) { final int finalI1 = i; childChildView.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { setFocusedItemIndex(v, finalI1, hasFocus); } }); } } } } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (!hasFocus()) { return; } if (focusItem != null) { if (focusShadowDrawable == null) { focusShadowDrawable = getContext().getResources().getDrawable(R.drawable.focus_border); } Rect toFocusedViewRect = UIUtil.createViewRect(this, focusItem, 0); UIUtil.drawDrawableAt(canvas, toFocusedViewRect, focusShadowDrawable); } } /*** * 更新UI并重绘 * * @param focusView 焦点Item * @param position Item的位置 */ public void modifyUI(View focusView, int position) { this.focusItem = focusView; this.focusedItemIndex = position; postInvalidate(); } /** * 获取子控件dispatchDraw的次序 */ @Override protected int getChildDrawingOrder(int childCount, int i) { if (focusedItemIndex < 0) { return i; } if (i < (childCount - 1)) { if (focusedItemIndex == i) i = childCount - 1; } else { if (focusedItemIndex < childCount) i = focusedItemIndex; } return i; } /** * 设置itemView焦点监听器 * @param itemFocusChangeListener */ public void setItemViewFocusChangeListener(onItemFocusChangeListener itemFocusChangeListener) { this.itemFocusChangeListener = itemFocusChangeListener; } public void setSpecialFocusedItemIndex(View toItem, int focusedItemIndex, boolean hasFocus) { if (hasFocus) { modifyUI(toItem, focusedItemIndex); } else { modifyUI(null, focusedItemIndex); } } public void setVideoFocusedItemIndex(View toItem, int focusedItemIndex, boolean hasFocus) { if (hasFocus) { modifyUI(toItem, focusedItemIndex); } else { modifyUI(null, focusedItemIndex); } } public void setFocusedItemIndex(final View toItem, final int focusedItemIndex, boolean hasFocus) { if (hasFocus) { if(toItem instanceof MainPageLiveVideoView){ modifyUI(toItem, focusedItemIndex); }else { toItem.setScaleY(1.06f); toItem.setScaleX(1.06f); modifyUI(toItem, focusedItemIndex); } } else { toItem.setScaleX(1.0f); toItem.setScaleY(1.0f); modifyUI(null, focusedItemIndex); } if(toItem != null && itemFocusChangeListener != null){ itemFocusChangeListener.onItemFocusChange(toItem, focusedItemIndex, hasFocus); } } private ItemViewFocusSearchListener itemViewFocusSearchListener; public void setItemViewFocusSearchListener(ItemViewFocusSearchListener endItemViewFocusSearchListener) { this.itemViewFocusSearchListener = endItemViewFocusSearchListener; } /** * 当焦点item在边缘时方便控制焦点分发 */ public interface ItemViewFocusSearchListener { boolean onItemViewFocusSearch(FocusRelativeLayout parent, View itemView, int itemCount, int position, KeyEvent event); } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (focusItem != null) { int itemCount = getChildCount(); if (itemViewFocusSearchListener != null) { if (itemViewFocusSearchListener.onItemViewFocusSearch(this, focusItem, itemCount, focusedItemIndex, event)) { return true; } } } return super.dispatchKeyEvent(event); } /** * itemView晃动动画 * @param view * @return */ public ObjectAnimator shockAnim(View view){ this.focusItem = view; ObjectAnimator animator= AnimTools.shock(focusItem); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { postInvalidate(); } }); animator.start(); return animator; } public void addChildView(View childView, int leftMargin, int topMargin, int rightMargin, int bottomMargin) { if (childView != null && childView.isFocusable()) { LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.leftMargin = leftMargin; lp.topMargin = topMargin; lp.rightMargin = rightMargin; lp.bottomMargin = bottomMargin; childView.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { // setFocusedItemIndex(v, ++childCount, hasFocus); } }); addView(childView, lp); invalidate(); } else { Log.d("danxx", "添加的ChildView错误"); } } /** * ItemView焦点变化接口 */ public interface onItemFocusChangeListener{ void onItemFocusChange(View itemView, int position, boolean hasFocus); } }