UI组件开发之带loading的button

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/S43565442/article/details/83618048

一、概述

最近项目重构,UI/UE提出要开发组件便于以后的使用和管理。
buttons组件要求有填充按钮,线框按钮,文字按钮三种,但本文只实现填充按钮,其他同理。功能如下:

  1. button默认包含常规,click,loading,disable状态
  2. 按钮文案始终居中展示,可独立调整参数:组件宽度、背景颜色、文字颜色,字号
  3. 文字30px #FFFFFF 黑色按钮1C1717 Click #605D5D 不可用按钮#CCCCCC
    在这里插入图片描述
    注释:不知为何,动图需要点击一下才能观看

二、开始构思并编码

先抛开按钮不同状态下的颜色变化(因为这个可以设置按钮background进行调整),要求可以自由调整组件长宽,文字文案,文字颜色,字号,loading状态的旋转按钮。那么,我们就可以开始着手写个超简单的自定义view来实现基础功能了。
1.首先需要自定义哪些属性?
文字文本,文字颜色,文字大小,button背景色。

private void loadAttributes(AttributeSet attrs, int defStyleRes) {
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.publicAppButton, defStyleRes, 0);
        text = a.getText(R.styleable.publicAppButton_public_button_text);
        textColor = a.getColorStateList(R.styleable.publicAppButton_public_button_textColor);
        if (textColor == null) {
            textColor = new ColorStateList(new int[][]{{android.R.attr.state_enabled}}, new int[]{getResources().getColor(R.color.public_color_FFFFFF)});
        }
        textSize = a.getDimensionPixelSize(R.styleable.publicAppButton_public_button_textSize, getResources().getDimensionPixelSize(R.dimen.public_font_15sp));
        background = a.getResourceId(R.styleable.publicAppButton_public_button_background, R.drawable.cart_button_black_background);
        a.recycle();
    }

2.接着把这些获取到的属性相应赋值即可。然后就是一个简单的旋转动画实现loading了。

private RotateAnimation mRegisteRotateAnimation;
public void startAnim() {
        if (mRegisteRotateAnimation == null) {
            mRegisteRotateAnimation = new RotateAnimation(0f, 359f, Animation.RELATIVE_TO_SELF,
                    0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            mRegisteRotateAnimation.setDuration(300);//设置动画持续时间
            LinearInterpolator lin = new LinearInterpolator();
            mRegisteRotateAnimation.setInterpolator(lin);
            mRegisteRotateAnimation.setRepeatCount(-1);//设置重复次数
            mRegisteRotateAnimation.setFillAfter(true);//动画执行完后是否停留在执行完的状态
            mRegisteRotateAnimation.setStartOffset(10);//执行前的等待时间
        }
     app_button_loading.startAnimation(mRegisteRotateAnimation);
    }

现在超简单的自定义view就已经实现完成了,至于要求不同状态下不同颜色直接使用选择器来完成就ok了。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--按下状态下颜色-->
    <item android:drawable="@drawable/cart_button_black_pressed" android:state_enabled="true" android:state_pressed="true" />
    <!--选择状态下颜色-->
    <item android:drawable="@drawable/cart_button_black_pressed" android:state_enabled="true" android:state_selected="true" />
    <!--正常状态下颜色-->
    <item android:drawable="@drawable/cart_button_black_normal" android:state_enabled="true" />
    <!--不可使用状态下颜色-->
    <item android:drawable="@drawable/cart_button_disable" />
</selector>

最后,使用方法:

<com.syr.view.AppButton
                android:id="@+id/login_submit"
                android:layout_width="match_parent"
                android:layout_height="@dimen/user_ui_45dp"
                android:layout_marginTop="@dimen/user_ui_13dp"
                android:enabled="false"
                android:gravity="center"
                app:public_button_background="@drawable/cart_button_black_background"
                app:public_button_text="@string/user_login"
                app:public_button_textColor="@color/public_color_FFFFFF"
                app:public_button_textSize="@dimen/public_font_15sp" />

代码中使用:

//修改button是否可用
loginSubmit.setEnabled(false);
//开始或结束执行旋转loading动画
loginSubmit.startAnim();
loginSubmit.stopAnim();

附录:
自定义AppButton源码:

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.secoo.commonres.R;

/**
 * 带loading图片的button
 */
public class AppButton extends FrameLayout {

    public AppButton(@NonNull Context context) {
        super(context);
        init(null, 0);
    }

    public AppButton(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public AppButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public AppButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs, defStyleRes);
    }

    @Override
    public void setEnabled(boolean enabled) {
        app_button_layout.setEnabled(enabled);
        super.setEnabled(enabled);
    }

    TextView app_button_text;
    ImageView app_button_loading;
    FrameLayout app_button_layout;

    private void init(AttributeSet attrs, int defStyleRes) {
        loadAttributes(attrs, defStyleRes);

        LayoutInflater.from(getContext()).inflate(R.layout.public_cart_app_button, this, true);
        app_button_layout = findViewById(R.id.app_button_layout);
        app_button_text = findViewById(R.id.app_button_text);
        app_button_loading = findViewById(R.id.app_button_loading);

        app_button_text.setText(text);
        app_button_text.setTextColor(textColor);
        app_button_text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        app_button_text.setEnabled(isEnabled());
        app_button_layout.setBackgroundResource(background);
    }

    private CharSequence text;
    private ColorStateList textColor;
    private float textSize;
    private int background;

    public void setTextColor(int textColor) {
        if (app_button_text == null) return;
        app_button_text.setTextColor(textColor);
    }

    public void setBackgroundResource(int backgroundResource) {
        if (app_button_layout == null) return;
        app_button_layout.setBackgroundResource(backgroundResource);
    }

    public void setText(CharSequence text) {
        this.text = text;
        app_button_text.setText(text);
    }

    public String getText() {
        if (app_button_text == null) return "";
        return app_button_text.getText().toString().trim();
    }

    private RotateAnimation mRegisteRotateAnimation;

    public void startAnim() {
        if (app_button_text != null) app_button_text.setVisibility(INVISIBLE);
        if (app_button_loading != null) app_button_loading.setVisibility(VISIBLE);
        if (mRegisteRotateAnimation == null) {
            mRegisteRotateAnimation = new RotateAnimation(0f, 359f, Animation.RELATIVE_TO_SELF,
                    0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            mRegisteRotateAnimation.setDuration(300);//设置动画持续时间
            LinearInterpolator lin = new LinearInterpolator();
            mRegisteRotateAnimation.setInterpolator(lin);
            mRegisteRotateAnimation.setRepeatCount(-1);//设置重复次数
            mRegisteRotateAnimation.setFillAfter(true);//动画执行完后是否停留在执行完的状态
            mRegisteRotateAnimation.setStartOffset(10);//执行前的等待时间
        }
        app_button_loading.startAnimation(mRegisteRotateAnimation);
    }

    public void stopAnim() {
        if (app_button_text != null) app_button_text.setVisibility(VISIBLE);
        if (app_button_loading != null) app_button_loading.setVisibility(GONE);
        if (mRegisteRotateAnimation != null) app_button_loading.clearAnimation();
    }

    private void loadAttributes(AttributeSet attrs, int defStyleRes) {
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.publicAppButton, defStyleRes, 0);
        text = a.getText(R.styleable.publicAppButton_public_button_text);
        textColor = a.getColorStateList(R.styleable.publicAppButton_public_button_textColor);
        if (textColor == null) {
            textColor = new ColorStateList(new int[][]{{android.R.attr.state_enabled}}, new int[]{getResources().getColor(R.color.public_color_FFFFFF)});
        }
        textSize = a.getDimensionPixelSize(R.styleable.publicAppButton_public_button_textSize, getResources().getDimensionPixelSize(R.dimen.public_font_15sp));
        background = a.getResourceId(R.styleable.publicAppButton_public_button_background, R.drawable.cart_button_black_background);
        a.recycle();
    }
}

AppButton布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/app_button_layout"
    android:background="@drawable/cart_button_yellow_background">

    <TextView
        android:id="@+id/app_button_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:enabled="false"
        android:gravity="center"
        android:textColor="@color/public_color_FFFFFF"
        android:textSize="@dimen/public_font_15sp" />

    <ImageView
        android:id="@+id/app_button_loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@mipmap/submmit_loading"
        android:visibility="gone" />
</FrameLayout>

猜你喜欢

转载自blog.csdn.net/S43565442/article/details/83618048
今日推荐