android tv 缩放,Android TV控件--ScaleButton

版本更新快,很多控件再一两个版本之后就丢掉了,未免有些可惜,这里记录一个缩放按钮的控件。先看看控件长什么样子。

8a513dad4b54

tv_scalebutton.gif

页面上放了4个ScaleButton控件,当触发了按钮的点击事件之后将按钮置为“选中状态”,按钮的背景色就变为红色。这个控件有四种状态,失焦(NORMAL),焦点(FOCUS),失焦&选中(NORMAL&CHOOSE),焦点&选中(FOCUS&CHOOSE)。功能不多,是一个组合控件,代码也比较简单。贴一下代码

package com.hpplay.scalebutton;

import android.animation.ValueAnimator;

import android.content.Context;

import android.graphics.Color;

import android.graphics.drawable.GradientDrawable;

import android.support.annotation.DrawableRes;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.util.TypedValue;

import android.view.Gravity;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.view.animation.AccelerateDecelerateInterpolator;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;

import android.widget.TextView;

import java.util.HashMap;

import java.util.Map;

/**

* Created by hpplay on 2016/11/10.

*/

public class ScaleButton extends RelativeLayout {

//失焦状态

public static final int NORMAL = 2;

//焦点状态

public static final int FOCUS = 4;

//选中状态, 选中状态与(失焦/焦点)状态平行,也就是说不管当前按钮是焦点状态还是失焦状态都可以设置为选中状态

public static final int CHOOSE = 8;

//默认当前为失焦状态

private int mStatus = NORMAL;

private Context mContext;

private int SCREEN_WIDTH;

//按钮下方的阴影

private ImageView mShadowView;

private LinearLayout mContentLL;

//按钮左侧的图片

private ImageView mLeftView;

//按钮右边的文字

private TextView mDesTxt;

//用于存储各个状态值所对应的背景色

private Map mColorMap = new HashMap();

//(失焦/焦点) & 未选中 状态对应的图片资源

private int mImageResourceId = -1;

//(失焦/焦点) & 选中 状态对应的图片资源

private int mImageChooseResourceId = -1;

public ScaleButton(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

this.mContext = context;

init();

}

public ScaleButton(Context context) {

super(context);

this.mContext = context;

init();

}

public ScaleButton(Context context, AttributeSet attrs) {

super(context, attrs);

this.mContext = context;

init();

}

private void init() {

SCREEN_WIDTH = getScreenWidth(mContext);

int btnHeight = getRelativeWidth(66);

mShadowView = new ImageView(mContext);

mShadowView.setImageResource(R.drawable.topbar_shadow);

mShadowView.setScaleType(ImageView.ScaleType.FIT_XY);

RelativeLayout.LayoutParams shadowParams = new LayoutParams(

getRelativeWidth(66), getRelativeWidth(66));

shadowParams.topMargin = getRelativeWidth(20);

this.addView(mShadowView, shadowParams);

mContentLL = new LinearLayout(mContext);

mContentLL.setOrientation(LinearLayout.HORIZONTAL);

mContentLL.setGravity(Gravity.LEFT);

RelativeLayout.LayoutParams contentParams = new RelativeLayout.LayoutParams(

btnHeight, btnHeight);

contentParams.addRule(RelativeLayout.CENTER_HORIZONTAL);

this.addView(mContentLL, contentParams);

mLeftView = new ImageView(mContext);

LinearLayout.LayoutParams leftParams = new LinearLayout.LayoutParams(

btnHeight,

btnHeight);

mContentLL.addView(mLeftView, leftParams);

mDesTxt = new TextView(mContext);

mDesTxt.setTextColor(Color.BLACK);

mDesTxt.setTextSize(TypedValue.COMPLEX_UNIT_PX, getRelativeWidth(30));

mDesTxt.setSingleLine(true);

mDesTxt.setGravity(Gravity.CENTER);

LinearLayout.LayoutParams desParams = new LinearLayout.LayoutParams(

ViewGroup.LayoutParams.WRAP_CONTENT,

btnHeight);

mContentLL.addView(mDesTxt, desParams);

this.setOnFocusChangeListener(new OnFocusChangeListener() {

@Override

public void onFocusChange(View v, boolean hasFocus) {

int status = hasFocus ? FOCUS : NORMAL;

if (mStatus == (NORMAL | CHOOSE)

|| mStatus == (FOCUS | CHOOSE)) {

setStatus(status | CHOOSE);

} else {

setStatus(status);

}

if (onScaleFocusChangeListener != null) {

onScaleFocusChangeListener

.onScaleBtnFocusChanged(ScaleButton.this, hasFocus);

}

}

});

this.setOnHoverListener(new OnHoverListener() {

@Override

public boolean onHover(View view, MotionEvent motionEvent) {

if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {

requestFocus();

}

return false;

}

});

//初始化三种状态对应的背景色

setBackgroundColor(Color.parseColor("#ffffff"), FOCUS);

setBackgroundColor(Color.parseColor("#CBCFD2"), NORMAL);

setBackgroundColor(Color.parseColor("#FD765F"), CHOOSE);

setStatus(NORMAL);

}

/**

* 设置按钮的状态

* @param status 状态值

*/

public void setStatus(int status) {

if (status == CHOOSE) {

if (this.mStatus == NORMAL) {

this.mStatus = NORMAL | CHOOSE;

} else if (this.mStatus == FOCUS) {

this.mStatus = FOCUS | CHOOSE;

}

} else {

this.mStatus = status;

}

switch (mStatus) {

case NORMAL:

scaleContent(false, false);

if (mImageResourceId > 0) {

mLeftView.setImageResource(mImageResourceId);

}

mContentLL.setBackgroundDrawable(getBgDrawable(mColorMap.get(NORMAL)));

mDesTxt.setTextColor(Color.BLACK);

break;

case FOCUS:

scaleContent(true, true);

if (mImageResourceId > 0) {

mLeftView.setImageResource(mImageResourceId);

}

mContentLL.setBackgroundDrawable(getBgDrawable(mColorMap.get(FOCUS)));

mDesTxt.setTextColor(Color.BLACK);

break;

case NORMAL | CHOOSE:

scaleContent(false, false);

if (mImageChooseResourceId > 0) {

mLeftView.setImageResource(mImageChooseResourceId);

}

mContentLL.setBackgroundDrawable(getBgDrawable(mColorMap.get(CHOOSE)));

mDesTxt.setTextColor(Color.WHITE);

break;

case FOCUS | CHOOSE:

scaleContent(true, true);

if (mImageChooseResourceId > 0) {

mLeftView.setImageResource(mImageChooseResourceId);

}

mContentLL.setBackgroundDrawable(getBgDrawable(mColorMap.get(CHOOSE)));

mDesTxt.setTextColor(Color.WHITE);

break;

}

}

/**

* 清除按钮的选中状态

*/

public void clearChooseStatus() {

if (mStatus == (NORMAL | CHOOSE)) {

setStatus(NORMAL);

} else if (mStatus == (FOCUS | CHOOSE)) {

setStatus(FOCUS);

}

}

public int getStatus() {

return mStatus;

}

public void setBackgroundColor(int color, int status) {

mColorMap.put(status, color);

}

public void setDesTxt(String des) {

mDesTxt.setText(des);

}

public void setImageResource(@DrawableRes int resourceId) {

mImageResourceId = resourceId;

setStatus(mStatus);

}

public void setChooseImageResource(@DrawableRes int resourceId) {

mImageChooseResourceId = resourceId;

setStatus(mStatus);

}

private GradientDrawable getBgDrawable(int color) {

int roundRadius = getRelativeWidth(33); // 66/2

GradientDrawable gd = new GradientDrawable();

gd.setColor(color);

gd.setCornerRadius(roundRadius);

return gd;

}

private void scaleContent(boolean open, final boolean showShdowView) {

int targetValue = 0;

int startValue = mContentLL.getLayoutParams().width;

if (open) {//展开

targetValue = getRelativeWidth(184);

} else {

targetValue = getRelativeWidth(66);

}

ValueAnimator valueAnimator = ValueAnimator.ofInt(startValue, targetValue);

valueAnimator.setDuration(300);

valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

int currentValue = (Integer) animation.getAnimatedValue();

RelativeLayout.LayoutParams contentParams = (RelativeLayout.LayoutParams) mContentLL.getLayoutParams();

contentParams.width = currentValue;

mContentLL.setLayoutParams(contentParams);

RelativeLayout.LayoutParams shadowParams = (RelativeLayout.LayoutParams) mShadowView.getLayoutParams();

shadowParams.width = currentValue + getRelativeWidth(20);

mShadowView.setLayoutParams(shadowParams);

if (showShdowView) {

mShadowView.setAlpha(animation.getAnimatedFraction());

} else {

mShadowView.setAlpha(1 - animation.getAnimatedFraction());

}

}

});

valueAnimator.start();

}

private OnScaleFocusChangeListener onScaleFocusChangeListener;

public void setOnScaleFocusChangeListener(OnScaleFocusChangeListener onScaleFocusChangeListener) {

this.onScaleFocusChangeListener = onScaleFocusChangeListener;

}

public interface OnScaleFocusChangeListener {

void onScaleBtnFocusChanged(ScaleButton scaleButton, boolean focus);

}

public int getScreenWidth(Context context) {

DisplayMetrics displayMetrics = new DisplayMetrics();

WindowManager windowManager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

windowManager.getDefaultDisplay().getMetrics(displayMetrics);

return displayMetrics.widthPixels;

}

private int getRelativeWidth(int pxValue) {

if (SCREEN_WIDTH <= 0) {

return pxValue;

}

return (int) (pxValue * SCREEN_WIDTH / 1920.f);

}

}

功能比较简单,就不多叙了。

看看如何使用,使用的时候可以直接写在布局文件里面,也可以直接用代码写。比较重要的就是设置下面三个属性

ScaleButton mSetBtn = new ScaleButton(this);

mSetBtn.setImageResource(R.drawable.topbar_setting_black_button);

mSetBtn.setChooseImageResource(R.drawable.topbar_setting_white_button);

mSetBtn.setDesTxt("设置");

然后再把这个控件添加到你自己的布局中就可以了。下面贴上实现演示图片功能的代码

package com.hpplay.scalebutton;

import android.content.Intent;

import android.graphics.Color;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity implements ScaleButton.OnScaleFocusChangeListener {

private ScaleButton mStandardBtn;

private ScaleButton mGameBtn;

private ScaleButton mSetBtn;

private ScaleButton mHelpBtn;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

RelativeLayout rootLayout = (RelativeLayout) View.inflate(this, R.layout.activity_main, null);

setContentView(rootLayout);

init(rootLayout);

}

private void init(RelativeLayout relativeLayout) {

mSetBtn = new ScaleButton(this);

mSetBtn.setId(30003);

mSetBtn.setFocusable(true);

mSetBtn.setFocusableInTouchMode(true);

mSetBtn.setClickable(true);

RelativeLayout.LayoutParams setParams = new RelativeLayout.LayoutParams

(ViewGroup.LayoutParams.WRAP_CONTENT

, ViewGroup.LayoutParams.WRAP_CONTENT);

setParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

setParams.topMargin = 20;

relativeLayout.addView(mSetBtn, setParams);

mSetBtn.setImageResource(R.drawable.topbar_setting_black_button);

mSetBtn.setChooseImageResource(R.drawable.topbar_setting_white_button);

mSetBtn.setDesTxt("设置");

mHelpBtn = new ScaleButton(this);

mHelpBtn.setFocusable(true);

mHelpBtn.setFocusableInTouchMode(true);

mHelpBtn.setClickable(true);

mHelpBtn.setId(30002);

RelativeLayout.LayoutParams helpParams = new RelativeLayout.LayoutParams(

ViewGroup.LayoutParams.WRAP_CONTENT

, ViewGroup.LayoutParams.WRAP_CONTENT);

helpParams.addRule(RelativeLayout.LEFT_OF, mSetBtn.getId());

helpParams.addRule(RelativeLayout.ALIGN_TOP, mSetBtn.getId());

relativeLayout.addView(mHelpBtn, helpParams);

mHelpBtn.setImageResource(R.drawable.topbar_help_black_button);

mHelpBtn.setChooseImageResource(R.drawable.topbar_help_white_button);

mHelpBtn.setDesTxt("帮助");

mGameBtn = new ScaleButton(this);

mGameBtn.setFocusableInTouchMode(true);

mGameBtn.setFocusable(true);

mGameBtn.setClickable(true);

mGameBtn.setId(30001);

RelativeLayout.LayoutParams gameParams = new RelativeLayout.LayoutParams(

ViewGroup.LayoutParams.WRAP_CONTENT

, ViewGroup.LayoutParams.WRAP_CONTENT);

gameParams.addRule(RelativeLayout.ALIGN_TOP, mHelpBtn.getId());

gameParams.addRule(RelativeLayout.LEFT_OF, mHelpBtn.getId());

relativeLayout.addView(mGameBtn, gameParams);

mGameBtn.setDesTxt("游戏");

mGameBtn.setImageResource(R.drawable.topbar_game_black_button);

mGameBtn.setChooseImageResource(R.drawable.topbar_game_white_button);

mStandardBtn = new ScaleButton(this);

mStandardBtn.setFocusable(true);

mStandardBtn.setFocusableInTouchMode(true);

mStandardBtn.setClickable(true);

mStandardBtn.setId(30000);

RelativeLayout.LayoutParams standardParams = new RelativeLayout.LayoutParams(

ViewGroup.LayoutParams.WRAP_CONTENT

, ViewGroup.LayoutParams.WRAP_CONTENT);

standardParams.addRule(RelativeLayout.ALIGN_TOP, mHelpBtn.getId());

standardParams.addRule(RelativeLayout.LEFT_OF, mGameBtn.getId());

relativeLayout.addView(mStandardBtn, standardParams);

mStandardBtn.setDesTxt("标准");

mStandardBtn.setImageResource(R.drawable.topbar_home_black_button);

mStandardBtn.setChooseImageResource(R.drawable.topbar_home_white_button);

mSetBtn.setNextFocusRightId(mStandardBtn.getId());

mStandardBtn.setNextFocusLeftId(mSetBtn.getId());

mStandardBtn.setOnScaleFocusChangeListener(this);

mGameBtn.setOnScaleFocusChangeListener(this);

mSetBtn.setOnScaleFocusChangeListener(this);

mHelpBtn.setOnScaleFocusChangeListener(this);

View.OnClickListener onClickListener = new View.OnClickListener() {

@Override

public void onClick(View view) {

if (view instanceof ScaleButton) {

clearBtnChooseStatus();

((ScaleButton) view).setStatus(ScaleButton.CHOOSE);

}

}

};

mSetBtn.setOnClickListener(onClickListener);

mHelpBtn.setOnClickListener(onClickListener);

mGameBtn.setOnClickListener(onClickListener);

mStandardBtn.setOnClickListener(onClickListener);

}

/**

* 清除所有按钮的选中状态

*/

private void clearBtnChooseStatus() {

mSetBtn.clearChooseStatus();

mHelpBtn.clearChooseStatus();

mGameBtn.clearChooseStatus();

mStandardBtn.clearChooseStatus();

}

@Override

public void onScaleBtnFocusChanged(ScaleButton scaleButton, boolean focus) {

if (scaleButton == mSetBtn) {//mSetBtn获取到焦点

} else if (scaleButton == mHelpBtn) {//mHelpBtn获取到焦点

} else if (scaleButton == mGameBtn) {//mGameBtn获取到焦点

} else if (scaleButton == mStandardBtn) {//mStandardBtn获取到焦点

}

}

}

最简单的MainActivity,布局文件也比较简单,就是一个空的Relativelayout,新建项目默认生成的。

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context="com.hpplay.scalebutton.MainActivity">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World!" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值