UI组件开发之带loading的button

一、概述

最近项目重构,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>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要使用 Element UI 中的 Loading 组件,您需要先安装 Element UI 并引入相应的模块。以下是一个简单的示例,展示了如何在 Vue.js 中使用 Element UILoading 组件: 首先,确保您已经安装了 Vue.js 和 Element UI。您可以通过以下命令使用 npm 进行安装: ``` npm install vue npm install element-ui ``` 接下来,在您的 Vue 组件中,导入 Loading 组件: ```javascript import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); ``` 然后,您可以在组件中使用 Loading 组件了。例如,在一个按钮的点击事件中显示一个加载状态: ```html <template> <div> <el-button @click="showLoading">显示加载状态</el-button> <el-loading v-if="loading" :text="loadingText" :background="loadingBackground" :spinner="loadingSpinner"></el-loading> </div> </template> <script> export default { data() { return { loading: false, loadingText: '加载中...', // 可选,自定义加载文字 loadingBackground: 'rgba(0, 0, 0, 0.7)', // 可选,自定义加载背景色 loadingSpinner: 'el-icon-loading', // 可选,自定义加载图标 }; }, methods: { showLoading() { this.loading = true; // 模拟异步操作 setTimeout(() => { this.loading = false; }, 3000); }, }, }; </script> ``` 以上代码中,`el-loading` 组件通过 `v-if` 控制是否显示加载状态。您可以根据需要自定义加载文字、背景色和加载图标,通过相应的属性进行设置。 请注意,以上示例仅为简单演示如何使用 Element UILoading 组件。您还可以通过查阅 Element UI 的官方文档来了解更多关于 Loading 组件的用法和配置选项。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值