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

时间: 2024-10-09 09:41:09

android 自己定义TextView&quot;会发脾气的TextView&quot;的相关文章

Android 自己定义TextView 实现文本间距

转载请标明出处: http://blog.csdn.net/u011974987/article/details/50845269: Android系统中TextView默认显示中文时会比較紧凑.不是非常美观.为了让每行保持一定的行间距,能够设置属性android:lineSpacingExtra或android:lineSpacingMultiplier. 可是有时候我们须要在TextView的文本之间有间距,两个字的话,我们能够在xml文件里.用敲空格的方式来实现.假设有非常多文本或者是一个

Android UI-自定义日历控件

Android UI-自定义日历控件 本篇博客笔者给大家分享一个日历控件,这里有个需求:要求显示当前月的日期,左右可以切换月份来查看日期. 我们想一想会如何去实现这样的一个控件,有开源的,但可能不太满足我们的特定的需求,这里笔者自定义了一个,读者可以根据自己的需求来修改代码.下面来说一下实现的思路: 首先我们要显示当前月份,自然我们要计算出当前的日期,并且把每一天对应到具体的星期,我们会有以下效果: 我们先想一下这样的效果用什么控件可以实现?很自然可以想到用网格视图GridView,但这里笔者使

ANDROID自己定义视图——onLayout源代码 流程 思路具体解释

简单介绍: 在自己定义view的时候.事实上非常easy.仅仅须要知道3步骤: 1.測量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3.绘制--onDraw():怎样绘制这个View. 而第3步的onDraw系统已经封装的非常好了,基本不用我们来担心,仅仅须要专注到1,2两个步骤就中好了. 第一步的測量,能够參考我之前的文章:(ANDROID自己定义视图--onMeasure流程.MeasureSpec具体解释) 而

android 自己定义标签的使用,实现扁平化UI设计

2014年8月6日11:06:44 android对自己定义标签的使用.实现扁平化UI设计: 1.attrs.xml文件里自己定义标签 如: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="first"> //reference指的是是从string.xml引用过来 <attr name="n

android 自己定义控件属性(TypedArray以及attrs解释)

近期在捣鼓android 自己定义控件属性,学到了TypedArray以及attrs.在这当中看了一篇大神博客Android 深入理解Android中的自己定义属性.我就更加深入学习力一番.我就沿着这个学习,讲一下流程吧,兴许一篇还有应用. 1.attrs文件编写 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="titleText" for

46.Android 自己定义Dialog

46.Android 自己定义Dialog Android 自己定义Dialog 前言 提示Dialog 提示Dialog 效果图 菜单Dialog 菜单Dialog 效果图 DialogActivity 前言 提供两套自己定义Dialog模板 第一种.提示Dialog,有消失时间. 另外一种,菜单Dialog,用于用户交互. 提示Dialog CustomDialog public class CustomDialog extends Dialog { private TextView dia

Android 自己定义ViewGroup 实战篇 -&amp;gt; 实现FlowLayout

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38352503 .本文出自[张鸿洋的博客] 1.概述 上一篇已经基本给大家介绍了怎样自己定义ViewGroup.假设你还不了解,请查看:Android 手把手教您自定ViewGroup ,本篇将使用上篇介绍的方法,给大家带来一个实例:实现FlowLayout,何为FlowLayout,假设对Java的Swing比較熟悉的话一定不会陌生.就是控件依据ViewGroup的宽,自己主动

Android自己定义组件系列【5】——进阶实践(2)

上一篇<Android自己定义组件系列[5]--进阶实践(1)>中对任老师的<可下拉的PinnedHeaderExpandableListView的实现>前一部分进行了实现,这一篇我们来看看ExpandableListView的使用并实现剩下的部分. 原文出处:http://blog.csdn.net/singwhatiwanna/article/details/25546871 一.ExpandableListView的使用方法 ExpandableListView是ListVi

android 自己定义控件

Android自己定义View实现非常easy 继承View,重写构造函数.onDraw.(onMeasure)等函数. 假设自己定义的View须要有自己定义的属性.须要在values下建立attrs.xml. 在当中定义你的属性. 在使用到自己定义View的xml布局文件里须要增加xmlns:前缀="http://schemas.android.com/apk/res/你的应用所在的包路径". 在使用自己定义属性的时候.使用前缀:属性名,如my:textColor="#FF