等级进度条android_支付宝 等级进度条 android - CSDN
  • 写一个等级条view效果如下:

    写一个等级条view效果如下:



    前言:对于熟悉自定义view的同学来说,这个效果实在是太简单了。自己写的时候发现,在写之前一定要事先把各个测量点,绘制的点计算方法想好,不然还是要调试一番才能完善,当然我这个肯定还不够完善,勉强看的过去了。


    用到知识点:

    1、view测量

    2、shader

    3、属性动画

    重点:等级划分的时候,每个等级有一个开始点和结束点,比如0-50,50-200;在这个效果中,每个等级的宽度是一样的,所以比如100的时候,它的宽度就是,一分宽度,加(100-50)/(200-50)*一个等级宽度,有了这个思维之后其他都是小问题了。


    1、测量高度,宽度不用测量了,因为你定义view的时候肯定会告诉我一个固定的宽度吧(mathparent也是一个精确宽度)

    这个如果要写自定义view需要先定义字体大小,图片大小,进度条宽度等等,为了方便直接用变量写死,想要支撑自定义属性的时候直接取出来赋值就可以了。这里偷懒跳过。。。

    首先拿到图片的宽高和字体的高度

      public void getLevelImgWH() {
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(getResources(), levelimgs_gray[0], opts);
            this.levelImgWidth = opts.outWidth;
            this.levelImgHeight = opts.outHeight;
            Log.i(Tag, "levelImgWidth:" + levelImgWidth + ",levelImgHeight:" + levelImgHeight);
    
        }

    再写个方法计算字符串的宽高

      public Rect getTextWH(String text, int textSize) {
            Paint pFont = new Paint();
            Rect rect = new Rect();
            pFont.setTextSize(textSize);
            pFont.getTextBounds(text, 0, text.length(), rect);
            return rect;
        }

    这样我们再规定好,进度条和字符串的间隔

        //图片等级与线条的间距
        private int padding_img = 20;
        //线条与上面文字的间距
        private int padding_text = 20;

    由于我们的进度条首尾是有弧度的,我们绘制的时候,进不能从0到最后的,这样弧度效果就没了。。。

    于是由于规定死了进度条的宽度为20.那么我就指定笔触的宽度为10,这个在进度条的首尾留出笔触的宽度,就可以看到弧度效果了。

        private int cap = 10;//笔触宽度
        private int lineWidth = 20;//进度条宽度

    基本上所有的高度都有了,现在设置控件的高度

     @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int height = getPaddingTop() + getPaddingBottom() + lineWidth + padding_img + levelImgHeight + 20 + textHeight + padding_text;
            setMeasuredDimension(getMeasuredWidth(), height);
        }

    2、绘制

          先绘制没有设置进度值的时候,默认六个都是灰色的图片,当我们有等级值的时候,我们就要根据等级,计算出下面的等级图片,很简单,哪一个数组来存放这些图片,每次设置等级值的时候都重新计算,就可以达到动态显示效果了。

    首先根据等级值,计算等级,并且计算它实际应该有多宽

       //根据当前值,按照比例,计算它该有的长度,每个刻度的长度一样,但是每个刻度的差值不一样,
        //这里就根据比例来计算
        public int getCurrentDialLength() {
    
            getDialAllLength();
            if (allLength > 0 && datas.size() > 0 && currentDialvalue > 0) {
                int pre = allLength / (datas.size());
                for (int i = 0; i < datas.size(); i++) {
                    UserLevelDial dial = datas.get(i);
                    if (currentDialvalue <= dial.dial_e && currentDialvalue >= dial.dial_s) {
                        this.currentImg = i;
                        cDialLenth = pre * i + (int) (pre * ((currentDialvalue - dial.dial_s) / ((float) dial.dial_e - dial.dial_s)));
                        Log.i(Tag, "i:" + i);
                        break;
                    }
                }
            }
            if (currentDialvalue > datas.get(datas.size() - 1).dial_e) {
                this.currentImg = datas.size();
                cDialLenth = allLength;
            }
            Log.i(Tag, "cDialLenth:" + cDialLenth);
            //重新设置等级图片
            setLevelImgs();
            return cDialLenth;
        }

    然后根据等级,设置下面的等级图片

        private int[] levelimgs_gray = {R.drawable.grade_v1, R.drawable.grade_v2, R.drawable.grade_v3,
                R.drawable.grade_v4, R.drawable.grade_v5, R.drawable.grade_v6};
        private int[] levelimgs_light = {R.drawable.grade_v1_arrive, R.drawable.grade_v2_arrive, R.drawable.grade_v3_arrive,
                R.drawable.grade_v4_arrive, R.drawable.grade_v5_arrive, R.drawable.grade_v6_arrive};
        private ArrayList<Bitmap> bitmap_levelimgs_gray = new ArrayList<Bitmap>();
        private ArrayList<Bitmap> bitmap_levelimgs_light = new ArrayList<Bitmap>();
        private ArrayList<Bitmap> bitmap_levelimgs_show = new ArrayList<Bitmap>();

      public void setLevelImgs() {
            bitmap_levelimgs_show.clear();
            for (int i = 0; i < bitmap_levelimgs_gray.size(); i++) {
                if (i <= currentImg) {
                    bitmap_levelimgs_show.add(bitmap_levelimgs_light.get(i));
                } else {
                    bitmap_levelimgs_show.add(bitmap_levelimgs_gray.get(i));
                }
            }
        }

    接着,绘制

      @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);//利用父类去绘制背景
    //        clearScr(canvas);
    
            if (cDialLenth > 0) {//cDialLenth当前等级的刻度的长度,大于0才绘制上门的文字x/1500 
                //绘制文字
                Rect rect = getTextWH(currentDialvalue + "", textSize);
                Rect rect2 = getTextWH("/" + maxValue, textSize);
                int text_pw = cDialLenth < rect.width() ? 0 : cDialLenth - rect.width();
                text_pw += getPaddingLeft();
                //修正边界
                int maxw = allLength - rect.width() - rect2.width() + cap * 2 + getPaddingLeft() - 5;
                text_pw = text_pw > maxw ? maxw : text_pw;
                Log.i(Tag, "textgetPaddingTop:" + getPaddingTop());
                int text_ph = getPaddingTop() +rect.height();
                String v_str = String.valueOf(currentDialvalue);
                canvas.drawText(v_str, text_pw, text_ph, paint_text_value);
                int text_pw2 = text_pw + rect.width() + 5;
                canvas.drawText("/" + maxValue, text_pw2, text_ph, paint_text_total);
            }
            int bgline_ph = lineWidth / 2 + 1 + getPaddingTop() + textHeight + padding_text;
            canvas.drawLine(getPaddingLeft() + cap, bgline_ph, getMeasuredWidth() - getPaddingRight() - cap, bgline_ph, paint_bg);
            linearGradient = new LinearGradient(getPaddingLeft(), 0, cDialLenth, 0, new int[]{getResources().getColor(R.color.userlevels1), getResources().getColor(R.color.userlevels2)}, null, LinearGradient.TileMode.CLAMP);
            paint_first.setShader(linearGradient);
    
            canvas.drawLine(getPaddingLeft() + cap, bgline_ph, cDialLenth + getPaddingLeft() + cap, bgline_ph, paint_first);
            drawLevel(canvas);
        }

    最后,来一个值动画,从0变到等级值,就ok了。

    /**
         * 设置当前刻度
         */
        public void setCurrentDialvalue(int dial) {
            if (null != valueAnimator && valueAnimator.isRunning()) {
                valueAnimator.cancel();
            }
            valueAnimator = ValueAnimator.ofInt(0, dial);
    
            valueAnimator.setDuration(dial > 500 ? 2000 : 1000);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    currentDialvalue = (int) valueAnimator.getAnimatedValue();
                    getCurrentDialLength();
                    invalidate();
                }
            });
            valueAnimator.start();
    
    
        }



    源码下载



    展开全文
  • 最近看见有个博主写的等级进度条不从,自己改进下 ,希望提提意见 1.自定义LeveIDemo 继承RelativeLayout package com.leveldemo; import android.annotation.TargetApi; import android.content.Context; ...

    最近看见有个博主写的等级进度条不从,自己改进下 ,希望提提意见

    1.自定义LeveIDemo 继承RelativeLayout

    package com.leveldemo;
    
    
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.os.Build;
    import android.util.AttributeSet;
    import android.util.SparseArray;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewTreeObserver;
    import android.widget.HorizontalScrollView;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.List;
    
    public class LeveIDemo extends RelativeLayout {
        //横向seekbar的容器
        public HorizontalScrollView horizontalScrollView;
        public LinearLayout contentLl;
        //经验值悬浮窗
        public TextView expTv;
        //当前等级的百分比
        public double percent;
        private String string;
        //横向seekbar的宽度
    
        public double getPercent() {
            return percent;
        }
    
        public void setPercent(double percent) {
            this.percent = percent;
        }
    
        public int width;
        //底色白线
        public View whiteLine;
        //经验红线
        private View redLine;
        private SparseArray<ImageView> imageViews;
        private SparseArray<TextView> textviews;
        private List<SimpleLevelModel> simpleLevelModelList;
    
        private int myLevel = 0;
        private Context context1;
        public int MDR = 9;
    
    
        public LeveIDemo(Context context) {
    
            super(context);
            this.context1 = context;
        }
    
        public LeveIDemo(Context context, AttributeSet attrs) {
    
            super(context, attrs);
            this.context1 = context;
    
            initView(context, attrs);
            initData();
        }
    
        public int getMyLevel() {
            return myLevel;
        }
    
        public void setMyLevel(int myLevel) {
            this.myLevel = myLevel;
        }
    
        public int getMDR() {
            return MDR;
        }
    
        public void setMDR(int MDR) {
            this.MDR = MDR;
        }
    
        private void initView(Context context, AttributeSet attrs) {
            // 加载布局
            LayoutInflater.from(context).inflate(R.layout.leve_id_view, this);
    
            horizontalScrollView = findViewById(R.id.scrollview_level);
            contentLl = findViewById(R.id.ll_content_img);
            expTv = findViewById(R.id.tv_exp);
            redLine = findViewById(R.id.red_line);
            whiteLine = findViewById(R.id.white_line);
    
    
    
    
            simpleLevelModelList = new ArrayList<>();
            for (int i = 0; i < MDR; i++) {
                SimpleLevelModel moel = new SimpleLevelModel();
                moel.setLevelId(i + 1);
                simpleLevelModelList.add(moel);
            }
    
        }
    
    
        private void initData() {
            if (imageViews == null) {
                imageViews = new SparseArray<>();
            }
            if (textviews == null) {
                textviews = new SparseArray<>();
            }
            for (int i = 0; i < simpleLevelModelList.size(); i++) {
                if (i != simpleLevelModelList.size() - 1) {
                    contentLl.addView(getRadioView(i, false), i);
                } else {
                    contentLl.addView(getRadioView(i, true), i);
                }
            }
            contentLl.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                @Override
                public void onGlobalLayout() {
                    width = contentLl.getWidth();
                    contentLl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    setDefault(myLevel);
                }
            });
    
        }
    
    
        private View getRadioView(final int i, boolean isLast) {
            View view = null;
            if (!isLast) {
                view = LayoutInflater.from(context1).inflate(R.layout.item_lv_tagpoint, contentLl, false);
                ImageView imageview = (ImageView) view.findViewById(R.id.image);
                TextView textview = (TextView) view.findViewById(R.id.tv_level_seekbar);
                textview.setText("LV" + simpleLevelModelList.get(i).getLevelId());
                imageViews.put(i, imageview);
                textviews.put(i, textview);
            } else {
                view = LayoutInflater.from(context1).inflate(R.layout.item_lv_lastpoint, contentLl, false);
                ImageView imageview = (ImageView) view.findViewById(R.id.image);
                TextView textview = (TextView) view.findViewById(R.id.tv_level_seekbar);
                textview.setText("LV" + simpleLevelModelList.get(i).getLevelId());
                imageViews.put(i, imageview);
                textviews.put(i, textview);
    
            }
            return view;
        }
    
        public void setDefault(int level) {
            for (int i = 0; i < imageViews.size(); i++) {
                if (i < level) {
                    imageViews.get(i).setImageResource(R.drawable.level_red_point);
                } else {
                    imageViews.get(i).setImageResource(R.drawable.level_white_point);
                }
            }
    
    //
            //进度底色
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) whiteLine.getLayoutParams();
            lp.width = (simpleLevelModelList.size() - 1) * DensityUtils.dp2px(context1.getApplicationContext(), 100F);
            lp.setMargins(DensityUtils.dp2px(context1.getApplicationContext(), 50F), 0, 0, 0);
    //
            whiteLine.setLayoutParams(lp);
    
            RelativeLayout.LayoutParams lp1 = (RelativeLayout.LayoutParams) redLine.getLayoutParams();
            lp1.width = (myLevel - 1) * DensityUtils.dp2px(context1.getApplicationContext(), 100F) + (int)
                    (percent * DensityUtils.dp2px(context1.getApplicationContext(), 100F));
            lp1.setMargins(DensityUtils.dp2px(context1.getApplicationContext(), 50F), 0, 0, 0);
            redLine.setLayoutParams(lp1);
            horizontalScrollView.scrollTo(lp1.width, 0);
    
            RelativeLayout.LayoutParams lp2 = (RelativeLayout.LayoutParams) expTv.getLayoutParams();
            //偏移时需要加悬浮窗宽度+point的宽度
            lp2.setMargins(lp1.width + DensityUtils.dp2px(context1.getApplicationContext(), 50F) - expTv.getWidth() / 2, 0, 0, DensityUtils.dp2px(context1.getApplicationContext(), 10F));
            expTv.setLayoutParams(lp2);
    
        }
    }
    

    2新建实体类

    package com.leveldemo;
    
    /**
     * Created by clear on 2017/5/10.
     */
    public class SimpleLevelModel {
    
        private int levelId;
        private int minExp;
    
        public int getLevelId() {
            return levelId;
        }
    
        public void setLevelId(int levelId) {
            this.levelId = levelId;
        }
    
        public int getMinExp() {
            return minExp;
        }
    
        public void setMinExp(int minExp) {
            this.minExp = minExp;
        }
    }
    

    3.工具类

    package com.leveldemo;
    
    import android.content.Context;
    import android.util.TypedValue;
    
    /**
     * Created by Administrator on 2017/5/9 0009.
     */
    
    public class DensityUtils {
    
         private DensityUtils(){
              /* cannot be instantiated */
             throw new UnsupportedOperationException("cannot be instantiated");
         }
         /**
           * dp 转 px
           *
           * @param context
           * @param
           * @return
           */
         public static int dp2px(Context context, float dpVal) {
             return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                        dpVal, context.getResources().getDisplayMetrics());
         }
    
        /**
         * sp转px
         * @param context
         * @param spVal
         * @return
         */
             public static int sp2px(Context context, float spVal) {
                 return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                      spVal, context.getResources().getDisplayMetrics());
             }
    
        /**
         * px转dp
         * @param context
         * @param pxVal
         * @return
         */
        public static float px2dp(Context context, float pxVal) {
             final float scale = context.getResources().getDisplayMetrics().density;
             return (pxVal / scale);
        }
    
        /**
         * px转sp
         * @param context
         * @param pxVal
         * @return
         */
         public static float px2sp(Context context, float pxVal) {
             return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
         }
    }
    

    3.在activity_main,的布局

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
    
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    
        android:background="#356485"
        android:gravity="center_vertical"
        android:orientation="vertical">
    
        <com.leveldemo.LeveIDemo
    
            android:id="@+id/id_le"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
      
    
    </FrameLayout>
    

    4.在MainActivity的设置

    package com.leveldemo;
    
    import android.annotation.TargetApi;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.SparseArray;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewTreeObserver;
    import android.widget.HorizontalScrollView;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            LeveIDemo leveIDemo = (LeveIDemo) findViewById(R.id.id_le);
    //
            leveIDemo.setMyLevel(2);//等级
    
            leveIDemo.expTv.setText("22289万元");//目前等级的数据
            leveIDemo.setPercent(0.23);//目前等级的百分比
        }
    
    
    }
    

    5.效果图;


     

    展开全文
  • Android等级进度条demo

    2020-07-30 23:32:11
    Android自定义view--等级进度条demo
  • 核心部分 ProgressLineView package ... import android.content.Context;...import android.graphics.Bitmap;...import android.graphics.BitmapFactory;...import android.graphics.Canvas...
    此篇应该算一个基础的自定义控件入门,内部没有去写自定义属性 ~

    目录

    • 实现效果
    • 了解部分
    • 核心部分
    • 使用部分

    实现效果

    在这里插入图片描述

    了解部分

    1. 创建画笔
    	Paint  paint = new Paint();
    
    1. 画笔颜色
        paint.setColor(Color.parseColor("#FFFFFF"));
    
    1. 设置画笔样式,如果不设置,默认是全部填充(FILL)
       paint.setStyle(Paint.Style.FILL);
    
    画笔样式分三种
    • Paint.Style.STROKE:描边

    • Paint.Style.FILL_AND_STROKE:描边并填充

    • Paint.Style.FILL:填充

    4.打开抗锯齿;抗锯齿是依赖于算法的,算法决定抗锯齿的效率,在我们绘制棱角分明的图像时,比如一个矩形、一张位图,我们不需要打开抗锯齿

     paint.setAntiAlias(true);
    

    5.设置笔刷的粗细度

       int linePaintStroke = dp2px(context, 3);
       paint.setStrokeWidth(linePaintStroke);
    

    核心部分

    ProgressLineView
    package com.advance.yongliu.customlineview;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.View;
    
    /**
     * @author YongLiu
     *         date  2019/1/6.
     *         desc:
     */
    
    public class ProgressLineView extends View {
        private Paint paint;
        private int viewWidth;
        private int viewHeight;
        private Paint behindPaint;
        private Paint textPaint;
        private float mPresent;
        private String growthValue = "成长值";
        private String current = "目前";
    
        public ProgressLineView(Context context) {
            super(context);
            init(context);
        }
    
        public ProgressLineView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        public ProgressLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context);
        }
    
        private void init(Context context) {
            /**
             * 顶部画笔配置
             * */
            paint = new Paint();
            paint.setColor(Color.parseColor("#FFFFFF"));
            paint.setStyle(Paint.Style.FILL);
            paint.setAntiAlias(true);
            int linePaintStroke = dp2px(context, 3);
            paint.setStrokeWidth(linePaintStroke);
    
            /**
             * 底部画笔配置
             * */
            behindPaint = new Paint();
            behindPaint.setColor(Color.parseColor("#33000000"));
            behindPaint.setStyle(Paint.Style.FILL);
            behindPaint.setAntiAlias(true);
            int linePaintStroke1 = dp2px(context, 3);
            behindPaint.setStrokeWidth(linePaintStroke1);
    
            /**
             * 控件文字画笔配置
             * */
            textPaint = new Paint();
            textPaint.setColor(Color.parseColor("#FFFFFF"));
            textPaint.setStyle(Paint.Style.FILL);
            textPaint.setTextSize(16);
            textPaint.setAntiAlias(true);
            int linePaintStroke2 = dp2px(context, 50);
            textPaint.setStrokeWidth(linePaintStroke2);
        }
    
        /**
         * 设值 - 绘制
         * */
        public void setPresent(float present, String growthValue) {
            this.growthValue = growthValue;
            //动画效果,不适合此处控件
        /*    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, present).setDuration(2000);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mPresent = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            valueAnimator.start();*/
            mPresent = present;
            //绘制
            invalidate();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            /**
             * 获取我们控件的宽、高
             * */
            viewWidth = MeasureSpec.getSize(widthMeasureSpec);
            viewHeight = MeasureSpec.getSize(heightMeasureSpec);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            
            /**
    		 * 设置图片,并获取图片宽高  (俩图自行找UI获取)
    		 * @params bigBitmap  进度大圆点
    		 * @params smallBitmap 首尾小圆点
    		 */
            Bitmap bigBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_big_whirte_dot);
            int bitmapWidth = bigBitmap.getWidth();
            int bitmapHeight = bigBitmap.getHeight();
            Bitmap smallBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_small_white_dot);
            int smallWidth = bigBitmap.getWidth();
            int smallHeight = bigBitmap.getHeight();
    
            //字体宽高
            float text1Width = textPaint.measureText(current);
            float text2Width = textPaint.measureText(growthValue);
            Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
            float textHeight = fontMetrics.bottom - fontMetrics.top;
    
           /**
            * @params mPresent 进度百分比
            * @params stopLine 上层线条展示的区域长度
            * */
            float stopLine = viewWidth * mPresent;
            if (stopLine == 0) {
                stopLine = smallWidth / 2;
            }
            if (mPresent >= 0.95) {
                stopLine = viewWidth - (smallWidth + 20);
            }
    
            /**
             * 文字间距配置
             * */
            float text1Start = stopLine - text1Width / 2 > 0 ? stopLine - text1Width : 0;
            float text2Start = stopLine - text2Width / 2 > 0 ? stopLine - text2Width : 0;
            if (text1Start <= 0) {
                text1Start = 15;
            }
            if (text2Start <= 0) {
                text2Start = 15;
            }
    
            if (mPresent != 1) {
                if (text1Start == 15 || text2Start == 15) {
                    canvas.drawText(current, text1Start, viewHeight / 2 - textHeight, textPaint);
                    canvas.drawText(growthValue, text2Start, viewHeight / 2, textPaint);
                } else {
                    canvas.drawText(current, text1Start + smallWidth / 2 + 10, viewHeight / 2 - textHeight, textPaint);
                    canvas.drawText(growthValue, text2Start + smallWidth + 10, viewHeight / 2, textPaint);
                }
            } else {
                canvas.drawText(current, viewWidth - text1Width, viewHeight / 2 - textHeight, textPaint);
                canvas.drawText(growthValue, viewWidth - text2Width, viewHeight / 2, textPaint);
            }
    
            /**
             * 进行绘制!!!   俩条线、首位俩个圆点、一个进度点
             * */
            canvas.drawLine(10, viewHeight / 2 + 40, viewWidth - 10, viewHeight / 2 + 40, behindPaint);
            canvas.drawLine(10 , viewHeight / 2 + 40, stopLine, viewHeight / 2 + 40, paint);
            canvas.drawBitmap(bigBitmap, stopLine, viewHeight / 2 - bitmapHeight / 2 + 40, null);
            canvas.drawBitmap(smallBitmap, 0, viewHeight / 2 - smallHeight / 2 + 42, null);
            canvas.drawBitmap(smallBitmap, viewWidth - smallWidth, viewHeight / 2 - smallHeight / 2 + 42, null);
        }
    
    
        private int dp2px(Context context, float dpValue) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    }
    
    

    使用部分

    MainActivity
    package com.advance.yongliu.customlineview;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ProgressLineView mLineView = findViewById(R.id.line_progress_view);
            TextView mCurrent = findViewById(R.id.tv_current);
            TextView mLast = findViewById(R.id.tv_last);
    
            /**
             * 传入自定义控件的数据,此处先行设置模拟值(这里一般都是接口返回处理我们进行组装)
             * @params currentData 当前成长值  用于文字显示区域
             * @params newCurrent  此处有公式 newCurrent =  currentData - 上一等级值 ; 因此处上一等级值为0 故直接设置
             * @params newNestData 下一等级值
             * */
            float currentData = Float.parseFloat("20");
            float newCurrent = 20;
            float newNestData = 100;
            mLineView.setPresent(newCurrent / newNestData, "成长值" + Float.valueOf(currentData).intValue());
    
            mCurrent.setText(String.format("青铜等级:%d", 0));
            mLast.setText(String.format("白银等级:%s", 100));
    
            /**
             * 参考代码 :目前项目中使用的
             * @params lastLevelValue 上个等级
             * @params nextLevelValue 下个个等级
             *
             * float lastData = Float.parseFloat(lastLevelValue);
             * float nestData = Float.parseFloat(nextLevelValue);
             *
             * float newCurrent = currentData - lastData;
             * float newNestData = nestData - lastData;
             * */
        }
    }
    
    
    MainActivity xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f00"
        android:orientation="vertical"
        tools:context="com.advance.yongliu.customlineview.MainActivity">
    
        <com.advance.yongliu.customlineview.ProgressLineView
            android:id="@+id/line_progress_view"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="20dp"
            />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/tv_current"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="5dp"
                android:text="当前等级"
                android:textColor="#fff"
                android:textSize="11sp"
                />
    
            <TextView
                android:id="@+id/tv_last"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_marginRight="5dp"
                android:layout_marginTop="5dp"
                android:text="下一等级"
                android:textColor="#fff"
                android:textSize="11sp"
                />
        </RelativeLayout>
    </LinearLayout>
    
    展开全文
  • 现在很多APP的会员进度条等级、积分进度条都是按分段显示的,由于最近自己的项目也用到类似的控件,如下图所示,于是就自己撸了一个! package progressandanimation.wtt.com.myapplication; import android...

    现在很多APP的会员进度条、等级、积分进度条都是按分段显示的,由于最近自己的项目也用到类似的控件,如下图所示,于是就自己撸了一个!

    package progressandanimation.wtt.com.myapplication;
    
    
    import android.animation.ValueAnimator;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    
    /**
     * Date:2018/11/27
     * Author:WangTingting
     * 说明:自定义信用等级
     */
    public class MyProgressView extends View {
    
        private Paint mCircleOutPaint;
        private Paint mCircleInPaint;
        private Paint mLinePaint;
    
        private Paint mDefaltCircleOutPaint;
        private Paint mDefaltCircleInPaint;
        private Paint mDefaltLinePaint;
    
        private Paint mTvPaint;
        private int circleOutRadius = 16;
        private int circleInRadius = 8;
        private int margin = 60; //左右margin
    
        private float mProgress;
        private ValueAnimator animation;
    
        public MyProgressView(Context context) {
            super(context);
            initView();
        }
    
        public MyProgressView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView();
        }
    
        public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView();
        }
    
        public void initView() {
            mCircleOutPaint = new Paint();
            mCircleOutPaint.setStyle(Paint.Style.FILL);
            mCircleOutPaint.setColor(Color.parseColor("#40A5FF"));
            mCircleOutPaint.setAntiAlias(true);
    
            mCircleInPaint = new Paint();
            mCircleInPaint.setStyle(Paint.Style.FILL);
            mCircleInPaint.setColor(Color.WHITE);
            mCircleInPaint.setAntiAlias(true);
    
            mLinePaint = new Paint();
            mLinePaint.setColor(Color.parseColor("#40A5FF"));
            mLinePaint.setStrokeWidth(8);
    
            mDefaltCircleOutPaint = new Paint();
            mDefaltCircleOutPaint.setStyle(Paint.Style.FILL);
            mDefaltCircleOutPaint.setColor(Color.parseColor("#858585"));
            mDefaltCircleOutPaint.setAntiAlias(true);
    
            mDefaltCircleInPaint = new Paint();
            mDefaltCircleInPaint.setStyle(Paint.Style.FILL);
            mDefaltCircleInPaint.setColor(Color.WHITE);
            mDefaltCircleInPaint.setAntiAlias(true);
    
            mDefaltLinePaint = new Paint();
            mDefaltLinePaint.setColor(Color.parseColor("#858585"));
            mDefaltLinePaint.setStrokeWidth(8);
    
            mTvPaint = new Paint();
            mTvPaint.setColor(Color.parseColor("#858585"));
            mTvPaint.setTextSize(sp2px(getContext(), 12));
        }
    
        public void setProgress(float progress) {
            if (animation == null) {
                animation = ValueAnimator.ofFloat(0f, Float.valueOf(progress));
            }
    
            if (progress > 0 && progress <= 400) {
                mLinePaint.setColor(getResources().getColor(R.color.ring1));
                mCircleOutPaint.setColor(getResources().getColor(R.color.ring1));
            } else if (progress > 400 && progress <= 700) {
                mLinePaint.setColor(getResources().getColor(R.color.ring2));
                mCircleOutPaint.setColor(getResources().getColor(R.color.ring2));
            } else if (progress > 700 && progress <= 900) {
                mLinePaint.setColor(getResources().getColor(R.color.ring3));
                mCircleOutPaint.setColor(getResources().getColor(R.color.ring3));
            } else if (progress > 900) {
                mLinePaint.setColor(getResources().getColor(R.color.ring4));
                mCircleOutPaint.setColor(getResources().getColor(R.color.ring4));
            }
    
            animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mProgress = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            animation.setDuration(3000);
            animation.start();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            getSuggestedMinimumWidth();
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            int height = getHeight();
            int width = getWidth();
            int realWidth = (width - 2 * margin - 8 * circleOutRadius) / 3;
    
            canvas.drawLine(margin + circleOutRadius * 2, height / 2, width - margin - circleOutRadius * 2, height / 2, mDefaltLinePaint);
    
            for (int i = 0; i < 4; i++) {
                canvas.drawCircle(margin + circleOutRadius * (i * 2 + 1) + realWidth * i, height / 2, circleOutRadius, mDefaltCircleOutPaint);
                canvas.drawCircle(margin + circleOutRadius * (i * 2 + 1) + realWidth * i, height / 2, circleInRadius, mDefaltCircleInPaint);
            }
    
            canvas.drawText("0", margin + circleOutRadius - getTextWidth("0"), height / 2 - 30, mTvPaint);
            canvas.drawText("400", margin + circleOutRadius * 3 + realWidth - getTextWidth("400"), height / 2 - 30, mTvPaint);
            canvas.drawText("700", margin + circleOutRadius * 5 + realWidth * 2 - getTextWidth("700"), height / 2 - 30, mTvPaint);
            canvas.drawText("900+", margin + circleOutRadius * 7 + realWidth * 3 - getTextWidth("900+"), height / 2 - 30, mTvPaint);
    
            canvas.drawText("低信用", margin + circleOutRadius - getTextWidth("低信用"), height / 2 + 50, mTvPaint);
            canvas.drawText("中信用", margin + circleOutRadius * 3 + realWidth - getTextWidth("中信用"), height / 2 + 50, mTvPaint);
            canvas.drawText("高信用", margin + circleOutRadius * 5 + realWidth * 2 - getTextWidth("高信用"), height / 2 + 50, mTvPaint);
            canvas.drawText("极高信用", margin + circleOutRadius * 7 + realWidth * 3 - getTextWidth("极高信用"), height / 2 + 50, mTvPaint);
    
            float ratio;
            float result = 0;
    
            if (mProgress > 0 && mProgress <= 400) {
                ratio = mProgress / 400;
                result = margin + circleOutRadius * 2 + (ratio * realWidth);
            } else if (mProgress > 400 && mProgress <= 700) {
                ratio = (mProgress - 400) / 300;
                result = margin + circleOutRadius * 4 + (ratio * realWidth) + realWidth;
            } else if (mProgress > 700 && mProgress <= 900) {
                ratio = (mProgress - 700) / 200;
                result = margin + circleOutRadius * 6 + realWidth * 2 + (ratio * realWidth);
            } else if (mProgress > 900) {
                result = margin + circleOutRadius * 8 + 3 * realWidth;
            }
            canvas.drawLine(margin + circleOutRadius, height / 2, result, height / 2, mLinePaint);
    
            if (mProgress <= 0) {
                return;
            }
            canvas.drawCircle(margin + circleOutRadius, height / 2, circleOutRadius, mCircleOutPaint);
            canvas.drawCircle(margin + circleOutRadius, height / 2, circleInRadius, mCircleInPaint);
            if (mProgress <= 400) {
                return;
            }
            canvas.drawCircle(margin + circleOutRadius * 3 + realWidth, height / 2, circleOutRadius, mCircleOutPaint);
            canvas.drawCircle(margin + circleOutRadius * 3 + realWidth, height / 2, circleInRadius, mCircleInPaint);
            if (mProgress <= 700) {
                return;
            }
            canvas.drawCircle(margin + circleOutRadius * 5 + realWidth * 2, height / 2, circleOutRadius, mCircleOutPaint);
            canvas.drawCircle(margin + circleOutRadius * 5 + realWidth * 2, height / 2, circleInRadius, mCircleInPaint);
            if (mProgress <= 900) {
                return;
            }
            canvas.drawCircle(margin + circleOutRadius * 7 + realWidth * 3, height / 2, circleOutRadius, mCircleOutPaint);
            canvas.drawCircle(margin + circleOutRadius * 7 + realWidth * 3, height / 2, circleInRadius, mCircleInPaint);
        }
    
        public float getTextWidth(String text) {
            return mTvPaint.measureText(text) / 2;
        }
    
        public static int sp2px(Context context, float spValue) {
            final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
            return (int) (spValue * fontScale + 0.5f);
        }
    }
    

    然后在Activity中这样写就实现了

    展开全文
  • Android进度条

    2020-01-16 17:16:52
    其中style属性设置进度条的样式:如上面设置的进度条为水平的进度条 若不设置默认为圆形进度条。 style="@android:style/Widget.ProgressBar.Small" 设置进度的大小如下截图 还有一种对话框进度条ProgressDialog 在...

    首页xml中代码:


    其中style属性设置进度条的样式:如上面设置的进度条为水平的进度条
    若不设置默认为圆形进度条。
    style="@android:style/Widget.ProgressBar.Small"
    设置进度的大小如下截图

    还有一种对话框进度条ProgressDialog
    在button监听事件里实现如下代码
    ProgressDialog progressDialog=new ProgressDialog(MainActivity.this);
    progressDialog.setTitle(“进度条对话框”);
    progressDialog.setMessage(“loading…”);
    progressDialog.setCancelable(true);
    progressDialog.show();

    这里需要注意的式setCancelable()里面设置true表示对话框可以按back键退出。而false表示不可以按back键退出。所以我们在实际项目中做好控制。数据加载完必须调用dismiss()方法

    关闭,否则它一直存在。

    展开全文
  • android进度条的实现

    2018-05-25 17:16:02
    package ... import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.ProgressBar; public cla...
  • h5实现等级进度条  需求如下: 实现一个动画进度条,页面一打开实现一个进度条动画,因为App这个页面会经常改,所以没有使用原审Android或者IOS来实现,希望通过H5来做;  服务器端返回如下数据: var Config...
  • ZzHorizontalProgressBarA Horizontal ProgressBar that is customized easily.功能简介: 1.支持自定义进度颜色; 2.支持自定义背景颜色; 3.支持自定义背景与进度之间的内间距大小; 4.支持自定义最大值和默认...
  • Android 进度条算法 更新进度条算法 long int
  • 一、简介  进度条是UI界面中一种非常实用的组件,退出用于向用户显示某个比较耗时间的操作完成的百分比。... Android支持几种风格的进度条,通过style属性可以为Progress指定风格。该属性可以支持如下几个属性值。
  • android中,提供了及进度
  • 一开始没什么思绪,因为系统自带的进度条,无论是seekbar还是progressbar都不能够满足需求,首先这个时候,我就会考虑自定义一个私人订制的进度条style,我们知道进度条有两种样式,即水平进度条(@android:style/...
  • 今天来设计针对一个会员,积分系统,设计一个水平的进度条,首先看图说话看出图中会员等级分为4级,每一级的长度均分4个实心的点,分为四个区间,每个区间中设置均分的进度,所以用普通的ProgressBar、SeekBar是无法...
  • Android更新进度条

    2015-08-26 08:58:14
    问题: Android是不允许子线程更新UI界面的,子线程更新界面会出现异常,然而下面的例子非常让人苦恼,‘子线程’更新UI界面,并且没有发生异常。 @Override public void onClick(View arg0) { Log.d(TAG, ...
  • Android原生控件只有横向进度条一种,而且没法变换样式,比如原生rom的样子 很丑是吧,当伟大的产品设计要求更换前背景,甚至纵向,甚至圆弧状的,咋办,比如 ok,我们开始吧:   一)变换前背景 先来看看...
  • 作为一个自学入门android的人来说,刚接触自定义view时完全处于懵逼状态,不过还好,大神们已经铺好了路,尔等只需稍加钻研即可小有成就的,废话不多说了,先上效果图! 理清下此view的思路: 1.此view由圆和文字...
  • 一、测试截图 二、实现原理     package com.freedomanlib; import java.util.Timer;...import android.annotation.SuppressLint;...import android.content.Context;...import android.graphics....
  • 做了一个用户等级进度条,只是练手。  本人对后台不是太了解,所以这里做成了用户自己输入参数的办法来模拟从后台读参数的过程。  演示: 用户等级 在线时间:本级所需时间:    ...
  • Android 水平无限期进度条,基于 animated-vector 简单易用,修改方便 仅适用于 Android Lollipop 5.0 API level 21 及以上 效果: 资源文件结构: 资源文件内容: res/animator/anim_apih_rect1_grp...
1 2 3 4 5 ... 20
收藏数 1,551
精华内容 620
关键字:

等级进度条android