安卓TV焦点框处理

    xiaoxiao2021-03-25  15

    TV焦点

    1.自定义属性

    <!--焦点边框控件属性--> <declare-styleable name="EdgeView"> <attr name="scale" format="float"/> <attr name="shadow" format="reference"/> <attr name="border" format="reference"/> <attr name="host" format="reference"/> </declare-styleable>

    2.源码

    package com.coship.homefinance.ui; import com.coship.homefinance.R; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.DecelerateInterpolator; /** * EdgeView can make the focus of the more obvious */ public class EdgeView extends View implements ViewTreeObserver.OnGlobalFocusChangeListener { private static final int DEFAULT_TRAN_DUR_ANIM = 200; private static final float DEFUALT_SCALE = 1.0f; private View mFocusContent; private float mScale = 1.05f; private View mOldFocusView; private boolean mAnimEnabled = true; private Drawable mDrawableShadow; private Drawable mDrawableBorder; private int mHostViewId; public EdgeView(Context context) { this(context, null, 0); } public EdgeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public EdgeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray tArray = context.obtainStyledAttributes(attrs, R.styleable.EdgeView);// 获取配置属性 mDrawableBorder = tArray.getDrawable(R.styleable.EdgeView_border); mDrawableShadow = tArray.getDrawable(R.styleable.EdgeView_shadow); mScale = tArray.getFloat(R.styleable.EdgeView_scale, 1.1f); mHostViewId = tArray.getResourceId(R.styleable.EdgeView_host, android.R.id.content); tArray.recycle(); setFocusable(false); } @Override protected void onFinishInflate() { super.onFinishInflate(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); ViewGroup viewGroup = (ViewGroup) getParent(); if (viewGroup != null) { this.mFocusContent = viewGroup.findViewById(mHostViewId); if (this.mFocusContent != null) { mFocusContent.getViewTreeObserver().addOnGlobalFocusChangeListener(this); } } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (this.mFocusContent != null) { this.mFocusContent.getViewTreeObserver().removeOnGlobalFocusChangeListener(this); } } @Override protected void onDraw(Canvas canvas) { canvas.save(); drawShadow(canvas); drawBorder(canvas); canvas.restore(); super.onDraw(canvas); } //draw shadow protected void drawShadow(Canvas canvas) { if (mDrawableShadow != null) { RectF shadowPaddingRect = new RectF(10, 10, 10, -55); int width = getWidth(); int height = getHeight(); Rect padding = new Rect(); mDrawableShadow.getPadding(padding); // int left = (int) Math.rint(shadowPaddingRect.left); int right = (int) Math.rint(shadowPaddingRect.right); int bottom = (int) Math.rint(shadowPaddingRect.bottom); int top = (int) Math.rint(shadowPaddingRect.top); // mDrawableShadow.setBounds(-padding.left - (left), -padding.top - (top), width + padding.right + (right), height + padding.bottom + (bottom)); mDrawableShadow.draw(canvas); } } //draw Border protected void drawBorder(Canvas canvas) { if (mDrawableBorder != null) { RectF paddingRect = new RectF(0, 0, 0, 0); int width = getWidth(); int height = getHeight(); Rect padding = new Rect(); // 边框的绘制. mDrawableBorder.getPadding(padding); // int left = (int) Math.rint(paddingRect.left); int right = (int) Math.rint(paddingRect.right); int bottom = (int) Math.rint(paddingRect.bottom); int top = (int) Math.rint(paddingRect.top); // mDrawableBorder.setBounds(-padding.left - (left), -padding.top - (top), width + padding.right + (right), height + padding.bottom + (bottom)); mDrawableBorder.draw(canvas); } } public void flyWhiteBorder(final View focusView) { flyWhiteBorder(focusView, EdgeView.this, mScale, mScale); } private void flyWhiteBorder(final View focusView, View oldFocus, float scaleX, float scaleY) { int newWidth; int newHeight; float oldTranslationX,oldTranslationY; float newTranslationX,newTranslationY; if (focusView != null) { int[] rectNew = new int[2]; //新焦点框在屏幕的位置 focusView.getLocationOnScreen(rectNew); oldTranslationX = oldFocus.getTranslationX(); oldTranslationY = oldFocus.getTranslationY(); newTranslationX = rectNew[0]; newTranslationY = rectNew[1]; newWidth = (int) (Math.rint(focusView.getWidth() * scaleX)); newHeight = (int) (Math.rint(focusView.getHeight() * scaleY)); ViewGroup.LayoutParams params = getLayoutParams(); params.width = newWidth; params.height = newHeight; setLayoutParams(params); ObjectAnimator transAnimatorX = ObjectAnimator.ofFloat(oldFocus, "translationX", oldTranslationX, newTranslationX); ObjectAnimator transAnimatorY = ObjectAnimator.ofFloat(oldFocus, "translationY", oldTranslationY, newTranslationY); AnimatorSet mAnimatorSet = new AnimatorSet(); mAnimatorSet.playTogether(transAnimatorX, transAnimatorY); mAnimatorSet.setInterpolator(new DecelerateInterpolator(1)); mAnimatorSet.setDuration(DEFAULT_TRAN_DUR_ANIM); //添加动画监听 mAnimatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { if (getVisibility() != VISIBLE) { setVisibility(VISIBLE); } } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); mAnimatorSet.start(); } } @Override public void onGlobalFocusChanged(final View oldFocus, final View newFocus) { if (!mAnimEnabled) return; if (mOldFocusView != null) { mOldFocusView.animate().scaleX(DEFUALT_SCALE).scaleY(DEFUALT_SCALE).setDuration(DEFAULT_TRAN_DUR_ANIM).start(); } if(!isContain(mFocusContent, newFocus)){ setVisibility(GONE); return; } if (newFocus != null ) { mOldFocusView = newFocus; // 4.3以下需要自己保存. newFocus.bringToFront(); newFocus.animate().scaleX(mScale).scaleY(mScale).setDuration(DEFAULT_TRAN_DUR_ANIM).start(); postDelayed(new Runnable() { @Override public void run() { flyWhiteBorder(newFocus);//页面切换时view的位置更新慢导致计算不正确 } },DEFAULT_TRAN_DUR_ANIM); } } private boolean isContain(View view, View viewChild){ if(view == viewChild){ return true; } else if(view instanceof ViewGroup){ ViewGroup viewGroup = (ViewGroup)view; int count = viewGroup.getChildCount(); for (int i = 0; i < count; i++) { View v = viewGroup.getChildAt(i); if(isContain(v, viewChild)){ return true; } } } return false; } }

    转载请注明原文地址: https://ju.6miu.com/read-149774.html

    最新回复(0)