代码:View的学习案例(自定义StepView)

1.效果图:

2.代码:

package extra.view;

import extra.util.L;

import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.drawable.GradientDrawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;

/** * 作者:余天然 on 2015/7/14 10:00 * 邮箱:[email protected] * 博客:http://my.oschina.net/u/2345676/blog * 座右铭:知识来自积累,经验源于总结 */public class StepView extends View {    Context context;

Paint paint;    int viewWidth, viewHeight;//视图的宽、高

int mWidth,mHeight,mInRadius,mOutRadius;

int stepNumber=4;//总步数

int step=0;//开始的步数    float percentage=0.0f;//拖动的百分比

int minDistance;//最小移动间距(0.5倍间距)    float distance;//实际移动距离

// 颜色    int[] colors=new int[]{0xFF02FF02,0xFF02A7F5,0xFFFF144E,0xFFFBAB06};    int[] colorBgs=new int[]{0x7702FF02,0x7702A7F5,0x77FF144E,0x77FBAB06};    int lineColor=0xFF878787;

public StepView(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;    }

@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        initView();    }

private void initView() {        viewWidth = getWidth();        viewHeight = getHeight();

mWidth=viewWidth-50-50;        mHeight=10;        mInRadius=20;        mOutRadius=30;

L.e("viewWidth=" + viewWidth + "\tviewHeight=" + viewHeight);

paint = new Paint();

minDistance=mWidth/(stepNumber-1)/2;

}

@Override    protected void onDraw(Canvas canvas) {        //移动画布到中间        canvas.translate(50,viewHeight/2);

drawLine(canvas);

drawCircle(canvas);

drawGriend(canvas);    }

/**     * 绘制背景的横线和圆圈     * @param canvas     */    private void drawLine(Canvas canvas) {        canvas.save();        paint.setColor(lineColor);        //绘制横线        canvas.drawRect(0,0,mWidth,mHeight,paint);        //绘制未选择的圆圈        for(int i=0;i<stepNumber;i++){            canvas.drawCircle(0+mWidth/(stepNumber-1)*i, 0, mInRadius, paint);        }        canvas.restore();    }

/**     * 绘制有颜色的圆圈     * @param canvas     */    private void drawCircle(Canvas canvas) {        for(int i=0;i<stepNumber;i++){            if(i==step){                //绘制有色的横线                paint.setColor(colors[i]);                canvas.drawRect(0,0,mWidth/(stepNumber-1)*i,mHeight,paint);

//绘制外圆                paint.setColor(colorBgs[i]);                canvas.drawCircle(0 + mWidth / (stepNumber - 1) * i, 0, mOutRadius, paint);

//绘制内圆                for(int j=0;j<=i;j++){                    paint.setColor(colors[i]);                    canvas.drawCircle(0+mWidth/(stepNumber-1)*j, 0, mInRadius, paint);                }

}        }    }

/**     * 绘制移动时的颜色渐变     */    private void drawGriend(Canvas canvas) {        GradientDrawable gr = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[]{colors[step],colors[(step+1)%stepNumber]});        gr.setShape(GradientDrawable.RECTANGLE);//设置形状为矩形

int startW=0+mWidth/(stepNumber-1)*step;        gr.setBounds(startW, 0, (int)(startW+distance), mHeight);        gr.draw(canvas);    }

float startX,startY,moveX,moveY,endX,endY;    @Override    public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                startX=event.getX();                startY=event.getY();                L.e( "ACTION_DOWN:startX="+startX+"\tstartY="+startY);                break;

case MotionEvent.ACTION_MOVE:                moveX=event.getX();                moveY=event.getY();                L.e( "ACTION_MOVE:moveX="+moveX+"\tmoveY="+moveY);                doMove();                break;

case MotionEvent.ACTION_UP:                endX=event.getX();                endY=event.getY();                L.e( "ACTION_UP:endX="+endX+"\tendY="+endY);                doUp();                break;

}        return true;    }

private void doUp() {        distance=endX-startX;        percentage=distance/(minDistance*2);

if(percentage>0.5f){            addStep();        }else if (percentage<-0.5f){            reduceStep();        }        distance=0;        invalidate();        iStepListener.currentStep(step);    }

private void doMove() {        distance=moveX-startX;

if(distance>=minDistance*2){            distance=minDistance*2;        }        invalidate();    }

private void addStep() {        step++;        step=(step%stepNumber+stepNumber)%stepNumber;    }

private void reduceStep() {        step--;        step=(step%stepNumber+stepNumber)%stepNumber;    }

public interface IStepListener{        void currentStep(int step);    }

IStepListener iStepListener;

public void setiStepListener(IStepListener iStepListener) {        this.iStepListener = iStepListener;    }}

来自为知笔记(Wiz)

时间: 2024-10-12 08:12:24

代码:View的学习案例(自定义StepView)的相关文章

自定义View 篇一--------《自定义View流程分析》

本文部分内容参考自掘金网:点击打开链接 坐标图解: 概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会比较多.但是任何复杂的技术后面都是一点点简单知识的积累.通过对自定义控件的学习去可以更深入的掌握android的相关知识点,所以学习android自定义控件是很有必要的.所以,今天写的是怎么去自定义一个控件.而不是里面涉及到的细化知识点.一个东西我

从零开始--系统深入学习android(实践-让我们开始写代码-Android框架学习-7.通知)

通知 一个通知是一条消息他是显示于你应用程序之外的一个界面中.当你告诉系统要发布一个通知时,它首先作为一个icon出现在通知区域.为了看见通知的细节,用户可以点击通知区域展开一个新的界面.下面让我们来看一下图7-1和图7-2: 图7-1 通知出现在通知区域 图7-2 通知展开后的效果(drawer) 注意:除非特别注明外,本章指的都是NotificationCompat.Builder,它在v4 Support Library中有,正式添加于API Level 15.但有了v4 Support

StyleCop学习笔记——自定义规则

本文将简单的一步一步的指导这可能有助于学习如何创建自己的规则 1.创建一个项目. Visual Studio创建一个新的类库项目.NET3.5 2.引用两个DLL,StyleCop.dll和StyleCop.Csharp.dll. 3.添加自定义的规则. MyCustomAnalyzer.cs代码如下: using StyleCop; using StyleCop.CSharp; namespace MyCustomRules { /// <summary> /// Custom analyz

Struts2重新学习之自定义拦截器(判断用户是否是登录状态)

拦截器 一:1:概念:Interceptor拦截器类似于我们学习过的过滤器,是可以再action执行前后执行的代码.是web开发时,常用的技术.比如,权限控制,日志记录. 2:多个拦截器Interceptor连在一起组成了Interceptor栈.拦截器是AOP面向切面编程的一种实现,具有热插拔的效应. 3:Struts2拦截器,每个拦截器类只有一个对象实例,即采用了单利模式.所有引用这个拦截器的action都共享着一拦截器类的实例. 拦截器和过滤器的区别 1:拦截器和过滤器的概念非常类似 2:

javascript 学习之自定义滚动条加滚轮事件

要自己写一个自定义滚动条加上滚轮事件,之前的没有滚轮事件不完整,今天整理了一个. 1.滚轮事件是不兼容的,firefox中是必需要用事件绑定的添加,用的DOMMouseScroll,当滚动鼠标的时候,只要鼠标滚动的方法就行了,而这通过检测datail的正负号就可以确定 2.其他的用mousewheel(Ie是onmousewheel),通过检测wheelDelta 1 <!doctype html> 2 <html> 3 <head> 4 <title>拖拽

java类加载器学习2——自定义类加载器和父类委托机制带来的问题

一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载器.如果父类加载器加载不了,依次再使用其子类进行加载.当然这类所说的父类加载器,不一定他们之间是继承的关系,有可能仅仅是包装的关系. Java之所以出现这条机制,因为是处于安全性考虑.害怕用户自己定义class文件然后自己写一个类加载器来加载原本应该是JVM自己加载的类.这样会是JVM虚拟机混乱或者

hadoop学习;自定义Input/OutputFormat;类引用mapreduce.mapper;三种模式

hadoop分割与读取输入文件的方式被定义在InputFormat接口的一个实现中,TextInputFormat是默认的实现,当你想要一次获取一行内容作为输入数据时又没有确定的键,从TextInputFormat返回的键为每行的字节偏移量,但目前没看到用过 以前在mapper中曾使用LongWritable(键)和Text(值),在TextInputFormat中,因为键是字节偏移量,可以是LongWritable类型,而当使用KeyValueTextInputFormat时,第一个分隔符前后

JAVA Excel API学习案例

先贴代码吧,运行一下,看看效果,然后看看注释,再看看代码后面的基础介绍 创建一个新excel并写入数据: public static void myExcel2() throws IOException, WriteException { WritableWorkbook wwb = Workbook.createWorkbook(new File("F:" + File.separator + "myExcel1.xls")); // 创建excel表格中的一个s

MySQL学习笔记-自定义函数

MySQL学习笔记-自定义函数 1.自定义函数简介 自定义函数:用户自定义函数(user-defined function,UDF)是一种对MySQL扩展的途径,其用法与内置函数相同 自定义函数的两个必要条件:(1)参数  (2)返回值 自定义函数: 创建自定义函数 CREATE FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL} routine_body 关于函数体: 1.函数体可以由合法的SQL语句构成: 2.函数体可以是