亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android自定義view仿IOS開(kāi)關(guān)效果

 更新時(shí)間:2019年06月15日 12:00:47   作者:AND_Devil  
這篇文章主要為大家詳細(xì)介紹了Android自定義view仿IOS開(kāi)關(guān)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文主要講解如何在 Android 下實(shí)現(xiàn)高仿 iOS 的開(kāi)關(guān)按鈕,并非是在 Android 自帶的 ToggleButton 上修改,而是使用 API 提供的 onDraw、onMeasure、Canvas 方法,純手工繪制。基本原理就是在 Canvas 上疊著放兩張圖片,上面的圖片根據(jù)手指觸摸情況,不斷移動(dòng),實(shí)現(xiàn)開(kāi)關(guān)效果。

廢話不說(shuō),上效果圖,看看怎么樣

樣式如下: 

 

網(wǎng)上也有實(shí)現(xiàn)這種效果的,但是大都滑動(dòng)沒(méi)中間消失的動(dòng)畫(huà),或者是很復(fù)雜,今天用簡(jiǎn)單的繪圖方式實(shí)現(xiàn),重點(diǎn)就在onDraw里繪圖。

功能點(diǎn):

  • 不滑出邊界,超過(guò)一半自動(dòng)切換(邊界判斷)
  • 可滑動(dòng),也可點(diǎn)擊(事件共存)
  • 提供狀態(tài)改變監(jiān)聽(tīng)(設(shè)置回調(diào))
  • 通過(guò)屬性設(shè)置初始狀態(tài)、背景圖片、滑動(dòng)按鈕(自定義屬性)

自定義View的概述

Android 在繪制 View 時(shí),其實(shí)就像蒙上眼睛在畫(huà)板上畫(huà)畫(huà),它并不知道應(yīng)該把 View 畫(huà)多大,畫(huà)哪兒,怎么畫(huà)。所以我們必須實(shí)現(xiàn) View 的三個(gè)重要方法,以告訴它這些信息。即:onMeasure(畫(huà)多大),onLayout(畫(huà)哪兒),onDraw(怎么畫(huà))。

View的生命周期

在動(dòng)手寫(xiě)之前,必須先了解以下幾個(gè)概念:

1.View 的默認(rèn)不支持 WRAP_CONTENT,必須重寫(xiě) onMeasure 方法,通過(guò) setMeasuredDimension() 設(shè)置尺寸
2.基本的事件分發(fā)機(jī)制:onClickListener 一定是在 onTouchEvent 之后執(zhí)行

自定義View的流程

開(kāi)始動(dòng)手

1.導(dǎo)入開(kāi)關(guān)的樣式文件

<resources>

 <!-- Base application theme. -->
 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
 <!-- Customize your theme here. -->
 <item name="colorPrimary">@color/colorPrimary</item>
 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 <item name="colorAccent">@color/colorAccent</item>
 </style>
 <!--高仿IOS7開(kāi)關(guān) - 樣式-->
 <declare-styleable name="SwitchButton">
 <attr name="buttonColor" format="color" />
 </declare-styleable>

</resources>

2.開(kāi)始自定義view,重點(diǎn)在onDraw()

/**
 * Author:AND
 * Time:2018/3/20.
 * Email:2911743255@qq.com
 * Description:
 * Detail:仿IOS開(kāi)關(guān)
 */
public class SwitchButton extends View {
 //畫(huà)筆
 private final Paint mPaint = new Paint();
 private static final double MBTNHEIGHT = 0.55;
 private static final int OFFSET = 3;
 private int mHeight;
 private float mAnimate = 0L;
 //此處命名不規(guī)范,目的和Android自帶的switch有相同的用法
 private boolean checked = false;
 private float mScale;
 private int mSelectColor;
 private OnCheckedChangeListener mOnCheckedChangeListener;

 public SwitchButton(Context context) {
 this(context, null);
 }

 public SwitchButton(Context context, AttributeSet attrs) {
 super(context, attrs);
 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SwitchButton);
 mSelectColor = typedArray.getColor(R.styleable.SwitchButton_buttonColor, Color.parseColor("#2eaa57"));
 typedArray.recycle();
 }

 /**
 * @param widthMeasureSpec
 * @param heightMeasureSpec 高度是是寬度的0.55倍
 */
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 int width = MeasureSpec.getSize(widthMeasureSpec);
 mHeight = (int) (MBTNHEIGHT * width);
 setMeasuredDimension(width, mHeight);
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 mPaint.setStyle(Paint.Style.FILL);
 mPaint.setAntiAlias(true);
 mPaint.setColor(mSelectColor);
 Rect rect = new Rect(0, 0, getWidth(), getHeight());
 RectF rectf = new RectF(rect);
 //繪制圓角矩形
 canvas.drawRoundRect(rectf, mHeight / 2, mHeight / 2, mPaint);

 //以下save和restore很重要,確保動(dòng)畫(huà)在中間一層 ,如果大家不明白,可以去搜下用法

 canvas.save();
 mPaint.setColor(Color.parseColor("#E6E6E6"));
 mAnimate = mAnimate - 0.1f > 0 ? mAnimate - 0.1f : 0; // 動(dòng)畫(huà)標(biāo)示 ,重繪10次,借鑒被人的動(dòng)畫(huà)
 mScale = (!checked ? 1 - mAnimate : mAnimate);
 canvas.scale(mScale, mScale, getWidth() - getHeight() / 2, rect.centerY());
 //繪制縮放的灰色圓角矩形
 canvas.drawRoundRect(rectf, mHeight / 2, mHeight / 2, mPaint);

 mPaint.setColor(Color.WHITE);
 Rect rect_inner = new Rect(OFFSET, OFFSET, getWidth() - OFFSET, getHeight() - OFFSET);
 RectF rect_f_inner = new RectF(rect_inner);
 //繪制縮放的白色圓角矩形,和上邊的重疊實(shí)現(xiàn)灰色邊框效果
 canvas.drawRoundRect(rect_f_inner, (mHeight - 8) / 2, (mHeight - 8) / 2, mPaint);
 canvas.restore();

 //中間圓形平移
 int sWidth = getWidth();
 int bTranslateX = sWidth - getHeight();
 final float translate = bTranslateX * (!checked ? mAnimate : 1 - mAnimate);
 canvas.translate(translate, 0);

 //以下兩個(gè)圓帶灰色邊框
 mPaint.setColor(Color.parseColor("#E6E6E6"));
 canvas.drawCircle(getHeight() / 2, getHeight() / 2, getHeight() / 2 - OFFSET / 2, mPaint);

 mPaint.setColor(Color.WHITE);
 canvas.drawCircle(getHeight() / 2, getHeight() / 2, getHeight() / 2 - OFFSET, mPaint);

 if (mScale > 0) {
  mPaint.reset();
  invalidate();
 }
 }

 /**
 * 事件分發(fā)
 *
 * @param event
 * @return
 */
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
  return true;
  case MotionEvent.ACTION_MOVE:
  break;
  case MotionEvent.ACTION_UP:
  mAnimate = 1;
  checked = !checked;

  if (mOnCheckedChangeListener != null) {

   mOnCheckedChangeListener.OnCheckedChanged(checked);

  }
  invalidate();
  break;
 }
 return super.onTouchEvent(event);
 }

 /**
 * 狀態(tài)構(gòu)造函數(shù)
 *
 * @return
 */
 public boolean isChecked() {
 return checked;
 }

 public void setChecked(boolean checked) {
 this.checked = checked;
 }

 /**
 * 構(gòu)造函數(shù)
 *
 * @return
 */
 public OnCheckedChangeListener getmOnCheckedChangeListener() {
 return mOnCheckedChangeListener;
 }

 /**
 * 調(diào)用方法
 *
 * @param mOnCheckedChangeListener
 */
 public void setmOnCheckedChangeListener(OnCheckedChangeListener mOnCheckedChangeListener) {
 this.mOnCheckedChangeListener = mOnCheckedChangeListener;
 }

 /**
 * 滑動(dòng)接口
 */
 public interface OnCheckedChangeListener {
 void OnCheckedChanged(boolean isChecked);
 }

}

3.Activity中使用

@Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mBtnSwitch = (SwitchButton) findViewById(R.id.switch_btn);
 mBtnSwitch.setmOnCheckedChangeListener(new SwitchButton.OnCheckedChangeListener() {
  @Override
  public void OnCheckedChanged(boolean isChecked) {
  Toast.makeText(MainActivity.this, "" + isChecked, Toast.LENGTH_SHORT).show();
  }
 });
 }

當(dāng)然,也可以上來(lái)就給開(kāi)關(guān)定義狀態(tài)值

mBtnSwitch.setChecked(boolean);

好了,自定義工作全部完成!!

那么300行左右的代碼 完成了我們的仿iOS SwitchButton 的控件 SwitchView

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論