android 的控件的状态,详解Android控件状态依赖框架

在生产型Android客户端软件(企业级应用)开发中,界面可能存在多个输入(EditText)和多个操作(MotionEvent和KeyEvent),且操作依赖于输入的状态。如下图所示的场景:

0e2f590da9149e7b9c8f167a04235fb1.png

设定图中

确认操作依赖于商品编码和储位的状态

跳过操作不依赖于输入状态

登记差异操作依赖于储位和数量的状态

输入框有三种状态:

待输入;

待校验;

校验成功。

操作需要当其依赖的输入数据校验成功,才能执行。

如果在Activity中去判断输入框状态,那么实际需要调用(3个输入框)*(3种状态)*(3个按钮) = 27个 if 判断,对于状态的维护将使得整个程序可维护性极差,并随着输入和操作的增加,维护的状态呈指数增长。

通过对这种场景的抽象,实现了Android控件状态依赖框架,其使用方法如下:

使用方法:

1、布局文件引用WatchEditText和WatchButton

android:id="@+id/edit_query_1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:tag="editQuery1"

android:imeOptions="actionNext"

android:hint="商品编码"

android:inputType="number"/>

android:id="@+id/search_button_1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:tag="buttonSearch1"

android:text="确认" />

由于Library Module中的控件id不是常量(可参考ButterKnife对Library Module的支持采用R2的原因),这里采用了tag的方式。

2、在Activity中通过注解申明依赖

@ViewName("商品编码")

private WatchEditText editQuery1;

@ViewName("储位")

private WatchEditText editQuery2;

@ViewName("数量")

private WatchEditText editQuery3;

@ViewDependency(name = @ViewName("确认"), dependency = {"editQuery1", "editQuery2"})

private WatchButton buttonSearch1;

@ViewDependency(name = @ViewName("跳过")/*不依赖输入*/)

private WatchButton buttonSearch2;

@ViewDependency(name = @ViewName("登记缺货"), dependency = {"editQuery2", "editQuery3"})

private WatchButton buttonSearch3;

ViewName定义控件名称,ViewDependency中dependency指定其依赖的控件tag。

3、直接执行onClick和onEditorAction(修改状态)

@Override

public void onClick(View v) {

if (v == buttonSearch1) {

Toast.makeText(this, "调接口", Toast.LENGTH_SHORT).show();

} else if (v == buttonSearch2) {

Toast.makeText(this, "跳下一页", Toast.LENGTH_SHORT).show();

} else if (v == buttonSearch3) {

Toast.makeText(this, "登记缺货", Toast.LENGTH_SHORT).show();

}

}

可以看出,这里并没有通过if判断各个输入控件的状态。

@Override

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

if (actionId == EditorInfo.IME_ACTION_NEXT && v == editQuery1

&& (query1Str = editQuery1.getText().toString()).isEmpty()) {

if (query1Str.equals("12345")) {

editQuery1.complete();

return true;

}

}

// 省略代码

return false;

}

onEditorAction模拟调用软件的Enter进行校验,这里需要注意通过editQuery1.complete()修改该EidtText的状态。

实现原理

整个框架分为三个package:annotation、state和view。

1、在annotation中定义ViewName和ViewDependency注解,分别用于WatchEditText和WatchButton。ViewName指定WatchEditText控件在业务中的名称,ViewDependency指定WatchButton依赖的WatchEditText控件;

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface ViewDependency {

ViewName name() default @ViewName;

String[] dependency() default {};

}

2、在state中通过状态模式定义Enter、Verify、Complete,其基类为抽象类Operator,定义方法operator;

public abstract class Operator {

// 操作对应的上下文

protected Context context;

// 操作

public abstract boolean operator(String operatorName, String viewName);

}

public class Enter extends Operator {

private static Enter enter;

private Enter(Context context) {

this.context = context;

}

public static Enter getInstance(Context context) {

if (enter == null) {

enter = new Enter(context);

}

return enter;

}

@Override

public boolean operator(String operatorName, String viewName) {

Toast.makeText(context, String.format("[%s]为空,不允许执行[%s]", viewName, operatorName),

Toast.LENGTH_SHORT).show();

return false;

}

}

3、WatchEditText和WatchButton定义控件的依赖关系。WatchEditText实现ViewState接口,其包含三种状态的转换方法。

public interface ViewState {

void enter();

void verify();

void complete();

}

以上,博客园对markdown支持的不太好,无法添加注释(/* */),如需查看源码,请移步Github地址:https://github.com/yhthu/AndroidViewDependency.git

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值