android:滑动挂断自定义View的简单实现

要点:

  • 随着手指的滑动更新位置
  • 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



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

时间: 2024-11-07 05:37:53

android:滑动挂断自定义View的简单实现的相关文章

Android知识梳理之自定义View

虽然android本身给我们提供了形形色色的控件,基本能够满足日常开发的需求,但是面对日益同质化的app界面,和不同的业务需求.我们可能就需要自定义一些View来获得比较好的效果.自定义View是android开发者走向高级开发工程师必须要走的一关. 转载请标明出处:http://blog.csdn.net/unreliable_narrator/article/details/51274264 一,构造函数: 当我们创建一个类去继承View的时候,会要求我们至少去实现一个构造函数. publi

Android进阶之绘制-自定义View完全掌握(二)

这是自定义View系列的第二篇博客,我们继续来学习关于自定义View的知识. 今天我们来实现一下广告条案例. 我们要实现的是这样的一个效果. 要想实现这样的效果,我们可以借助ViewPager控件,然后加上自定义的一些控件即可完成.那么现在就开始吧. 新建一个android项目. 修改activity_main.xml文件. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:a

Android 如何 画 柱状图 -------自定义View

实现了 柱状图 根据 SeekBar的滑动 改变的效果: 图示效果: 自定义View的代码: package com.example.coustomviewdemo; import android.R.color; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.g

Android应用开发之自定义View触摸相关工具类全解

背景 最近有些乱,各种事情,各种交叉.好在还有一点上进心,于是继续将自定义这个系列的核心知识再梳理一下吧.关于自定义控件前面博文说过了,这里不会教你拿来主义,只授之以渔,如果你喜欢拿来主义,不好意思,请绕行,如果你喜欢得渔,那请继续. 前面我们已经叙述过了几篇关于自定义View涉及的东西,大家可以自己回过头去看我之前的博客,譬如事件处理.坐标系.工具类等.下面我们还是继续补充一些常用的自定义控件工具类. [工匠若水 http://blog.csdn.net/yanbober 未经允许严禁转载,请

Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如onDraw,为了我们自定义的View在一个项目中能够重用,有时候我们需要自定义其属性,举个很简单的例子,我在项目中的多个界面使用我自定义的View,每个界面该自定义View

Android ——利用OnDraw实现自定义View(转)

自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.本文将介绍自绘控件的用法.自绘控件的意思是,这个控件上的内容是用onDraw函数绘制出来的.关于onDraw函数的介绍可参看 Android视图绘制流程完全解析,带你一步步深入了解View(二) . 例子1:在layout文件中使用自绘控件 出处:http://blog.csdn.net/guolin_blog/article/details/17357967 下面我们准备来自定义一个计数器View,这个View可以响应

Android进阶之绘制-自定义View完全掌握(三)

自定义View系列的第三篇博客,我们来学习如何实现自定义下拉框. 今天的程序,我们来实现这样的一个效果. 布局非常简单,我们直接开始编码. 修改activity_main.xml文件的代码. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:

Android进阶之绘制-自定义View完全掌握(四)

前面的案例中我们都是使用系统的一些控件通过组合的方式来生成我们自定义的控件,自定义控件的实现还可以通过自定义类继承View来完成.从该篇博客开始,我们通过自定义类继承View来实现一些我们自定义的控件. 我们通过一个案例来学习,现在来实现这样一个效果. 我们新建一个类MyToggleButton,让它继承View. 注意,一定要重写带两个参数的构造方法,因为如果我们在布局文件使用该类,将会用这个构造方法实例该类,如果没有就崩溃. 介绍一下一个控件从创建到显示过程中的主要方法. 执行构造方法实例化

Android属性动画与自定义View——实现vivo x6更新系统的动画效果

晚上好,现在是凌晨两点半,然后我还在写代码.电脑里播放着<凌晨两点半>,晚上写代码,脑子更清醒,思路更清晰. 今天聊聊属性动画和自定义View搭配使用,前面都讲到自定义View和属性动画,但是一起用的还是不多,刚巧今晚手机提示我更新系统,我看到那个更新的动画还不错,仔细的分析了一下,于是我也决定写一个,不是一模一样的,但是效果和原理是一样的. 先看看图: 这是一张静态的图,这里有三个波浪线,当下载完之后,波浪线会往上活动,一直到消失. 所以难点也是在这个波浪线上.这个波浪线类似于一个水波纹,也