<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 數據綁定基礎類使用 包引用: * ui庫: `compile "com.healthmall.android:healthmall-core-ui:2.0.0-beta1"` * 基礎頁面庫: `compile "com.healthmall.android:basemodule:2.0.0-beta1"` ## 普通頁面 以往的頁面,Activity或Fragment等,都是繼承`AbstractMvpXXXX`的,在使用數據綁定時,需要繼承`AbstractDataBindingXXX`,總體跟MVP的使用上沒多大區別,只是多了一個`<B extends ViewDataBinding>`的泛型成員,用于綁定變量。當實現的頁面有需要`presenter`的時候,我們還自動進行了`presenter`的綁定(需要xml中定義好`presenter`變量): public abstract class AbstractDataBindingActivity<T extends BasePresent, B extends ViewDataBinding> extends AbstractMvpActivity<T> implements BaseView { protected B binding; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); if (presenter != null) { binding.setVariable(com.gzdxjk.ihealth.basemodule.BR.presenter, presenter); } } @CallSuper @Override public void dealOnForemost(Bundle savedInstanceState) { super.dealOnForemost(savedInstanceState); binding = DataBindingUtil.setContentView(this, setContentView()); } @Override protected void onDestroy() { super.onDestroy(); binding.unbind(); } } 以上就是基礎類的全部代碼。使用示例略。 ## 列表頁面 以往的列表頁都是通過繼承`BaseLoadMoreAdapter`,然后在`onBindViewHolder`方法里面完成數據綁定。因為新版本需要在xml中完成數據綁定,所以我們有了一個新的基礎綁定適配器`BaseDataBindingAdapter`,大大的簡化了列表開發中的代碼量。同時提供了一個接口`BindItem`,用以修飾綁定到列表的VM,并要求其提供一個對應布局layout。得益于此接口,列表可以輕松的處理多種不同類型的VM。`BaseLoadMoreAdapter`為使用`BindItem`的列表提供了構造函數的支持。 `BaseDataBindingAdapter`依然保留與舊的接口相似的初始化方式(`public BaseAdapter(Context context, int layout,List<?> list)`)提供默認統一的布局文件,但不再需要提供泛型限制(因為有數據綁定的動態變量設置能力),即Adapter現在可以接受任何類型的數據,而不管數據是否實現`BindItem`。即便如此,我希望大家不要在使用舊的初始化方式的時候,再往列表添加/替換`BindItem`接口類型的數據(目前是可行);或者是使用新的初始化方式的時候,添加/替換非`BindItem`接口類型的數據(不可行,會報錯)。推薦使用新的構造函數和新的`BindItem`接口。下面是示例: * 使用`BindItem`接口實現統一類型的列表: VM實現`BindItem`接口: public class DataBindListItemInfoVM implements BindItem { ... @Override public int getBindingLayout(){ return R.layout.your_layout; } } 一般情況下不需要額外編寫一個類去實現`BaseDataBindingAdapter`,寥寥數行代碼就可以完成: BaseDataBindingAdapter adapter = new BaseDataBindingAdapter(getApplicationContext(), bindingVMs) { @Override protected void bindPresenter(BaseBindingViewHolder holder, ViewDataBinding bind) { bind.setVariable(BR.presenter, value); } }; 上面`bindPresenter`方法,是一個供以綁定除了數據以外的變量的模版方法,如果需要不需要任何處理,那么整個適配器一行就可以完成。除了這個模版方法以外,`changeViewSize`模版方法同樣保留,其他例如`onClickHook`等方法由于數據綁定或者其他歷史原因,都無需保留。 * 使用`BindItem`實現多種類型的列表方式和上面方法完全一致,在構造、添加/替換列表元素的時候,去添加你實現了`BindItem`接口的實際的VM即可。 * 使用舊的構造方式實現統一類型的列表,與舊的適配器相比,基本不再需要額外編寫一個類,同樣簡潔的完成了: BaseDataBindingAdapter adapter = new BaseDataBindingAdapter(getApplicationContext(), R.layout.your_layout, bindingVMs) { }; ## 局部頁面元素綁定 目前我們沒有一個基礎的View來實現我們的MVP的V接口,所以局部的視圖元素綁定,直接用綁定庫提供生成的的綁定類去inflate即可,具體參考數據綁定教程。 # 項目中的MVPVM規則 與從MVC轉換到MVP不同,我們的MVPVM可以看作只是MVP架構的一個數據綁定能力的補充和規范。也沒必要有了databinding就一定要用MVVM,這只是一個工具。 MVPVM中M、V、P三者的角色和作用與MVP中一致,而VM則是充當一個數據轉換(Transfer Object)和綁定的角色,實際上講單元測試的時候,我已經向大家提出過VM這一點,所以單元測試的編寫也是遵循我們目前的方式。下圖箭頭表示它們之間數據的流動方向: Model ↓ ↑ Presenter ↓ ↑ ViewModel ↓ View 為了實現一些代碼上的統一和精簡,以及保持項目的可讀性和可維護性,需要對使用數據綁定的使用進行必要的規范,暫時有以下幾點: * 禁止在布局xml中包含任何業務邏輯,不允許表達式使用各種`+ - * | & instanceOf`等等符號; * 禁止直接把接口數據作為ViewModel使用!禁止接口數據實現`BindItem`接口!; * 為了統一使用`BaseDataBindingAdapter`,列表項的布局文件中`<variable>`變量標簽的`name`屬性**必須**是`item`。同理,使用我們的`AbstractDataBindingXXXX`的頁面布局,事件處理的`<variable>`變量標簽必須命名為`presenter`; * 禁止私自自定義控件的已有屬性,其他自定義屬性必須有統一的文檔維護(下面的章節)。自定義控件的自定義屬性方法必須寫在控件類里面,屬性名不能包含任何縮寫; * 嚴禁為基礎通用控件設置任何業務相關的非通用自定義屬性; # 項目中的屬性封裝 得益于databinding庫提供的自定義屬性設置器功能,使我們有能力通過簡單的屬性設置實現我們想要的效果,從而減少重復代碼的編寫。但同時因為自定義屬性是通過`@BindAdapter`注解來實現,編譯器生成代碼的時候無須關心注解來源。為了防止各種不明所以的屬性滿天飛,必須有統一的文檔維護和規則去限制,避免它成為一把傷人的劍。 通過自動設置器可以設置的屬性不再闡述,以下是我們的庫中已有的自定義屬性封裝: * 流式布局`FlowLayout`中的`child_layout`和`items`屬性,同時設置它們即可以填充布局。下面是它們對應的屬性和方法定義: @BindingAdapter({"bind:child_layout", "bind:items"}) public static void bindTextItem(FlowLayout flowLayout, int childLayoutId, List<String> itemList) { flowLayout.addTextTag(childLayoutId, itemList); } * 待補充。 希望大家在項目的過程中,遇到常用的可以自定義的部分積極提出,我再去一一實現。例如需要WebView增加一個url屬性,去自動加載設置的地址(因為WebView加載的方法是`loadData`,無法通過自動設置器設置),又如給ViewPager的`addOnPageChangeListener`方法封裝自定義屬性(ViewPager確實有`setOnPageChangeListener`方法,但已經過時),來進行代碼精簡。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看