Kotlin-可調節加減的進度條

1.效果圖:

2.主界面,其實是從一個java項目,簡單修改而來的 ,項目下載地址:https://github.com/wrs13634194612/KotlinProcess 

package com.ufi.pdioms.ztkotlin

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import kotlinx.android.synthetic.main.activity_first.*
import kotlinx.android.synthetic.main.activity_main.*
import android.view.View.OnLongClickListener

class MainActivity : AppCompatActivity() {
    private var SYNC_INCSUB = 0
    private var BOOL_HP = false
    private var HP_Freq = 0
    private var LP_Freq = 0
    private var Freq = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_first)

        id_mcl_seekbar_valume.setOnSeekBarChangeListener { mhs_SeekBar, progress, fromUser ->
            Log.e("TAG", "progress: $progress ,fromUser: $fromUser")
            tv_main.text = (progress+20).toString()
            id_mcl_seekbar_valume.progress = progress
            Freq= progress
        }

        id_b_freq_dialog_inc.setOnClickListener {
            SYNC_INCSUB = 1
            Freq_INC_SUB(true)
        }

        id_b_freq_dialog_inc.setOnLongClickListener(object : OnLongClickListener{
            override fun onLongClick(p0: View?): Boolean {
                id_b_freq_dialog_inc.setStart()
                return false
            }
        })


        id_b_freq_dialog_inc.setOnLongTouchListener(object: LongCickButton.LongTouchListener{
            override fun onLongTouch() {
                SYNC_INCSUB = 1
                Freq_INC_SUB(true)
            }
        },100)

        //  =====    ---

        id_b_freq_dialog_sub.setOnClickListener {
            SYNC_INCSUB =0
            Freq_INC_SUB(false)
        }

        id_b_freq_dialog_sub.setOnLongClickListener(object : OnLongClickListener{
            override fun onLongClick(p0: View?): Boolean {
                id_b_freq_dialog_sub.setStart()
                return false
            }
        })


        id_b_freq_dialog_sub.setOnLongTouchListener(object: LongCickButton.LongTouchListener{
            override fun onLongTouch() {
                SYNC_INCSUB = 0
                Freq_INC_SUB(false)
            }
        },100)


    }

    private fun Freq_INC_SUB(inc: Boolean) {
        if (inc) {//遞增
            if (BOOL_HP) {//高通
                if (++Freq > LP_Freq) {
                    Freq = LP_Freq
                }
            } else {
                if (++Freq > 480) {
                    Freq = 480
                }
            }
        } else {
            if (BOOL_HP) {//高通
                if (--Freq < 0) {
                    Freq = 0
                }
            } else {
                if (--Freq < HP_Freq) {
                    Freq = HP_Freq
                }
            }
        }

        id_mcl_seekbar_valume.progress = Freq
        tv_main.text = (Freq+20).toString()
    }
}

3.主界面佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mhsb_seekbar="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="20"
        android:textSize="30sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <com.ufi.pdioms.ztkotlin.LongCickButton
            android:id="@+id/id_b_freq_dialog_sub"
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_gravity="center"
            android:background="@drawable/chs_output_valume_sub_press"
            android:gravity="center"
            android:scaleType="fitCenter"
            android:textAllCaps="false" />

        <com.ufi.pdioms.ztkotlin.MHS_SeekBar
            android:id="@+id/id_mcl_seekbar_valume"
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:layout_centerInParent="true"
            android:layout_gravity="center"
            android:thumb="@drawable/chs_mhs_seekbar_thumb"
            mhsb_seekbar:mhs_numtext_color="@color/output_channel_valume_text_color"
            mhsb_seekbar:mhs_numtext_size="12sp"
            mhsb_seekbar:mhs_progress_background_color="@color/mastervolume_seekbar_progress_bg_color"
            mhsb_seekbar:mhs_progress_color="@color/output_channel_valume_text_color"
            mhsb_seekbar:mhs_progress_max="480"
            mhsb_seekbar:mhs_progress_width="2dp" />

        <com.ufi.pdioms.ztkotlin.LongCickButton
            android:id="@+id/id_b_freq_dialog_inc"
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_gravity="center"
            android:background="@drawable/chs_output_valume_inc_press"
            android:gravity="center"
            android:scaleType="fitCenter"
            android:textAllCaps="false" />
    </LinearLayout>

</LinearLayout>

4.自定義進度條

package com.ufi.pdioms.ztkotlin;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class MHS_SeekBar extends View {

    private final boolean DEBUG = false;
    private final String TAG = "MHS_SeekBar";

    private Context mContext = null;
    private AttributeSet mAttrs = null;

    private Drawable mThumbDrawable = null;
    private int mThumbHeight = 0;
    private int mThumbWidth = 0;
    private int[] mThumbNormal = null;
    private int[] mThumbPressed = null;
    private boolean CanTouch = true;
    private boolean ThumbTouch = false;
    private float mSeekBarMax = 0;
    private float mThumbX = 0;
    private float mThumbY = 0;
    private Paint mhsSeekBarBackgroundPaint = null;
    private Paint mhsSeekbarProgressPaint = null;
    private RectF RectF_mhsbg = null;
    private RectF RectF_mhsprogress = null;
    private float mhsSeekbarLong = 0;
    private int mhsSeekbarWidth = 0;
    private int mhsSeekbarRound = 0;
    private float mhsprogress_set = 0;
    private int sb_left = 0;
    private int sb_top = 0;
    private int sb_right = 0;
    private int sb_bottom = 0;

    private int mViewHeight = 0;
    private int mViewWidth = 0;
    //private int mSeekBarCenterX = 0;
    private int mSeekBarCenterY = 0;
    private int mCurrentProgress = 0;
    private int old_mCurrentProgress = 0;
    private OnMSBSeekBarChangeListener mOnMSBSeekBarChangeListener = null;

    public MHS_SeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        mAttrs = attrs;
        initView();
    }

    public MHS_SeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mAttrs = attrs;
        initView();
    }

    public MHS_SeekBar(Context context) {
        super(context);
        mContext = context;
        initView();
    }

    private void initView() {
        if (DEBUG) Log.d(TAG, "initView");
        TypedArray localTypedArray = mContext.obtainStyledAttributes(mAttrs, R.styleable.mhsb_seekbar);

        mThumbDrawable = localTypedArray.getDrawable(R.styleable.mhsb_seekbar_android_thumb);
        mThumbWidth = this.mThumbDrawable.getIntrinsicWidth();
        mThumbHeight = this.mThumbDrawable.getIntrinsicHeight();

        mThumbNormal = new int[]{-android.R.attr.state_focused, -android.R.attr.state_pressed,
                -android.R.attr.state_selected, -android.R.attr.state_checked};
        mThumbPressed = new int[]{android.R.attr.state_focused, android.R.attr.state_pressed,
                android.R.attr.state_selected, android.R.attr.state_checked};
        localTypedArray.getDimension(R.styleable.mhsb_seekbar_mhs_progress_width, 5);
        mhsSeekbarWidth = (int) localTypedArray.getDimension(R.styleable.mhsb_seekbar_mhs_progress_width, 5);
        mhsSeekbarRound = (int) localTypedArray.getDimension(R.styleable.mhsb_seekbar_mhs_progress_bar_round, 4);

        int progressBackgroundColor = localTypedArray.getColor(R.styleable.mhsb_seekbar_mhs_progress_background_color, getResources().getColor(R.color.csb_bg));
        int progressFrontColor = localTypedArray.getColor(R.styleable.mhsb_seekbar_mhs_progress_color, getResources().getColor(R.color.text_color_xoverset));
        mSeekBarMax = localTypedArray.getInteger(R.styleable.mhsb_seekbar_mhs_progress_max, 60);
        //----
        mhsSeekBarBackgroundPaint = new Paint();
        mhsSeekbarProgressPaint = new Paint();

        mhsSeekBarBackgroundPaint.setColor(progressBackgroundColor);
        mhsSeekbarProgressPaint.setColor(progressFrontColor);

        mhsSeekBarBackgroundPaint.setAntiAlias(true);
        mhsSeekbarProgressPaint.setAntiAlias(true);

        localTypedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        setMeasuredDimension(width, height);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (DEBUG) Log.d(TAG, "onMeasure");
        mViewWidth = width;//getWidth();
        mViewHeight = height;//getHeight();

        //mSeekBarCenterX = mViewWidth / 2;
        mSeekBarCenterY = mViewHeight / 2;
        mhsSeekbarLong = mViewWidth - mThumbWidth;
        //seekbar progress and bar start point and stop point
        sb_left = mThumbWidth / 2;
        sb_top = mSeekBarCenterY - mhsSeekbarWidth / 2;
        sb_right = (int) (sb_left + mhsSeekbarLong);
        sb_bottom = mSeekBarCenterY + mhsSeekbarWidth / 2;

        //seekbar progress
        mhsprogress_set = mhsSeekbarLong / mSeekBarMax * mCurrentProgress;
        //draw Rect seekbar bg
        RectF_mhsbg = new RectF(sb_left, sb_top, sb_right, sb_bottom);
        //draw Rect seekbar progress
        RectF_mhsprogress = new RectF(sb_left, sb_top, mhsprogress_set, sb_bottom);
        //seekbar Thumb
        mThumbX = mhsprogress_set;
        mThumbY = mSeekBarCenterY - mThumbHeight / 2;
        if (DEBUG) System.out.println("MHS mViewWidth:" + mViewWidth);
        if (DEBUG) System.out.println("MHS mViewHeight:" + mViewHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int p_top = (int) (mhsprogress_set + mThumbWidth / 2);
        RectF_mhsprogress = new RectF(sb_left, sb_top, p_top, sb_bottom);
        canvas.drawRoundRect(RectF_mhsbg, mhsSeekbarRound, mhsSeekbarRound, mhsSeekBarBackgroundPaint);
        canvas.drawRoundRect(RectF_mhsprogress, mhsSeekbarRound, mhsSeekbarRound, mhsSeekbarProgressPaint);
        drawThumbBitmap(canvas);
        //drawProgressText(canvas);

        super.onDraw(canvas);
    }

    private void drawThumbBitmap(Canvas canvas) {
        this.mThumbDrawable.setBounds((int) mThumbX, (int) mThumbY,
                (int) (mThumbX + mThumbWidth), (int) (mThumbY + mThumbHeight));
        this.mThumbDrawable.draw(canvas);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!CanTouch) {
            return true;
        }
        float eventX = event.getX();
        float eventY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //Log.v(TAG, "MHS ACTION_DOWN eventX = " + eventX);
                if (((eventX + mThumbWidth / 4) > mThumbX) && ((eventX - mThumbWidth) < mThumbX)) {
                    ThumbTouch = true;
                } else {
                    ThumbTouch = false;
                }
                break;

            case MotionEvent.ACTION_MOVE:
                //Log.v(TAG, "MHS ACTION_MOVE eventX = " + eventX);
                seekTo(eventX, eventY, ThumbTouch, true);
                break;

            case MotionEvent.ACTION_UP:
                seekTo(eventX, eventY, false, false);
                ThumbTouch = false;
                mThumbDrawable.setState(mThumbNormal);
                invalidate();
                break;
            default:
                seekTo(eventX, eventY, false, false);
                ThumbTouch = false;
                mThumbDrawable.setState(mThumbNormal);
                invalidate();
                break;
        }
        return true;
    }

    private void seekTo(float eventX, float eventY, boolean isUp, boolean boolean_MotionEvent) {
        eventX -= mThumbWidth / 4;
        if (CanTouch == true) {
            if (true == isUp) {
                mThumbDrawable.setState(mThumbPressed);
                if ((eventX > mhsSeekbarWidth / 4) && (eventX < (mhsSeekbarLong))) {
                    mCurrentProgress = (int) (mSeekBarMax * eventX / mhsSeekbarLong);
                } else if (eventX > mhsSeekbarLong) {
                    mCurrentProgress = (int) mSeekBarMax;
                } else if (eventX < mhsSeekbarWidth / 4) {
                    mCurrentProgress = 0;
                }

                if ((mOnMSBSeekBarChangeListener != null) && (mCurrentProgress != old_mCurrentProgress)) {
                    old_mCurrentProgress = mCurrentProgress;
                    mOnMSBSeekBarChangeListener.onProgressChanged(this, mCurrentProgress, boolean_MotionEvent);
                }

                mhsprogress_set = mhsSeekbarLong / mSeekBarMax * mCurrentProgress;
                //mThumbY=mhsprogress_set+mThumbHeight/2;
                mThumbX = mhsprogress_set;

                //Log.v(TAG, "MHS mCurrentProgress = " + mCurrentProgress);

                invalidate();
            } else {
                if ((mOnMSBSeekBarChangeListener != null) && (mCurrentProgress != old_mCurrentProgress)) {
                    old_mCurrentProgress = mCurrentProgress;
                    mOnMSBSeekBarChangeListener.onProgressChanged(this, mCurrentProgress, false);
                }
                mThumbDrawable.setState(mThumbNormal);
                invalidate();
            }
        } else if (CanTouch == false) {
            if ((mOnMSBSeekBarChangeListener != null) && (mCurrentProgress != old_mCurrentProgress)) {
                old_mCurrentProgress = mCurrentProgress;
                mOnMSBSeekBarChangeListener.onProgressChanged(this, mCurrentProgress, boolean_MotionEvent);
            }
        }
    }

    /*
     */
    public void setTouch(boolean touch) {
        CanTouch = touch;
    }

    /*
     */
    public void setProgress(int progress) {
        CanTouch = true;
        if (DEBUG) Log.v(TAG, "setProgress progress = " + progress);
        if (progress > mSeekBarMax) {
            progress = (int) mSeekBarMax;
        }
        if (progress < 0) {
            progress = 0;
        }
        mCurrentProgress = progress;

        mhsprogress_set = mhsSeekbarLong / mSeekBarMax * mCurrentProgress;
        //mThumbY=mhsprogress_set+mThumbHeight/2;
        mThumbX = mhsprogress_set;
        //if (mOnMSBSeekBarChangeListener != null){
        //	mOnMSBSeekBarChangeListener.onProgressChanged(this, mCurrentProgress, false);
        invalidate();
    }

    public int getProgress() {
        return mCurrentProgress;
    }

    public void setProgressMax(int max) {
        if (DEBUG) Log.v(TAG, "setProgressMax max = " + max);
        mSeekBarMax = max;
    }

    public int getProgressMax() {
        return (int) mSeekBarMax;
    }

    public void setProgressThumb(int thumbId) {
        mThumbDrawable = mContext.getResources().getDrawable(thumbId);
    }

    public void setProgressBackgroundColor(int color) {
        mhsSeekBarBackgroundPaint.setColor(color);
    }

    public void setProgressFrontColor(int color) {
        mhsSeekbarProgressPaint.setColor(color);
    }

    public void setIsShowProgressText(boolean isShow) {
    }

    public void setOnSeekBarChangeListener(OnMSBSeekBarChangeListener l) {
        mOnMSBSeekBarChangeListener = l;
    }

    public interface OnMSBSeekBarChangeListener {

        public abstract void onProgressChanged(MHS_SeekBar mhs_SeekBar,
                                               int progress, boolean fromUser);

    }
}

5.:自定義的按鈕,帶點擊和長按監聽 

package com.ufi.pdioms.ztkotlin;


import android.annotation.SuppressLint;
import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;

@SuppressLint({"ClickableViewAccessibility", "AppCompatCustomView"})
public class LongCickButton extends Button {
    private boolean clickdown = false;
    private LongTouchListener mListener;
    private int mtime;

    public LongCickButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            //clickdown = true;

        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            clickdown = false;
        }
        return super.onTouchEvent(event);
    }

    public void setStart() {
        clickdown = true;
        new LongTouchTask().execute();
        System.out.println("BUG setStart clickdown=" + clickdown);
    }

    private void sleep(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    class LongTouchTask extends AsyncTask<Void, Integer, Void> {

        @SuppressLint("WrongThread")
        @Override
        protected Void doInBackground(Void... params) {
            while (clickdown) {
                sleep(mtime);
                publishProgress(0);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {

        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            mListener.onLongTouch();
        }

    }

    public void setOnLongTouchListener(LongTouchListener listener, int time) {
        mListener = listener;
        mtime = time;

    }

    public interface LongTouchListener {
        void onLongTouch();
    }

}

6.attr:文件,在values目錄下,新建attr文件

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="mhsb_seekbar">
        <attr name="android:thumb" />
        <attr name="mhs_numtext_size" format="dimension" />
        <attr name="mhs_numtext_color" format="color" />
        <attr name="mhs_progress_width" format="dimension" />
        <attr name="mhs_progress_bar_round" format="dimension" />
        <attr name="mhs_progress_background_color" format="color" />
        <attr name="mhs_progress_color" format="color" />
        <attr name="mhs_progress_max" format="integer" />
    </declare-styleable>
</resources>

end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章