美文网首页
Widget Switch UI定制

Widget Switch UI定制

作者: 洺优 | 来源:发表于2018-08-06 20:25 被阅读0次

我们知道自定义控件是最直接的方式,但是我想要的其实就是原生的switch的功能,仅仅是样式不同,所以去造一个哪怕是简易的仿造都显得麻烦。

👇下面这个就是我们想要的样式,on的时候track是绿色,thumb是白色;off的时候track是白色,thumb是绿色。

image.png

常见的switch长成👇这个样子

image

简单地修改一下, 你会发现宽高的修改完全与switch无关,改的是整个控件的大小。

<Switch
        android:id="@+id/switch1"
        android:layout_width="112dp"
        android:layout_height="73dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:text="Switch"
        android:thumb="@drawable/tutor_switch_btn_on"
        android:track="@drawable/tutor_switch_bg_on"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
image

再修改一下,加上android:switchMinWidth, 把背景换一换,让白色的thumb明显一点

    <Switch
        android:id="@+id/switch1"
        android:layout_width="112dp"
        android:layout_height="73dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:switchMinWidth="104dp"
        android:thumb="@drawable/tutor_switch_btn_on"
        android:track="@drawable/tutor_switch_bg_on"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />
image.png

好,到这里你就开始发现所有的switch的attr中设置的可变的参数都影响不了thumb的宽度或者track的高度了,各种padding都是浮云, 内心撕裂[流泪]。
几乎就要放弃的时候去自己写控件的时候,突然想到这个图片本身带点空白不就好了吗?然而,我没有切图工具也不会切图。所以我自己画一个吧

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <size android:height="40dp" android:width="40dp"/>
    <solid android:color="#FFFFFF"/>
    <stroke android:width="8dp"
        android:color="@color/transparent"/>
</shape>

顺便把字也加上


image.png image.png

对于这个字怎么加也想了一会,要求textOn、textOff显示的内容是不一样的,原生的控件是有textOn和textOff属性,但是它们是在thumb上

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mShowText) {
        if (mOnLayout == null) {
            mOnLayout = makeLayout(mTextOn);
        }

        if (mOffLayout == null) {
            mOffLayout = makeLayout(mTextOff);
        }
    }
...
private Layout makeLayout(CharSequence text) {
    final CharSequence transformed = (mSwitchTransformationMethod != null)
                ? mSwitchTransformationMethod.getTransformation(text, this)
                : text;

    int width = (int) Math.ceil(Layout.getDesiredWidth(transformed, 0,
            transformed.length(), mTextPaint, getTextDirectionHeuristic()));
    return new StaticLayout(transformed, mTextPaint, width,
            Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true);
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    ...
    if (thumbDrawable != null) {
        thumbDrawable.draw(canvas);
    }

    final Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
    if (switchText != null) {
        final int drawableState[] = getDrawableState();
        if (mTextColors != null) {
            mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0));
        }
        mTextPaint.drawableState = drawableState;

        final int cX;
        if (thumbDrawable != null) {
            final Rect bounds = thumbDrawable.getBounds();
            cX = bounds.left + bounds.right;
        } else {
            cX = getWidth();
        }

        final int left = cX / 2 - switchText.getWidth() / 2;
        final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2;
        canvas.translate(left, top);
        switchText.draw(canvas);
    }

    canvas.restoreToCount(saveCount);
}

原生的switchText是在thumb上的呢,所以自食其力吧,写两textView。
最简单的实现

CompoundButton.OnCheckedChangeListener mSwitchTutorListener = new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            mTvSwitchOff.setVisibility(View.GONE);
            mTvSwitchOn.setVisibility(View.VISIBLE);
        } else {
            mTvSwitchOff.setVisibility(View.VISIBLE);
            mTvSwitchOn.setVisibility(View.GONE);
        }
    }
};

这个是最简单的实现,然后你会发现,这个字唰一下出现唰一下没有真是一点也不美好,加点渐变动画吧。
你肯定会想到alpha动画的fadein和fadeout吧,要写个animation?不用不用,可以用view的crossfade animation:https://developer.android.com/training/animation/reveal-or-hide-view

使用起来非常简单:

CompoundButton.OnCheckedChangeListener mSwitchTutorListener = new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        mTvSwitchOff.setVisibility(View.VISIBLE);
        mTvSwitchOn.setVisibility(View.VISIBLE);
        if (isChecked) {
            mTvSwitchOff.animate().alpha(0f).setDuration(50).setListener(null);
            mTvSwitchOn.animate().alpha(1f).setDuration(250).setListener(null);
        } else {
            mTvSwitchOff.animate().alpha(1f).setDuration(250).setListener(null);
            mTvSwitchOn.animate().alpha(0f).setDuration(50).setListener(null);
        }
    }
};

这样我们就实现了渐变退出和进入啦,世界美好许多。
这个有个事情要注意的是,动画的终态如果是alpha等于0,下次你要再显示它记得把alpha值给设回来。我一开始就忘记了,Visibility半天没改回来一脸懵。

相关文章

  • Widget Switch UI定制

    我们知道自定义控件是最直接的方式,但是我想要的其实就是原生的switch的功能,仅仅是样式不同,所以去造一个哪怕是...

  • Flutter之Widget和Element

    一、Widget Flutter是移动UI框架,Widget组件是UI的基础。 它们都是抽象类,继承Widget,...

  • K01-02:Kivy的Widget组件

    基本上Kivy中的UI组件都是继承Widget,掌握好Widget就基本上掌握了UI组件的使用。Widget的设计...

  • Flutter Container Widget 布局详解

    在Flutter中,号称一切皆widget,手势是Widget,动画是Widget,UI更是Widget,今天我们...

  • Switch

    Android UI(Switch)详解

  • Flutter中的Widget

    Widget是什么? Widget是描述UI元素Element的配置数据;一个Widget可以对应多个Elemen...

  • Flutter 学习 ---- Widget

    万事皆 Widget Flutter 的核心思想是用 widget 来构建你的 UI 界面。 Widget 描述了...

  • Flutter Widget生命周期详解

    1 Widget 简介 在Flutter中,一切皆是Widget(组件),Widget的功能是“描述一个UI元素的...

  • Flutter-UI

    一、Widget在flutter中大部分类都是继承于widget,widget的作用就是描述一个UI的配置数据。可...

  • Flutter 学习 - 功能类Widget

    前言 功能类的Widget指的是非UI的Widget,具有一定的功能性,Flutter中有很多功能类的Widget...

网友评论

      本文标题:Widget Switch UI定制

      本文链接:https://www.haomeiwen.com/subject/jnhyvftx.html