要点:

  • 随着手指的滑动更新位置

  • drawText的时候,如何计算开始的位置,使str居中

1.CallSliderEndView.java

package net.mobctrl.callendview;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.RectF;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;/** * @date 2015年2月2日 下午11:02:00 * @author Zheng Haibo * @Description: 滑动挂断的自定义控件 * @Web http://www.mobctrl.net */@SuppressLint({ "DrawAllocation", "ClickableViewAccessibility" })public class CallSliderEndView extends View {    public interface SliderEndListener {        public void onSliderEnd();    }    private SliderEndListener sliderEndListener;    public void setSliderEndListener(SliderEndListener sliderEndListener) {        this.sliderEndListener = sliderEndListener;    }    private int height;    private int width;    private int circleOffset = 0;    private int prevX = 0;    private int maxOffset;    private String sliderText;    private float textSize;    private int progressBackgroundColor;    private int backgroundColor;    private int redReginWidth;    public CallSliderEndView(Context context) {        super(context);        init(context, null);    }    public CallSliderEndView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context, attrs);    }    public CallSliderEndView(Context context, AttributeSet attrs,            int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs);    }    private void init(Context context, AttributeSet attrs) {        if (null == attrs) {            return;        }        TypedArray typedArray = context.obtainStyledAttributes(attrs,                R.styleable.CallSliderEndView);        textSize = typedArray.getDimensionPixelSize(                R.styleable.CallSliderEndView_textSize, 40);        sliderText = typedArray.getString(R.styleable.CallSliderEndView_text);        progressBackgroundColor = typedArray.getColor(                R.styleable.CallSliderEndView_progressBackgroundColor,                Color.GREEN);        backgroundColor = typedArray.getColor(                R.styleable.CallSliderEndView_backgroundColor, 0x0fffffff);        typedArray.recycle();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // TODO        height = getHeight();        width = getWidth();        // 绘制背景        Paint paint = new Paint();        paint.setStyle(Style.FILL);        paint.setAntiAlias(true);        paint.setColor(backgroundColor);        drawBackground(canvas, paint);        // drawCircleButton(canvas, paint);        drawRoundButton(canvas, paint);    }    // 绘制背景    private void drawBackground(Canvas canvas, Paint paint) {        canvas.drawRoundRect(new RectF(0, 0, width, height), height / 2,                height / 2, paint);    }    // 绘制挂断按钮的View    @Deprecated    private void drawCircleButton(Canvas canvas, Paint paint) {        int circleMargin = height / 10;        paint.setColor(Color.RED);        canvas.drawCircle(height / 2 + circleOffset, height / 2, height / 2                - circleMargin, paint);    }    // 绘制挂断按钮的View    private void drawRoundButton(Canvas canvas, Paint paint) {        redReginWidth = width / 2;        // 绘制进度背景        paint.setColor(progressBackgroundColor);        canvas.drawRoundRect(new RectF(circleOffset, 0, circleOffset                + redReginWidth, height), height / 2, height / 2, paint);        // 将文本sliderText显示在中间        paint.setTextSize(textSize);        paint.setColor(Color.WHITE);        int yCenterPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint                .ascent()) / 2));// 计算在Y        int startX = circleOffset                + (redReginWidth - (int) paint.measureText(sliderText, 0,                        sliderText.length())) / 2;        canvas.drawText(sliderText, startX, yCenterPos, paint);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            actionDown(event);            break;        case MotionEvent.ACTION_MOVE:            actionMove(event);            break;        case MotionEvent.ACTION_UP:            actionUp(event);            break;        }        return true;    }    private void actionUp(MotionEvent event) {        if (this.circleOffset != maxOffset) {            this.circleOffset = 0;        }        postInvalidate();    }    private void actionMove(MotionEvent event) {        int tempOffset = (int) (event.getX() - this.prevX);        this.maxOffset = width - redReginWidth;        if (tempOffset >= maxOffset && this.circleOffset == maxOffset) {            return;        }        this.circleOffset = tempOffset;        if (this.circleOffset > maxOffset) {// 是否已经滑动到边缘            this.circleOffset = maxOffset;            if (sliderEndListener != null) {                sliderEndListener.onSliderEnd();            }        }        if (this.circleOffset <= 0) {            this.circleOffset = 0;        }        postInvalidate();    }    private void actionDown(MotionEvent e) {        this.prevX = (int) e.getX();    }}

2.使用
布局main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/net.mobctrl.callendview" android:id="@+id/rl_root" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/background_dark" android:orientation="horizontal" >    <net.mobctrl.callendview.CallSliderEndView  android:id="@+id/csev_slider_view" android:layout_width="match_parent" android:layout_height="60dp" android:layout_centerInParent="true" android:layout_margin="30dp" app:backgroundColor="#ffffff" app:progressBackgroundColor="#ffff1221" app:text="滑动挂断" app:textSize="24sp" /></RelativeLayout>

MainActivity.java

package net.mobctrl.callendview;import net.mobctrl.callendview.CallSliderEndView.SliderEndListener;import android.app.Activity;import android.os.Bundle;import android.widget.Toast;/** * * @author Zheng Haibo * @web http://www.mobctrl.net * */public class MainActivity extends Activity {    private CallSliderEndView callSliderEndView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        callSliderEndView = (CallSliderEndView) findViewById(R.id.csev_slider_view);        callSliderEndView.setSliderEndListener(new SliderEndListener() {            @Override            public void onSliderEnd() {                System.out.println("debug:onSliderEnd...");                Toast.makeText(getApplicationContext(), "Slider To End",                        Toast.LENGTH_SHORT).show();            }        });    }}

3.属性attr的配置(/res/value/attr.xml)

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="CallSliderEndView">        <attr name="backgroundColor" format="color" />        <attr name="progressBackgroundColor" format="color" />        <attr name="textSize" format="dimension" />        <attr name="text" format="string" />    </declare-styleable></resources>

4.效果

用户可以使用手指滑动

项目github地址:GitHub

Android开发联盟QQ群:272209595

未经许可,不得用于商业目的

更多相关文章

  1. FloatingActionButton 浮动按钮
  2. android 设置键盘按钮为发送按钮并监听 及 键盘显示与隐藏 监听
  3. android 实现自由移动的悬浮按钮
  4. Android的supportV7中默认按钮的颜色设置
  5. android > layout > background 背景图片重复
  6. Android背景设置
  7. android studio 添加按钮点击事件的三种方法
  8. android 按钮 背景 文字 自定义

随机推荐

  1. Android(安卓)NestedScrollView嵌套Recyc
  2. Android的动画简单学习
  3. [android]android自动化测试四之Monkey与
  4. Android(安卓)数据传递-通过Intent传递数
  5. android 事件传递机制 【转】
  6. android studio 中查看数据库
  7. Android(安卓)Framework系列之IMF(二)
  8. 4G模块Air720系列 android RIL驱动源码发
  9. android使用webView加载本地资源
  10. Android(安卓)System Property框架