android 自己定义TextView"会发脾气的TextView"
转载请注明出处王亟亟的大牛路
Git上看到的一个自己定义控件就搞来研究研究。蛮可爱的。
项目结构: 
 
执行效果:非常Q谈。谈的图片什么都 都能够换哦 
自己定义View:
public class JelloToggle extends FrameLayout {
    private static final int DEFAULT_DURATION = 1000;//动画持续时间
    private static final int UNCHECKED_JELLO_COLOR = 0xffadadad;//初始化颜色
    private static final int CHECKED_JELLO_COLOR = 0xffff0000;//初始化颜色
    private Rect mJelloRect;
    private Paint mJelloPaint;
    private Scroller mScroller;
    private Path mJelloPath;
    private TimeInterpolator mInterpolator;
    private OnCheckedChangeListener mListener;
    private Drawable mCheckedDrawable;
    private Drawable mOnCheckDrawable;
    private Drawable mUnCheckedDrawable;
    private Drawable mDrawable;
    private boolean mChecked = false;
    private int mTouchStartX;
    private int mScrollOffset;
    private int mJelloSize;
    private int mDragLimit;
    private int mJelloMax;
    private int mJelloOffset;
    private long mStartTime;
    private long mDuration;
    private int mCheckedColor = CHECKED_JELLO_COLOR;
    public JelloToggle(Context context) {
        super(context);
        init();
    }
    public JelloToggle(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public JelloToggle(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    private void init() {
        mJelloPaint = new Paint();
        mJelloPaint.setAntiAlias(true);
        mCheckedDrawable = getResources().getDrawable(R.drawable.checked);
        mOnCheckDrawable = getResources().getDrawable(R.drawable.check_on);
        mUnCheckedDrawable = getResources().getDrawable(R.drawable.uncheck);
        setJelloState();
        mJelloRect = new Rect();
        mScroller = new Scroller(getContext());
        mJelloPath = new Path();
        mInterpolator = new EaseOutElasticInterpolator();
        mDuration = DEFAULT_DURATION;
    }
    private void calPath() {
        mJelloPath.rewind();
        mJelloPath.moveTo(mJelloRect.right, 0);
        mJelloPath.lineTo(mJelloRect.left, 0);
        mJelloPath.cubicTo(mJelloRect.left, mJelloSize / 2, mJelloRect.left + mJelloOffset -
                        mJelloSize / 3, mJelloSize * 3 / 4,
                mJelloRect.left, mJelloSize);
        mJelloPath.lineTo(mJelloRect.right, mJelloRect.bottom);
        mJelloPath.close();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mDragLimit = getMeasuredWidth() / 4;
        mJelloSize = getMeasuredHeight();
        mJelloRect.set(getMeasuredWidth() - mJelloSize, 0, getMeasuredWidth() + mDragLimit,
                mJelloSize);
        mCheckedDrawable.setBounds(mJelloRect.left, mJelloRect.top, mJelloRect.left + mJelloSize,
                mJelloSize);
        mOnCheckDrawable.setBounds(mJelloRect.left, mJelloRect.top, mJelloRect.left + mJelloSize,
                mJelloSize);
        mUnCheckedDrawable.setBounds(mJelloRect.left, mJelloRect.top, mJelloRect.left + mJelloSize,
                mJelloSize);
        calPath();
    }
    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(mScrollOffset, 0);
        super.dispatchDraw(canvas);
        canvas.restore();
        canvas.save();
        canvas.translate(mScrollOffset / 2, 0);
        canvas.drawPath(mJelloPath, mJelloPaint);
        mDrawable.draw(canvas);
        canvas.restore();
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean ret = true;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.forceFinished(true);
                }
                mTouchStartX = (int) event.getX();
                mDrawable = mOnCheckDrawable;
                break;
            case MotionEvent.ACTION_MOVE:
                int dragLen = Math.min(0, (int) event.getX() - mTouchStartX);
                mScrollOffset = Math.max(-mDragLimit, dragLen);
                mJelloOffset = dragLen;
                calPath();
                postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                if (mScrollOffset < 0) {
                    mScroller.startScroll(mScrollOffset, 0, -mScrollOffset, 0);
                    mJelloMax = mJelloOffset;
                    if (mJelloOffset <= -mDragLimit) {
                        mChecked = !mChecked;
                        if (mListener != null) {
                            mListener.onCheckedChange(mChecked);
                        }
                    }
                    setJelloState();
                    postInvalidate();
                    startJello();
                }
                break;
        }
        return ret;
    }
    private void setJelloState() {
        if (mChecked) {
            mJelloPaint.setColor(mCheckedColor);
            mDrawable = mCheckedDrawable;
        } else {
            mJelloPaint.setColor(UNCHECKED_JELLO_COLOR);
            mDrawable = mUnCheckedDrawable;
        }
    }
    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            mScrollOffset = mScroller.getCurrX();
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }
    public void setJelloDuration(long duration) {
        if (duration <= 0) {
            duration = DEFAULT_DURATION;
        }
        mDuration = duration;
    }
    public void setCheckedJelloColor(int color) {
        mCheckedColor = color;
        setJelloState();
        postInvalidate();
    }
    public void setCheckedDrawable(Drawable drawable) {
        mCheckedDrawable = drawable;
    }
    public void setOnCheckDrawable(Drawable drawable) {
        mOnCheckDrawable = drawable;
    }
    public void setUnCheckedDrawable(Drawable drawable) {
        mUnCheckedDrawable = drawable;
    }
    private void startJello() {
        mStartTime = AnimationUtils.currentAnimationTimeMillis();
        post(mJelloRunnable);
    }
    private Runnable mJelloRunnable = new Runnable() {
        @Override
        public void run() {
            long playTime = AnimationUtils.currentAnimationTimeMillis() - mStartTime;
            if (playTime < mDuration) {
                float fraction = playTime / (float) mDuration;
                mJelloOffset = (int) (mJelloMax * (1 - mInterpolator.getInterpolation
                        (fraction)));
                calPath();
                ViewCompat.postInvalidateOnAnimation(JelloToggle.this);
                post(this);
            } else {
                mJelloOffset = 0;
                calPath();
                ViewCompat.postInvalidateOnAnimation(JelloToggle.this);
            }
        }
    };
    public interface OnCheckedChangeListener {
        void onCheckedChange(boolean checked);
    }
    public void setCheckedChangeListener(OnCheckedChangeListener listener) {
        mListener = listener;
    }
}
主Activity
public class MainActivity extends ActionBarActivity {
    private JelloToggle mToggle1;
    private JelloToggle mToggle2;
    private JelloToggle mToggle3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToggle1 = (JelloToggle) findViewById(R.id.jello1);
        mToggle1.setCheckedJelloColor(0xffdb654a);
        mToggle2 = (JelloToggle) findViewById(R.id.jello2);
        mToggle2.setCheckedJelloColor(0xfffb008a);
        mToggle3 = (JelloToggle) findViewById(R.id.jello3);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                tools:context=".MainActivity">
    <TextView
        android:text="Title1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"/>
    <me.fichardu.jellotoggle.JelloToggle
        android:id="@+id/jello1"
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:paddingLeft="24dp"
            android:text="Text"
            android:textSize="20sp"
            android:textColor="@android:color/white"
            android:background="#f0007D8B"
            />
    </me.fichardu.jellotoggle.JelloToggle>
    <TextView
        android:text="Title2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:layout_marginTop="50dp"/>
    <me.fichardu.jellotoggle.JelloToggle
        android:id="@+id/jello2"
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:paddingLeft="24dp"
            android:text="Text"
            android:textSize="20sp"
            android:textColor="@android:color/white"
            android:background="#ff6D4C41"
            />
    </me.fichardu.jellotoggle.JelloToggle>
    <me.fichardu.jellotoggle.JelloToggle
        android:id="@+id/jello3"
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:paddingLeft="24dp"
            android:text="Text"
            android:textSize="20sp"
            android:textColor="@android:color/white"
            android:background="#ff43A047"
            />
    </me.fichardu.jellotoggle.JelloToggle>
</LinearLayout>
详细内容能够看源代码。拿来就能用。想知道怎么实现能够 看源代码。量不大 
源代码地址:http://yunpan.cn/cd4szcyz5LsT4  訪问password fb75
android 自己定义TextView"会发脾气的TextView"的更多相关文章
- Android 自己定义TextView 实现文本间距
		转载请标明出处: http://blog.csdn.net/u011974987/article/details/50845269: Android系统中TextView默认显示中文时会比較紧凑.不是 ... 
- Android 高级UI设计笔记05:使用TextView实现跑马灯的效果
		1. 使用TextView属性实现跑马灯的效果: (1). 新建一个Android工程,命名为"MarqueeTextViewDemo",如下: (2). 来到activity_m ... 
- Android UI--自定义ListView(实现下拉刷新+加载更多)
		Android UI--自定义ListView(实现下拉刷新+加载更多) 关于实现ListView下拉刷新和加载更多的实现,我想网上一搜就一堆.不过我就没发现比较实用的,要不就是实现起来太复杂,要不就 ... 
- android ui定义自己的dialog(项目框架搭建时就写好,之后事半功倍)
		自定义一个dialog: 之前有很多博客都有过这方面的介绍,可是个人觉得通常不是很全面,通用性不是很强,一般会定义一个自己的dialog类,然后去使用,难道每一个dialog都要定义一个class吗? ... 
- ANDROID自己定义视图——onLayout源代码 流程 思路具体解释
		转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 在自己定义view的时候.事实上非常easy.仅仅须要知道3步骤: 1.測量- ... 
- Android开发:文本控件详解——TextView(一)基本属性
		一.简单实例: 新建的Android项目初始自带的Hello World!其实就是一个TextView. 在activity_main.xml中可以新建TextView,从左侧组件里拖拽到右侧预览界面 ... 
- android 自己定义视频播放器之2/1
		非常久没更新博客,相信大家年后都比較忙. 今天给大家带来了一款视频播放器,首先确认的得有几点. 1.首先得有个播放视频的view. 2.加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量: 3 ... 
- Android自己定义button实现长按功能
		Android自己定义button实现长按功能 通过自己定义BUTTON,写一个LongTouchBtn类,在按下的时候运行onTouchEvent事件,通过这个事件使用回调函数来实现长按功能! XM ... 
- Android自己定义View的实现方法
		转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了.回 ... 
随机推荐
- 1. DNN神经网络的前向传播(FeedForward)
			1. DNN神经网络的前向传播(FeedForward) 2. DNN神经网络的反向更新(BP) 3. DNN神经网络的正则化 1. 前言 神经网络技术起源于上世纪五.六十年代,当时叫感知机(perc ... 
- RecyclerView 输出的和排版的不一样
			遇到过这样一种情况,就是RecyclerView加载出来的和看到Android Studio里的不一样 原因是: @Override public ViewHolder onCreateViewHol ... 
- 阿里云  Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR invalid password
			如果你是买的阿里云的redis服务的话,不要被这个ERR invalid password所迷惑了. 你应该去检查一下你买的服务有没有设置白名单. 像mysql和mongodb的服务如果连不上的话也可 ... 
- Java编程的逻辑 (44) -  剖析TreeSet
			本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ... 
- linux安装setup
			安装setuptool #yum install setuptool 系统服务管理 #yum install ntsysv 防火墙设置.网络设置 #yum install ipt ... 
- hazelcast初探
			Hazelcast作为一个高度可扩展的数据分发和集群平台,提供了高效的.可扩展的分布式数据存储.数据缓存.Hazelcast是开源的,在分布式技术方面,Hazelcast提供了十分友好的接口供开发者选 ... 
- 【C】——信号量 互斥锁 条件变量的区别
			信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里).而互斥锁是用在多线程多任务互斥的,一个线程占用了某 ... 
- 图示 Smart-Art
			在PPT中,图示有两个作用,一是将对象间的逻辑关系视觉化,使文字承载的信息一目了然; 二是打破呆板的页面版式,让枯燥的文本变得更有魅力. 比较聪明的办法是在Sma吨Art生成图形的基础上继续编辑,使其 ... 
- Java设计模式(21)访问模式(Visitor者模式)
			Visitor定义:作用于某个对象群中各个对象的操作.它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 在Java中,Visitor模式实际上是分离了collection结构中的元 ... 
- 链接按钮LinkButton(按钮组)
			<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ... 
