• Android--自定义荷载进度的两种方法


    博客撰写人:It一zhai男 
    转载请标明地址:http://www.cnblogs.com/ityizhainan/p/5914487.html

    本文将用两个方法来写类似汽车荷载的进度

    1. 用LinearLayout的addview方法加上for循环
    2. 用自定义控件的方法

    先上截图

    1. 用LinearLayout的addview方法加上for循环

    1.1 processtest01.xml文件:

    <?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="horizontal" >
        <LinearLayout 
            android:id="@+id/ll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            
        </LinearLayout>
    
    </LinearLayout>

    1.2 LinearLayout的子布局view01.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
        <ImageView
            android:id="@+id/hezai_img"
            android:layout_width="12.5dp"
            android:layout_height="31.5dp"/>
    
    </LinearLayout>

    1.3 ProcessTest01.java

    package com.example.progresstest;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    
    public class ProcessTest01 extends Activity {
        private LinearLayout ll;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.processtest01);
            
            ll = (LinearLayout) findViewById(R.id.ll);
            
            setProcess(16);
            
        }
        
        private void setProcess(int green){
            LayoutInflater inflater = this.getLayoutInflater();
            //有进度就填充绿色图片
            for (int i = 0; i < green; i++) {
                View v = inflater.inflate(R.layout.view01, null);
                ImageView img = (ImageView) v.findViewById(R.id.hezai_img);
                img.setImageResource(R.drawable.green);
                ll.addView(v);
            }
            //没有进度就填充灰色图片
            for (int i = 0; i < 24-green; i++) {
                View v = inflater.inflate(R.layout.view01, null);
                ImageView img = (ImageView) v.findViewById(R.id.hezai_img);
                img.setImageResource(R.drawable.gray);
                ll.addView(v);
            }
        }
    }

    1.4 这里涉及了两个带边界的图片元素

    最后得到的截图

    这种方法有好处也有坏处。这种方法简单易懂,且耗内存少,运行速度快等,但若要不同的颜色,就要自己截不同大小,不同颜色的图片,并且还要左右带间距的,比较麻烦。下面的一种方法是自定义控件的方法,也是有好有坏。

    2 用自定义控件的方法

    2.1 myprocesstest.xml文件

    <?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" >
        <com.example.progresstest.HezaiProgress
            android:layout_marginTop="20dp"
            android:layout_gravity="center"
            android:id="@+id/process"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            >
            
        </com.example.progresstest.HezaiProgress>
    
    </LinearLayout>

    这里的com.example.progresstest是HezaiProgress所在的包名,HezaiProgress是自定义的控件代码。

    2.2 HezaiProgress.java文件

    package com.example.progresstest;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    import android.view.View.MeasureSpec;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.LinearLayout.LayoutParams;
    
    public class HezaiProgress extends View{
        private int process = 10;
        private int width,height;
        private int h = 32;
        private int w = 12;
        private int divideWidth=5;
        private int maxCount = 24;
        private int processColor=Color.GREEN;
        private int j = 1;
        private int num = 0;
        public int getProcessColor() {
            return processColor;
        }
        /**
         * 自定义颜色,输入的是“#ffffff”形式的颜色字符串
         * @param processColor
         */
        public void setProcessColor(String processColor) {
            char c = processColor.charAt(0);
            int r = 0;
            int g = 0;
            int b = 0;
            //默认颜色为绿色
            int rgb = Color.GREEN;
            if(c=='#'){
                for(int i = 1;i<processColor.length();i++){
                    c = processColor.charAt(i);
                    if(i<3){
                        r += rOrgOrb(c,i);
                    }
                    else if(i<5){
                        g += rOrgOrb(c,i);
                    }else{
                        b += rOrgOrb(c,i);
                    }
                    
                }
                rgb = Color.rgb(r, g, b);
            }
            this.processColor = rgb;
            
        }
        
        private int rOrgOrb(char c,int i){
            num++;
            char b = 0;
            if(c>='0'&&c<='9'){
                //j是用于判断是十六进制的哪一位
                if(i==j){
                    //十六进制的右数第二位
                    b += Integer.valueOf(c)*16;
                }
                if(i==j+1){
                    //十六进制的右数第一位
                    b += Integer.valueOf(c);
                }
            }
            //十六进制的大写字母形式
            if(c>='A'&&c<='F'){
                if(i==j){
                    //ascii码减去55,如A的ASCII码为65,减去55后等于10
                    b += ((int)c-55)*16;
                }
                if(i==j+1){
                    b += (int)c-55;
                }
            }
            //十六进制的小写字母形式
            if(c>='a'&&c<='f'){
                if(i==j){
                    //ascii码减去87,如a的ASCII码为97,减去87后等于10
                    b += ((int)c-87)*16;
                }
                if(i==j+1){
                    b += (int)c-87;
                }
            }
            //若计数为偶数,则给j加2
            if(num%2==0){
                j=j+2;
            }
            return b;
        }
        
        //得到最大进度数
        public int getMaxCount() {
            return maxCount;
        }
        //设置最大进度数
        public void setMaxCount(int maxCount) {
            this.maxCount = maxCount;
        }
    
        //得到进度
        public int getProcess() {
            return process;
        }
        //设置进度
        public void setProcess(int process) {
            this.process = process;
        }
        //设置间隔宽度
        public void setDivideWidth(int divideWidth){
            this.divideWidth = divideWidth;
        }
    
        public HezaiProgress(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // TODO Auto-generated constructor stub
        }
    
        public HezaiProgress(Context context, AttributeSet attrs) {
            this(context, attrs,0);
            // TODO Auto-generated constructor stub
        }
    
        public HezaiProgress(Context context) {
            this(context,null);
            // TODO Auto-generated constructor stub
        }
        
        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            setHezai(16, canvas);
        }
        //设置进度条高度
        public void setProcessHeight(int h){
            if(h==0)
                this.h = 32;
            else
                this.h = h;
        }
        //设置进度条宽度
        public void setProcessWidth(int w){
            if(w==0)
                this.w = 12;
            else
                this.w = w;
        }
        
        private void setHezai(int process,Canvas canvas){
            Rect rect;
            Paint paint;
            int tmp = 2;
            //进度取整,如果进度条总宽度大于指定控件宽度,则只显示整数个进度
            if(process*(w+tmp)+tmp>width)
                process = width/(w+divideWidth);
            //显示进度
            for (int i = 0;i<process;i++){
                rect = new Rect(tmp, 2,w+tmp,h);
                paint = new Paint();
                tmp=tmp+w+divideWidth;
                paint.setColor(processColor);
                canvas.drawRect(rect, paint);
    
            }
            //显示灰色进度,及默认没进度状态状态
            for (int i = 0; i < maxCount-process; i++) {
                rect = new Rect(tmp, 2,w+tmp,h);
                paint = new Paint();
                tmp=tmp+w+divideWidth;
                paint.setColor(Color.rgb(211, 211, 211));
                canvas.drawRect(rect, paint);
            }
        }
        //dp转换成px
        private int dipToPx(int dip){
            float scale = getContext().getResources().getDisplayMetrics().density;
            return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));//加0.5是为了四舍五入
        }
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // TODO Auto-generated method stub
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
            //MeasureSpec.EXACTLY,精确尺寸
            if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
                width = widthSpecSize;
            } else {
                //如果不是精确尺寸,则显示设置尺寸或默认尺寸
                width = w;
            }
            //MeasureSpec.AT_MOST,最大尺寸,只要不超过父控件允许的最大尺寸即可,MeasureSpec.UNSPECIFIED未指定尺寸
            if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
                //显示设置尺寸或默认尺寸
                height = dipToPx(h);
            } else {
                height = heightSpecSize;
            }
            //设置控件实际大小
            setMeasuredDimension(width, height);
            
        }
    }

    代码里做了详细注释,这里就不在说了。

    2.3 ProcessTest.java

    package com.example.progresstest;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class ProcessTest extends Activity {
        private HezaiProgress process;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.myprocesstest);
            process = (HezaiProgress) findViewById(R.id.process);
            //设置进度高度
            process.setProcessHeight(63);
            //设置进度宽度
            process.setProcessWidth(25);
            //设置间隔宽度
            process.setDivideWidth(10);
            //设置进度颜色
            process.setProcessColor("#008b8b");
        }
    }

    这里比第一种方法好的地方就是可以随意改变高度,宽度,间隔宽度,进度颜色等,而且只需要一句代码就行,因为前面已经封装好了,但似乎比较耗内存。

    这里是改变颜色后的截图,就是本博客的第一张图:

    源码地址就算了,步骤写的很详细了,相关的图标也给了。

  • 相关阅读:
    前端试题-正则中test, exec, match的区别
    前端试题-什么是css sprite?优缺点?
    有哪些软件堪称「神器」,却不被大众所知?(转)
    gif,png,jpg的区别
    前端试题-两列等高布局
    20160109小问题
    动画效果之运动
    用JS控制下拉菜单效果
    获取当前时间getDate()注意点
    全心加入web前端开发,向上吧!
  • 原文地址:https://www.cnblogs.com/ityizhainan/p/5914487.html
Copyright © 2020-2023  润新知