詳解Android控件狀態(tài)依賴框架
在生產(chǎn)型Android客戶端軟件(企業(yè)級應(yīng)用)開發(fā)中,界面可能存在多個輸入(EditText)和多個操作(MotionEvent和KeyEvent),且操作依賴于輸入的狀態(tài)。如下圖所示的場景:

設(shè)定圖中
- 確認操作依賴于商品編碼和儲位的狀態(tài)
- 跳過操作不依賴于輸入狀態(tài)
- 登記差異操作依賴于儲位和數(shù)量的狀態(tài)
輸入框有三種狀態(tài):
- 待輸入;
- 待校驗;
- 校驗成功。
操作需要當其依賴的輸入數(shù)據(jù)校驗成功,才能執(zhí)行。
如果在Activity中去判斷輸入框狀態(tài),那么實際需要調(diào)用(3個輸入框)*(3種狀態(tài))*(3個按鈕) = 27個 if 判斷,對于狀態(tài)的維護將使得整個程序可維護性極差,并隨著輸入和操作的增加,維護的狀態(tài)呈指數(shù)增長。
通過對這種場景的抽象,實現(xiàn)了Android控件狀態(tài)依賴框架,其使用方法如下:
使用方法:
1、布局文件引用WatchEditText和WatchButton
<com.android.yhthu.viewdependency.view.WatchEditText 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"/> <com.android.yhthu.viewdependency.view.WatchButton 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("數(shù)量")
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、直接執(zhí)行onClick和onEditorAction(修改狀態(tài))
@Override
public void onClick(View v) {
if (v == buttonSearch1) {
Toast.makeText(this, "調(diào)接口", 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判斷各個輸入控件的狀態(tài)。
@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模擬調(diào)用軟件的Enter進行校驗,這里需要注意通過editQuery1.complete()修改該EidtText的狀態(tài)。
實現(xiàn)原理
整個框架分為三個package:annotation、state和view。
1、在annotation中定義ViewName和ViewDependency注解,分別用于WatchEditText和WatchButton。ViewName指定WatchEditText控件在業(yè)務(wù)中的名稱,ViewDependency指定WatchButton依賴的WatchEditText控件;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ViewDependency {
ViewName name() default @ViewName;
String[] dependency() default {};
}
2、在state中通過狀態(tài)模式定義Enter、Verify、Complete,其基類為抽象類Operator,定義方法operator;
public abstract class Operator {
// 操作對應(yīng)的上下文
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]為空,不允許執(zhí)行[%s]", viewName, operatorName),
Toast.LENGTH_SHORT).show();
return false;
}
}
3、WatchEditText和WatchButton定義控件的依賴關(guān)系。WatchEditText實現(xiàn)ViewState接口,其包含三種狀態(tài)的轉(zhuǎn)換方法。
public interface ViewState {
void enter();
void verify();
void complete();
}
以上,博客園對markdown支持的不太好,無法添加注釋(/* */),如需查看源碼,請移步Github地址:https://github.com/yhthu/AndroidViewDependency.git
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android 啟動模式FLAG_ACTIVITY_CLEAR_TOP案例詳解
這篇文章主要介紹了Android 啟動模式FLAG_ACTIVITY_CLEAR_TOP案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08
Android開發(fā)中RecyclerView組件使用的一些進階技講解
RecyclerView是Android 5.0以來新加入的一個組件,基本上全面優(yōu)于ListView,這里我們將來關(guān)注Android開發(fā)中RecyclerView組件使用的一些進階技講解:2016-06-06
Android開發(fā)筆記之:一分鐘學會使用Logcat調(diào)試程序的詳解
本篇文章是對Android中Logcat調(diào)試程序的使用進行了詳細的分析介紹,需要的朋友參考下2013-05-05
Android編程實現(xiàn)加載等待ProgressDialog的方法
這篇文章主要介紹了Android編程實現(xiàn)加載等待ProgressDialog的方法,實例分析了Android中加載等待類ProgressDialog的具體使用方法,需要的朋友可以參考下2015-12-12
Android中使用Intent在Activity之間傳遞對象(使用Serializable或者Parcelable)的
這篇文章主要介紹了 Android中使用Intent在Activity之間傳遞對象(使用Serializable或者Parcelable)的方法的相關(guān)資料,需要的朋友可以參考下2016-01-01
Android Listview中顯示不同的視圖布局詳解及實例代碼
這篇文章主要介紹了Android Listview中顯示不同的視圖布局詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02

