美文网首页
自定义View——成长值、积分进度条

自定义View——成长值、积分进度条

作者: 烂吹笙 | 来源:发表于2017-10-25 12:51 被阅读0次
    产品需求中难免有一些不符合常理的设计!!!今天来设计针对一个会员,积分系统,设计一个水平的进度条,首先看图说话 image

    看出图中会员等级分为4级,每一级的长度均分4个实心的点,分为四个区间,每个区间中设置均分的进度,所以用普通的ProgressBar、SeekBar是无法实现的,所以必须自定义View,使用画笔画。

    1、画线

    我的思路就是先画一条灰色的虚线,让后,画四个点,根据传入的当前的成长值,计算出在哪个区间,进而绘画出红色的线,并且设置实心的红点的点

    package com.wj.progressbardemo;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.View;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 成长值进度条
     */
    
    public class GrowthValueProgress extends View {
    
        private MyCallback callback;
    
        private Context context;
    
        private int currentValues = 1100;//当前成长值
    
        private int v0Values = 0;//v0会员成长值
    
        private int v1Values = 100;//v1会员成长值
    
        private int v2Values = 10000;//v2会员成长值
    
        private int v3Values = 40000;//v3会员成长值
    
        private int v4Values = 80000;//v4会员成长值
    
        private Paint paint;//会员画笔
    
        private Paint grayPaint;
    
        private Paint pointPaint1;
    
        private Paint pointPaint2;
    
        private Paint pointPaint3;
    
        private Paint pointPaint4;
    
        private int lineHeight = 8;//线的高度
    
        private int pointSize = 8;//圆心的半径
    
        private int offsetX = 0;//x的坐标;
    
        private int width;
    
        private int hight;
    
        private List<Paint> paintList;
    
        public GrowthValueProgress(Context context) {
            super(context);
            this.context = context;
            initPaint();
        }
    
        public GrowthValueProgress(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
            initPaint();
        }
    
        public GrowthValueProgress(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.context = context;
            initPaint();
        }
    
        public int getCurrentValues() {
            return currentValues;
        }
    
        public void setCurrentValues(int currentValues) {
            this.currentValues = currentValues;
        }
    
        private void initPaint() {
    
            lineHeight=hight/2;//线的高度设置为布局的一半高度
            pointSize=hight/2;//圆点的半径设置为布局的一半高度
    
            grayPaint = new Paint();
            grayPaint.setColor(Color.GRAY);
            grayPaint.setStrokeWidth(lineHeight);
            grayPaint.setAntiAlias(true);
            grayPaint.setTextAlign(Paint.Align.CENTER);
            grayPaint.setStyle(Paint.Style.STROKE);
    
            paint = new Paint();
            paint.setColor(Color.RED);
            paint.setStrokeWidth(lineHeight);
            paint.setAntiAlias(true);
            paint.setTextAlign(Paint.Align.CENTER);
            paint.setStyle(Paint.Style.STROKE);
    
    
            pointPaint1 = new Paint();
            pointPaint2 = new Paint();
            pointPaint3 = new Paint();
            pointPaint4 = new Paint();
    
            paintList=new ArrayList<>();
            paintList.add(pointPaint1);
            paintList.add(pointPaint2);
            paintList.add(pointPaint3);
            paintList.add(pointPaint4);
    
            for (int i = 0; i < paintList.size(); i++) {
                Paint mPaint = paintList.get(i);
                mPaint.setStrokeWidth(10);
                mPaint.setAntiAlias(true);
                mPaint.setStyle(Paint.Style.FILL);
                mPaint.setTextAlign(Paint.Align.CENTER);
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            int lineLength = width / 5;
    
            //绘制底部长灰线
            canvas.drawLine(0, lineHeight, width, lineHeight, grayPaint);
    
            drawProgress(canvas, lineLength);
        }
    
    
        /**
         * 画进度
         *
         * @param canvas
         * @param lineLength 每个区间的平均长度
         */
        private void drawProgress(Canvas canvas, int lineLength) {
    
            //在V0~V1区间内
            if (currentValues >= v0Values && currentValues < v1Values) {
                int stopX = currentValues * lineLength / (v1Values - v0Values);
                //x起始位置,y起始位置,x停止位置,y停止位置
                offsetX = stopX;
                pointPaint1.setColor(Color.RED);
                pointPaint2.setColor(Color.GRAY);
                pointPaint3.setColor(Color.GRAY);
                pointPaint4.setColor(Color.GRAY);
            } else if (currentValues >= v1Values && currentValues < v2Values) {
                //在V1~V2区间内
                int stopX = (currentValues - v1Values) * lineLength / (v2Values - v1Values);
                offsetX = lineLength * 1 + stopX;
                pointPaint1.setColor(Color.RED);
                pointPaint2.setColor(Color.GRAY);
                pointPaint3.setColor(Color.GRAY);
                pointPaint4.setColor(Color.GRAY);
            } else if (currentValues >= v2Values && currentValues < v3Values) {
                //在V2~V3区间内
                int stopX = (currentValues - v2Values) * lineLength / (v3Values - v2Values);
                offsetX = lineLength * 2 + stopX;
                pointPaint1.setColor(Color.RED);
                pointPaint2.setColor(Color.RED);
                pointPaint3.setColor(Color.GRAY);
                pointPaint4.setColor(Color.GRAY);
            } else if (currentValues >= 00 && currentValues <= v4Values) {
                //在V3~V4区间内
                int stopX = (currentValues - v3Values) * lineLength / (v4Values - v3Values);
                offsetX = lineLength * 3 + stopX;
                pointPaint1.setColor(Color.RED);
                pointPaint2.setColor(Color.RED);
                pointPaint3.setColor(Color.RED);
                pointPaint4.setColor(Color.GRAY);
            } else if (currentValues > v4Values) {
                int stopX = 10;//超过8万使用固定值
                offsetX = lineLength * 4 + stopX;
                pointPaint1.setColor(Color.RED);
                pointPaint2.setColor(Color.RED);
                pointPaint3.setColor(Color.RED);
                pointPaint4.setColor(Color.RED);
            }
    
            canvas.drawLine(0, lineHeight, offsetX, lineHeight, paint);
    
    
            //圆心的XY坐标,圆心半径
            canvas.drawCircle(1 * lineLength - pointSize, pointSize, pointSize, pointPaint1);
            canvas.drawCircle(2 * lineLength - pointSize, pointSize, pointSize, pointPaint2);
            canvas.drawCircle(3 * lineLength - pointSize, pointSize, pointSize, pointPaint3);
            canvas.drawCircle(4 * lineLength - pointSize, pointSize, pointSize, pointPaint4);
    
            if (callback != null) {
                callback.callBack(offsetX,currentValues);
            }
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            width = this.getMeasuredWidth();
            hight = this.getMeasuredHeight();
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
        }
    
        public void getOffsetX(MyCallback callback){
            this.callback=callback;
        }
    
        public interface MyCallback {
            public void callBack(int offsetX,int currentValues);
        }
    
    }
    
    

    2、布局代码

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:id="@+id/ll_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="100dp"
            android:orientation="vertical">
        </LinearLayout>
    
        <com.wj.progressbardemo.GrowthValueProgress
            android:id="@+id/progress"
            android:layout_marginTop="3dp"
            android:layout_width="match_parent"
            android:layout_height="6dp" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.5" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="V1会员\n100" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="V2会员\n10000" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="V3会员\n40000" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="V4会员\n80000" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.5" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp">
    
            <EditText
                android:id="@+id/et_text"
                android:layout_width="100dp"
                android:layout_height="40dp" />
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="btnSetValues"
                android:text="设置" />
    
        </LinearLayout>
    </LinearLayout>
    
    

    ok,那么就有疑问了,线条上面的黑色会话框,是该怎么搞呢,我的想法是在View之外搞,根据接口回调,我能知道我的红色的线有多长,也就相当于我知道我的黑色会话框距离左边多远

    3、设置黑色会话框

    package com.wj.progressbardemo;
    
    import android.graphics.Color;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
        private int values=100;
        private EditText et_text;
        private GrowthValueProgress progress;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            progress = (GrowthValueProgress) findViewById(R.id.progress);
            final LinearLayout ll_content= (LinearLayout) findViewById(R.id.ll_content);
            et_text = (EditText) findViewById(R.id.et_text);
    
            progress.setCurrentValues(values);
    
            progress.getOffsetX(new GrowthValueProgress.MyCallback() {
                @Override
                public void callBack(int offsetX,int currentValues) {
                    TextView tv=new TextView(MainActivity.this);
                    tv.setBackgroundResource(R.drawable.ic_growth_values);
                    if (currentValues>80000){
                        tv.setText(8+"万+成长值");
                    }else{
                        tv.setText(currentValues+"成长值");
                    }
                    tv.setTextColor(Color.WHITE);
                    tv.setTextSize(10);
                    tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
                    ll_content.removeAllViews();
                    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tv.getLayoutParams();
                    params.setMargins(offsetX,0,0,0);
                    ll_content.addView(tv);
                }
            });
        }
    
        public void btnSetValues(View view) {
            String trim = et_text.getText().toString().trim();
            progress.setCurrentValues(Integer.parseInt(trim));
            progress.invalidate();
        }
    }
    
    
    看看结果: image

    相关文章

      网友评论

          本文标题:自定义View——成长值、积分进度条

          本文链接:https://www.haomeiwen.com/subject/verqpxtx.html