国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android自定義雙向進(jìn)度條的實現(xiàn)代碼

2019-12-12 02:03:16
字體:
供稿:網(wǎng)友

想整個雙向的進(jìn)度條,就是可以選取播放范圍的。

像這樣:


然而官方控件里只有單向的。不要慌,我們自己畫一個。

繪制一個進(jìn)度條主要是三方面。1.樣式,2.尺寸,3.操作監(jiān)聽。

完整代碼來一遍:

注釋基本上就把原理說明了一下。

package util;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.drawable.Drawable;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.example.qzd.utildemo.R;import java.math.BigDecimal;/** * 雙向滑塊的進(jìn)度條(區(qū)域選擇) */public class SeekRangeBar extends View {  private Context _context;  private static final int CLICK_ON_LOW = 1;    //手指在前滑塊上滑動  private static final int CLICK_ON_HIGH = 2;    //手指在后滑塊上滑動  private static final int CLICK_IN_LOW_AREA = 3;  //手指點(diǎn)擊離前滑塊近  private static final int CLICK_IN_HIGH_AREA = 4; //手指點(diǎn)擊離后滑塊近  private static final int CLICK_OUT_AREA = 5;   //手指點(diǎn)擊在view外  private static final int CLICK_INVAILD = 0;  private static final int[] STATE_NORMAL = {};  private static final int[] STATE_PRESSED = {android.R.attr.state_pressed,android.R.attr.state_window_focused,};  private static int mThumbMarginTop = 0;  //滑動塊頂部離view頂部的距離  private static int mTextViewMarginTop = 0;  //當(dāng)前滑塊文字距離view頂部距離  private Drawable hasScrollBarBg;    //滑動條滑動后背景圖  private Drawable notScrollBarBg;    //滑動條未滑動背景圖  private Drawable mThumbLow;     //前滑塊  private Drawable mThumbHigh;    //后滑塊  private int mScollBarWidth;   //控件寬度 = 滑動條寬度 + 滑動塊寬度  private int mScollBarHeight;  //控件高度  private int mThumbWidth;    //滑動塊直徑  private double mOffsetLow = 0;   //前滑塊中心坐標(biāo)  private double mOffsetHigh = 0;  //后滑塊中心坐標(biāo)  private int mDistance=0;   //總刻度是固定距離 兩邊各去掉半個滑塊距離  private int mFlag = CLICK_INVAILD;  //手指按下的類型  private double defaultScreenLow = 0;  //默認(rèn)前滑塊位置百分比  private double defaultScreenHigh = 100; //默認(rèn)后滑塊位置百分比  private OnSeekBarChangeListener mBarChangeListener;  private boolean editable=false;//是否處于可編輯狀態(tài)  private int miniGap=5;//AB的最小間隔  private double progressLow;//起點(diǎn)(百分比)  private double progressHigh;//終點(diǎn)  public SeekRangeBar(Context context) {    this(context, null);  }  public SeekRangeBar(Context context, AttributeSet attrs) {    this(context, attrs, 0);  }  public SeekRangeBar(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    _context=context;    //這里設(shè)置背景圖及滑塊圖,自定義過進(jìn)度條的同學(xué)應(yīng)該很熟悉了    notScrollBarBg = ContextCompat.getDrawable(_context,R.mipmap.hp_wbf);    hasScrollBarBg = ContextCompat.getDrawable(_context, R.mipmap.hp_ybf);    mThumbLow = ContextCompat.getDrawable(_context,R.mipmap.hp_a);    mThumbHigh = ContextCompat.getDrawable(_context,R.mipmap.hp_b);    mThumbLow.setState(STATE_NORMAL);    mThumbHigh.setState(STATE_NORMAL);    //設(shè)置滑動條高度    mScollBarHeight = notScrollBarBg.getIntrinsicHeight();    //設(shè)置滑動塊直徑    mThumbWidth = mThumbLow.getIntrinsicWidth();  }  /**   * 測量view尺寸(在onDraw()之前)   * @param widthMeasureSpec   * @param heightMeasureSpec   */  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    int width = MeasureSpec.getSize(widthMeasureSpec);    mScollBarWidth = width;    if(mDistance==0) {//這里滑塊中心坐標(biāo)初始化的時候測量一下(根據(jù)mDistance是否賦值判斷),并不需要不停地去測量。后面會根據(jù)進(jìn)度計算滑塊位置。      mOffsetLow = mThumbWidth / 2;      mOffsetHigh = width - mThumbWidth / 2;    }    mDistance = width - mThumbWidth;    if(defaultScreenLow != 0) {      mOffsetLow = formatInt(defaultScreenLow / 100 * (mDistance)) + mThumbWidth / 2;    }    if(defaultScreenHigh != 100) {      mOffsetHigh = formatInt(defaultScreenHigh / 100 * (mDistance)) + mThumbWidth / 2;    }    setMeasuredDimension(width, mThumbWidth + mThumbMarginTop + 2);  }  protected void onLayout(boolean changed, int l, int t, int r, int b) {    super.onLayout(changed, l, t, r, b);  }  /**   * 繪制進(jìn)度條   */  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    //設(shè)置繪制樣式    Paint text_Paint = new Paint();    text_Paint.setTextAlign(Paint.Align.CENTER);    text_Paint.setColor(Color.RED);    text_Paint.setTextSize(20);    int top = mThumbMarginTop + mThumbWidth / 2 - mScollBarHeight / 2;    int bottom = top + mScollBarHeight;    //繪制是否可操作狀態(tài)的下的不同樣式,僅可編輯狀態(tài)下顯示進(jìn)度條    if(editable) {      //白色滑動條,兩個滑塊各兩邊部分      notScrollBarBg.setBounds(mThumbWidth / 2, top, mScollBarWidth - mThumbWidth / 2, bottom);      notScrollBarBg.draw(canvas);      //紅色滑動條,兩個滑塊中間部分      hasScrollBarBg.setBounds((int) mOffsetLow, top, (int) mOffsetHigh, bottom);      hasScrollBarBg.draw(canvas);    }    //前滑塊    mThumbLow.setBounds((int) (mOffsetLow - mThumbWidth / 2), mThumbMarginTop, (int) (mOffsetLow + mThumbWidth / 2), mThumbWidth + mThumbMarginTop);    mThumbLow.draw(canvas);    //后滑塊    mThumbHigh.setBounds((int) (mOffsetHigh - mThumbWidth / 2), mThumbMarginTop, (int) (mOffsetHigh + mThumbWidth / 2), mThumbWidth + mThumbMarginTop);    mThumbHigh.draw(canvas);    //當(dāng)前滑塊刻度    progressLow = formatInt((mOffsetLow - mThumbWidth / 2) * 100 / mDistance);    progressHigh = formatInt((mOffsetHigh - mThumbWidth / 2) * 100 / mDistance);    canvas.drawText((int) progressLow + "", (int) mOffsetLow - 2 - 2, mTextViewMarginTop, text_Paint);    canvas.drawText((int) progressHigh + "", (int) mOffsetHigh - 2, mTextViewMarginTop, text_Paint);    if (mBarChangeListener != null) {      mBarChangeListener.onProgressChanged(this, progressLow, progressHigh);    }  }  //手勢監(jiān)聽  @Override  public boolean onTouchEvent(MotionEvent e) {    if(!editable) {      return false;    }    if (e.getAction() == MotionEvent.ACTION_DOWN) {      mFlag = getAreaFlag(e);      if (mFlag == CLICK_ON_LOW) {        mThumbLow.setState(STATE_PRESSED);      } else if (mFlag == CLICK_ON_HIGH) {        mThumbHigh.setState(STATE_PRESSED);      } else if (mFlag == CLICK_IN_LOW_AREA) {        mThumbLow.setState(STATE_PRESSED);        mThumbHigh.setState(STATE_NORMAL);        //如果點(diǎn)擊0-mThumbWidth/2坐標(biāo)        if (e.getX() < 0 || e.getX() <= mThumbWidth / 2) {          mOffsetLow = mThumbWidth / 2;        } else if (e.getX() > mScollBarWidth - mThumbWidth / 2) {          mOffsetLow = mThumbWidth / 2 + mDistance;        } else {          mOffsetLow = formatInt(e.getX());        }      } else if (mFlag == CLICK_IN_HIGH_AREA) {        mThumbHigh.setState(STATE_PRESSED);        mThumbLow.setState(STATE_NORMAL);        if (e.getX() >= mScollBarWidth - mThumbWidth / 2) {          mOffsetHigh = mDistance + mThumbWidth / 2;        } else {          mOffsetHigh = formatInt(e.getX());        }      }      //更新滑塊      invalidate();    } else if (e.getAction() == MotionEvent.ACTION_MOVE) {      if (mFlag == CLICK_ON_LOW) {        if (e.getX() < 0 || e.getX() <= mThumbWidth / 2) {          mOffsetLow = mThumbWidth / 2;        } else if (e.getX() >= mScollBarWidth - mThumbWidth / 2) {          mOffsetLow = mThumbWidth / 2 + mDistance;          mOffsetHigh = mOffsetLow;        } else {          mOffsetLow = formatInt(e.getX());          if (mOffsetHigh - mOffsetLow <= 0) {            mOffsetHigh = (mOffsetLow <= mDistance + mThumbWidth / 2) ? (mOffsetLow) : (mDistance + mThumbWidth / 2);          }        }      } else if (mFlag == CLICK_ON_HIGH) {        if (e.getX() < mThumbWidth / 2) {          mOffsetHigh = mThumbWidth / 2;          mOffsetLow = mThumbWidth / 2;        } else if (e.getX() > mScollBarWidth - mThumbWidth / 2) {          mOffsetHigh = mThumbWidth / 2 + mDistance;        } else {          mOffsetHigh = formatInt(e.getX());          if (mOffsetHigh - mOffsetLow <= 0) {            mOffsetLow = (mOffsetHigh >= mThumbWidth / 2) ? (mOffsetHigh) : mThumbWidth / 2;          }        }      }      //更新滑塊,每次滑塊有動作都要執(zhí)行此函數(shù)觸發(fā)onDraw方法繪制新圖片      invalidate();    } else if (e.getAction() == MotionEvent.ACTION_UP) {      Log.d("LOGCAT","ACTION UP:"+progressHigh+"-"+progressLow);      mThumbLow.setState(STATE_NORMAL);      mThumbHigh.setState(STATE_NORMAL);      if(miniGap>0 && progressHigh<progressLow+miniGap){        progressHigh=progressLow+miniGap;        this.defaultScreenHigh = progressHigh;        mOffsetHigh = formatInt(progressHigh / 100 * (mDistance)) + mThumbWidth / 2;        invalidate();      }    }    return true;  }  /**   * 設(shè)置是否可編輯狀態(tài),非可編輯狀態(tài)將不能對AB點(diǎn)進(jìn)行操作   * @param _b   */  public void setEditable(boolean _b){    editable=_b;    invalidate();  }  /**   * 獲取當(dāng)前手指位置   */  public int getAreaFlag(MotionEvent e) {    int top = mThumbMarginTop;    int bottom = mThumbWidth + mThumbMarginTop;    if (e.getY() >= top && e.getY() <= bottom && e.getX() >= (mOffsetLow - mThumbWidth / 2) && e.getX() <= mOffsetLow + mThumbWidth / 2) {      return CLICK_ON_LOW;    } else if (e.getY() >= top && e.getY() <= bottom && e.getX() >= (mOffsetHigh - mThumbWidth / 2) && e.getX() <= (mOffsetHigh + mThumbWidth / 2)) {      return CLICK_ON_HIGH;    } else if (e.getY() >= top      && e.getY() <= bottom      && ((e.getX() >= 0 && e.getX() < (mOffsetLow - mThumbWidth / 2)) || ((e.getX() > (mOffsetLow + mThumbWidth / 2))      && e.getX() <= ((double) mOffsetHigh + mOffsetLow) / 2))) {      return CLICK_IN_LOW_AREA;    } else if (e.getY() >= top && e.getY() <= bottom && (((e.getX() > ((double) mOffsetHigh + mOffsetLow) / 2) && e.getX() < (mOffsetHigh - mThumbWidth / 2)) || (e.getX() > (mOffsetHigh + mThumbWidth / 2) && e.getX() <= mScollBarWidth))) {      return CLICK_IN_HIGH_AREA;    } else if (!(e.getX() >= 0 && e.getX() <= mScollBarWidth && e.getY() >= top && e.getY() <= bottom)) {      return CLICK_OUT_AREA;    } else {      return CLICK_INVAILD;    }  }  /**   * 設(shè)置前滑塊位置   * @param progressLow   */  public void setProgressLow(double progressLow) {    this.defaultScreenLow = progressLow;    mOffsetLow = formatInt(progressLow / 100 * (mDistance)) + mThumbWidth / 2;    invalidate();  }  /**   * 設(shè)置后滑塊位置   * @param progressHigh   */  public void setProgressHigh(double progressHigh) {    this.defaultScreenHigh = progressHigh;    mOffsetHigh = formatInt(progressHigh / 100 * (mDistance)) + mThumbWidth / 2;    invalidate();  }  /**   * 設(shè)置滑動監(jiān)聽   * @param mListener   */  public void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener) {    this.mBarChangeListener = mListener;  }  /**   * 滑動監(jiān)聽,改變輸入框的值   */  public interface OnSeekBarChangeListener {    //滑動時    public void onProgressChanged(SeekRangeBar seekBar, double progressLow, double progressHigh);  }  /**   * 設(shè)置滑動結(jié)果為整數(shù)   */  private int formatInt(double value) {    BigDecimal bd = new BigDecimal(value);    BigDecimal bd1 = bd.setScale(0, BigDecimal.ROUND_HALF_UP);    return bd1.intValue();  }}

然后就可以在程序中使用了。

布局中

<util.SeekRangeBar  android:id="@+id/doubleSeekbar"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_centerVertical="true"/>

調(diào)用

private SeekRangeBar doubleSeekbar;//雙向進(jìn)度條doubleSeekbar = (SeekRangeBar) findViewById(R.id.doubleSeekbar);//監(jiān)聽進(jìn)度范圍變化doubleSeekbar.setOnSeekBarChangeListener(new SeekRangeBar.OnSeekBarChangeListener() {  @Override  public void onProgressChanged(SeekRangeBar seekBar, double progressLow, double progressHigh) {    Log.d("LOGCAT","低:" + progressLow + "高:" + progressHigh);  }});

相關(guān)GitHub項目地址:https://github.com/codeqian/android-class-lib

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 舟曲县| 都江堰市| 大荔县| 皮山县| 灵川县| 深州市| 甘孜| 盱眙县| 濮阳县| 长寿区| 大厂| 天等县| 南安市| 长宁区| 乌兰县| 湘乡市| 金昌市| 会理县| 嘉义县| 松滋市| 东辽县| 延安市| 缙云县| 萍乡市| 维西| 綦江县| 砀山县| 南城县| 北票市| 库车县| 红河县| 界首市| 德令哈市| 霍山县| 长岭县| 平果县| 贵港市| 怀宁县| 泰顺县| 饶阳县| 灵山县|