首页 > 代码库 > android 自己定义TextView"会发脾气的TextView"

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

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

android 自己定义TextView&quot;会发脾气的TextView&quot;