他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了

注: 本篇文章內容有點多,要文章跟demo一起看才相得益彰。希望大家能耐心看完,之後,你會覺得該控件真心贊,幫你項目開發更加精簡,建議收藏

先一句話描述這個控件的功能:

將BaseRecyclerViewAdapterHelper與MVVM模式完美結合起來,實現更加方便,快捷的列表加載,幫您省去大量的時間寫各種複雜的適配器,使項目的代碼結構更加簡潔優雅。

曾今有句Android界的讖言:Android UI開發只要會用列表就頂半邊天。我們日常開發中,用到的列表是何其多,大量的列表,就意味著大量的適配器,更意味著更大量的bean類、item佈局和複雜繁多的邏輯,所以,有一套方便,快捷的列表模板是何其重要。現在都已經9020年了,相信大家已經從MVC模式,過渡MVP模式,到MVVM模式了吧,如果還沒用MVVM模式的,你就out了!(這段是廢話,可以省略不看)


因為我公司項目是MVVM模式的,然後以前一個老Android同事寫過一個控件,就是能很方便地將列表跟viewModel綁定在一起,使得代碼精簡很多。不過也有一些不足,例如不支持多佈局的綁定,然後我這邊就站在巨人的肩膀上,將控件完善一下。

使用本控件的前提,項目使用MVVM開發模式,列表適配器是使用BRVAH的

BaseRecyclerViewAdapterHelper萬能適配器(本控件支持非使用AndroidX和使用AndroidX的條件,賊貼心)。


目錄

  1. 項目地址
  2. 首頁調用展示
  3. 如何依賴
  4. 調用BRVAH自帶的動畫,及line模式
  5. 自定義動畫調用設置,及grid模式
  6. 多佈局實現,item實現MultipleItem。
  7. 多佈局實現,item不實現MultipleItem的調用方式
  8. 如何用databinding模式添加多個頭部和腳部,並且有各自事件
  9. 空佈局及下拉刷新
  10. 側滑刪除
  11. 長按拖動
  12. 側滑刪除和長按拖動相結合
  13. ExpandableItem,可擴展的多佈局使用
  14. 下拉刷新,上拉加載
  15. 仿聊天界面,從下到上加載數據
  16. 雙列表使用,仿外賣(甚至可以更多列表)
  17. 支持使用自己的適配器來調用
  18. 支持列表側滑


地址


廢話不多說,先上Github的demo。從demo中,就可以看到項目結構精簡


如果你項目中,是不使用AndroidX的,請食用該地址:

https://github.com/CaesarShao/CSBrvahBinding


如果項目中使用了AndroidX的,請食用該地址:

https://github.com/CaesarShao/CSBrvahBindingX


默認習慣,先上圖再說,主要是裡面的代碼邏輯:


首先,大家可以看我library中的CSBrvahBindingAdapter這個類,裡面就是通過BindingAdapter的方法,將列表跟適配器綁定在一起。然後是CSItemBindingAdapter這個適配器,這就是本控件核心的適配器了,在這個adapter中,調用了databinding的綁定方法。然後大家可以看BaseBindingViewModel這個類,這個是viewModel的基類,裡面將一些屬性和方法定義,還有仿網絡請求的動作跟列表結合。後面邊寫邊解釋。


還有再提醒一下,大家看文章,要跟demo結合起來食用,不然可能會看得有點模糊。


首頁樣式


例子列表截圖:


首頁列表調用方式:


非常簡單,這個是Activity的內容,只要綁定viewModel,然後調用model.load(),加載列表的數據就可以了

<code>
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil
.setContentView<activitymainbinding>(this, R.layout.activity_main)
val model = MainViewModel()
binding.vm = model
model.load()
CSLog.Open()//測試用開啟日誌
}
}/<activitymainbinding>/<code>


首頁的viewModel:


<code>public class MainViewModel extends BaseBindingViewModel<maindata> {

@Override//獲取綁定的佈局和數據
protected Map<integer> getItemBinding() {
Map<integer> mp = new HashMap<>();
mp.put(0, new CSBravhItemBinding(BR.bean, R.layout.item_main, BR.action, new Action()));
return mp;
}

@Override//已經集成好的加載數據的方法
public void load() {
load(getData());
}

//另外的點擊事件動作,我為了方便這樣寫,也可以mvvm模式默認是寫在data數據中
public class Action implements CSAction1<maindata> {
@Override
public void call(MainData param) {
Intent intent = new Intent(FramGroble.INSTANCE.getTopActivity(), param.activity);
FramGroble.INSTANCE.getTopActivity().startActivity(intent);
}
}

//模擬網絡請求的數據
private Flowable<list>> getData() {
return Flowable.create(new FlowableOnSubscribe<list>>() {
@Override
public void subscribe(FlowableEmitter<list>> emitter) throws Exception {
ArrayList<maindata> data = new ArrayList<>();
data.add(new MainData("Animation,line,加載動畫效果", AnimationActivity.class));
data.add(new MainData("Animation,Grid,加載自定義動畫效果", AnimationCustomActivity.class));
data.add(new MainData("MultipleItem,line,多佈局", MultipleLineActivity.class));
data.add(new MainData("非MultipleItem,Grid,多佈局,(不想繼承MultiItemEntity,用自己的bean類)", NonMultipleActivity.class));
data.add(new MainData("添加多個頭部和尾部,有各自的數據,優雅", HeadFootActivity.class));

data.add(new MainData("空佈局及下拉刷新", EmptyRefreshActivity.class));
data.add(new MainData("側滑刪除", SwipeActivity.class));
data.add(new MainData("長按拖動,多佈局", DragActivity.class));
data.add(new MainData("可擴展的,多佈局", ExpandActivity.class));
data.add(new MainData("下拉刷新,上拉加載", LoadMoreLineActivity.class));
data.add(new MainData("聊天界面,下拉加載", LoadMoreChatActivity.class));
data.add(new MainData("2個列表的綁定,仿外賣", TwoListActivity.class));
data.add(new MainData("用自己的適配器(繼承萬能適配器)", CustomAdapterActivity.class));
emitter.onNext(data);
emitter.onComplete();
}
}, BackpressureStrategy.BUFFER);
}

@Override//設置自定義item的間距
public RecyclerView.ItemDecoration onitemDecoration() {
return new NormalLineDecoration(30, true);
}
}/<maindata>/<list>/<list>/<list>/<maindata>/<integer>/<integer>/<maindata>/<code>


viewModel中,沒有複雜的邏輯調用,只有一些回調。只要繼承BaseBindingViewModel<>,裡面設置數據的泛型,(多佈局泛型下面說明),通過getItemBinding()這個回調,設置每個item的佈局與綁定的數據(可以綁定多個data),其中map的鍵就是itemType的類型,如果是單佈局,寫0就可以了,如果是多佈局,按照itemType類型寫,mainActivity中的item,還另外綁定了一個事件Action,我這邊是設置為item的點擊事件。load()中的回調,調用了load(getData())來加載數據(我這邊使用rxjava來模擬數據的加載,現在的項目基本都是用retrofit和rxjava結合獲取網絡請求)。最下面的onitemDecoration()回調,是設置recyclerview的item間距。是不是很乾淨整潔,邏輯一目瞭然。


這時,就會有人問:哎呀,古誠欺啊,為什麼沒有看到列表的適配器啊。嘿嘿,適配器已經封裝在BaseBindingViewModel中了,別急,後面會一一講到,接下來,來看佈局文件,超級簡單:

<code>
<layout> xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
<variable> name="vm"
type="com.caesar.brvahbinding.MainViewModel" />
/<variable>/<data>

<linearlayout> android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<androidx.recyclerview.widget.recyclerview> android:layout_width="match_parent"
android:layout_height="match_parent"
app:cs_brvah_Decoration="@{vm.itemDecoration}"
app:cs_brvah_adapter="@{vm.bindingAdapter}"
/>
/<androidx.recyclerview.widget.recyclerview>/<linearlayout>
/<layout>/<code>


databinging的格式就不多說了,其中,app:cs_brvah_adapter="@{vm.bindingAdapter}",就是綁定viewModel中的適配器,因為在BaseBindingViewModel這個基類中已經初始化好了,所以直接引用就可以了。app:cs_brvah_Decoration="@{vm.itemDecoration}"這個是綁定Decoration,也就是設置每個item的間隔,在上面的viewModel中,不是有onitemDecoration()回調麼,就可以自己定製。


怎麼樣,是不是特別地簡便。目前只是簡單地說明一個,接下來會慢慢地講解,越後面,本控件的便捷之處就越會體現,有不懂的可以集合例子看,就會明白的。


怎麼引用該控件


這時就會有人問:哎呀,古誠欺啊,那該怎麼依賴這麼方便快捷的控件呢?


很簡單,在根build.gradle中:

<code>allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}/<code>


然後,如果你項目是使用AndroidX的,就引用該地址:

<code>dependencies {
implementation 'com.github.CaesarShao:CSBrvahBindingX:1.0.8'
}/<code>

如果項目不支持AndroidX的,就引用:

<code>dependencies {
implementation 'com.github.CaesarShao:CSBrvahBinding:1.0.8'
}/<code>


還有,因為我依賴的萬能適配器的版本是com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50,所以大家項目中的版本最好不低於2.9.50。不然可能會有兼容問題。


是不是賊貼心,都給大家考慮到了.好接下來我就一一講解具體的調用方式,請大家耐心看下去。


調用BRVAH自帶的動畫及line模式


Activity的調用我就不講了,很簡單,大家看AnimationActivity這個類常規調用,先將代碼貼出來:


<code>public class AnimationViewModel extends BaseBindingViewModel<simpledata> {

public AdapterView.OnItemSelectedListener onItemClickListener = getOnItemCli();

//構造方法,裡面可以設置基礎屬性
public AnimationViewModel() {
super();
//該viewmodel是演示效果,實際在構造方法中,直接調用即可,

// animationType.set(BaseQuickAdapter.SLIDEIN_BOTTOM);
}

@Override
protected Map<integer> getItemBinding() {
Map<integer> mp = new HashMap<>();
mp.put(0, new CSBravhItemBinding(com.caesar.brvahbinding.BR.bean, R.layout.item_simple));
return mp;
}

@Override
public void load() {
load(CreateData.getSimpleData());
}

//這個是Spinner控件的OnItemSelectedListener的監聽,在佈局中綁定,當spinner使用時,會回調這個方法.
public AdapterView.OnItemSelectedListener getOnItemCli() {
return new AdapterView.OnItemSelectedListener() {

@Override
public void onItemSelected(AdapterView> parent, View view, int position, long id) {
switch (position) {
case 0:
animationType.set(BaseQuickAdapter.SLIDEIN_BOTTOM);
break;
case 1:
animationType.set(BaseQuickAdapter.ALPHAIN);
break;
case 2:
animationType.set(BaseQuickAdapter.SCALEIN);
break;
case 3:
animationType.set(BaseQuickAdapter.SLIDEIN_LEFT);
break;
case 4:
animationType.set(BaseQuickAdapter.SLIDEIN_RIGHT);
break;
}
}

@Override
public void onNothingSelected(AdapterView> parent) {

}
};
}

@Override

public RecyclerView.ItemDecoration onitemDecoration() {
return new NormalLineDecoration(30, true);
}
}
/<integer>/<integer>/<simpledata>/<code>


大家先看佈局文件,有一個

app:cs_brvah_animation="@{vm.animationType}",這個就是設置brvah自帶的動畫效果,當依賴好之後,只要在viewmodel的構造方法中設置,比如animationType.set(BaseQuickAdapter.SLIDEIN_BOTTOM);這樣調用就可以了,如果佈局中依賴過,它默認的動畫效果是BaseQuickAdapter.SLIDEIN_BOTTOM。


然後在RecyclerView中,綁定adapter之後,就是app:cs_brvah_adapter="@{vm.bindingAdapter}",會默認設置RecyclerView的顯示方式為LinearLayoutManager。


如何加載自定義動畫和GridLayoutManager呢


大家看AnimationCustomActivity這個界面,


<code>
<layout> xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<variable> name="vm"

type="com.caesar.brvahbinding.animation.AnimationCustomViewModel" />

<import>
/<variable>/<data>

<linearlayout> android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<button> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{vm.onBack}"
android:text="返回" />


<androidx.recyclerview.widget.recyclerview> android:layout_width="match_parent"
android:layout_height="match_parent"
app:cs_brvah_Decoration="@{vm.itemDecoration}"
app:cs_brvah_adapter="@{vm.bindingAdapter}"
app:cs_brvah_animation_custom="@{vm.customAnimation}"
app:cs_brvah_layoutManager="@{CSBrvahLayoutManager.grid(2)}" />
/<androidx.recyclerview.widget.recyclerview>/<button>/<linearlayout>
/<layout>/<code>
<code>public class AnimationCustomViewModel extends BaseBindingViewModel<simpledata> {

@Override
protected Map<integer> getItemBinding() {
Map<integer> mp = new HashMap<>();
mp.put(0, new CSBravhItemBinding(com.caesar.brvahbinding.BR.bean, R.layout.item_simple));
return mp;
}

@Override
public void load() {
load(CreateData.getSimpleData());
}

@Override
public RecyclerView.ItemDecoration onitemDecoration() {
return new GridSpacingItemDecoration(2, 30, true);
}

@Override//設置自定義動畫
public BaseAnimation onCustomAnimation() {
return new CustomAnimation();
}
}/<integer>/<integer>/<simpledata>/<code>


可以看到,佈局文件中,綁定了2個其他的東西,其中app:cs_brvah_animation_custom="@{vm.customAnimation}"就是綁定自定義動畫,在viewModel中的onCustomAnimation()回調中設置,我這邊copy了brvah官方的自定義動畫。在佈局文件中,還可以看到,我引入了<import>,在RecyclerView中,我調用,app:cs_brvah_layoutManager="@{CSBrvahLayoutManager.grid(2)}",這個就是將列表的顯示方式,設置為2格的GridLayoutManager,大家可以去看看CSBrvahLayoutManager這個類,裡面有設置各種LayoutManager的方法。


多佈局,實現MultipleItem


大家看MultipleLineActivity這個類,activity還

大家可以看到,佈局文件很簡單,跟首頁的基本一模一樣,在MultiLineViewModel中,繼承baseviewmodel時,要傳泛型為MultiItemEntity,可以看到,是不是跟其他的基本一毛一樣,然後每個item的data也都很簡單。


這時,就會有同學問了:誒呀,古誠欺啊,如果我想要我的item數據不實現MultiItemEntity怎麼辦?當然可以。


item不實現MultiItemEntity的多佈局

<code>public class MultiLineViewModel extends BaseBindingViewModel<multiitementity> {
@Override//多佈局根據data的itemtype返回的值,將綁定類型的寫上去
protected Map<integer> getItemBinding() {
Map<integer> mp = new HashMap<>();
mp.put(0, new CSBravhItemBinding(com.caesar.brvahbinding.BR.data, R.layout.item_multi_zero));
mp.put(1, new CSBravhItemBinding(com.caesar.brvahbinding.BR.data, R.layout.item_multi_one));
mp.put(2, new CSBravhItemBinding(com.caesar.brvahbinding.BR.data, R.layout.item_multi_two));
return mp;
}

@Override
public void load() {
load(getData());
}

private Flowable<list>> getData() {
return Flowable.create(new FlowableOnSubscribe<list>>() {
@Override
public void subscribe(FlowableEmitter<list>> emitter) throws Exception {
ArrayList<multiitementity> data = new ArrayList<>();
data.add(new MultiDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new MultiDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));
data.add(new MultiDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img2));
data.add(new MultiDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new MultiDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new MultiDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new MultiDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img2));
data.add(new MultiDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new MultiDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));
data.add(new MultiDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));
data.add(new MultiDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));

data.add(new MultiDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
emitter.onNext(data);
emitter.onComplete();
}
}, BackpressureStrategy.BUFFER);
}

@Override
public RecyclerView.ItemDecoration onitemDecoration() {
return new NormalLineDecoration(30, true);
}

}/<multiitementity>/<list>/<list>/<list>/<integer>/<integer>/<multiitementity>/<code>
<code><layout>    xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<variable> name="vm"
type="com.caesar.brvahbinding.multiple.MultiLineViewModel" />

/<variable>/<data>

<linearlayout> android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<button> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{vm.onBack}"
android:text="返回" />

<androidx.recyclerview.widget.recyclerview> android:layout_width="match_parent"
android:layout_height="match_parent"
app:cs_brvah_Decoration="@{vm.itemDecoration}"
app:cs_brvah_adapter="@{vm.bindingAdapter}"
app:cs_brvah_animation="@{vm.animationType}" />
/<androidx.recyclerview.widget.recyclerview>/<button>/<linearlayout>
/<layout>/<code>

大家可以看到,佈局文件很簡單,跟首頁的基本一模一樣,在MultiLineViewModel中,繼承baseviewmodel時,要傳泛型為MultiItemEntity,可以看到,是不是跟其他的基本一毛一樣,然後每個item的data也都很簡單。


這時,就會有同學問了:誒呀,古誠欺啊,如果我想要我的item數據不實現MultiItemEntity怎麼辦?當然可以。

item不實現MultiItemEntity的多佈局

<code>
<layout> xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable> name="vm"
type="com.caesar.brvahbinding.nonMultiple.NonMultiViewModel" />

<import>
/<variable>/<data>

<linearlayout> android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".nonMultiple.NonMultipleActivity">

<button> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{vm.onBack}"
android:text="返回" />

<androidx.recyclerview.widget.recyclerview> android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
app:cs_brvah_Decoration="@{vm.itemDecoration}"
app:cs_brvah_adapter="@{vm.bindingAdapter}"
app:cs_brvah_layoutManager="@{CSBrvahLayoutManager.grid(4)}"
app:cs_brvah_multiType="@{vm.multiTypeDelegat}"
app:cs_brvah_spansize="@{vm.spanSizeLookup}" />
/<androidx.recyclerview.widget.recyclerview>/<button>/<linearlayout>
/<layout>/<code>
<code>public class NonMultiViewModel extends BaseBindingViewModel<customdata> {
//在構造方法中,設置SpanSizeLookup,這個是每個item佔幾格的回調.MultiTypeDelegat這個是itemType的回調判斷了,如果不想繼承MultiItemEntity的話
//就要由該回調來判斷

public NonMultiViewModel() {
super();
setSpan(new BaseQuickAdapter.SpanSizeLookup() {
@Override
public int getSpanSize(GridLayoutManager gridLayoutManager, int i) {
if (items.get(i).getItemType() == 0) {
return 1;
} else if (items.get(i).getItemType() == 1) {
return 2;
} else if (items.get(i).getItemType() == 2) {
return 4;
} else {
return 0;
}
}
});
setMultiTypeDelegat(new MultiTypeDelegate<customdata>() {
@Override
protected int getItemType(customData customData) {
return customData.getItemType();
}
});
}

@Override//這裡面還是跟其他的一樣
protected Map<integer> getItemBinding() {
Map<integer> mp = new HashMap<>();
mp.put(0, new CSBravhItemBinding(com.caesar.brvahbinding.BR.data, R.layout.item_nomulti_zero));
mp.put(1, new CSBravhItemBinding(com.caesar.brvahbinding.BR.data, R.layout.item_nomulti_one));
mp.put(2, new CSBravhItemBinding(com.caesar.brvahbinding.BR.data, R.layout.item_nomulti_two));
//這邊的0,1,2要跟上面setMultiTypeDelegat返回的要對應起來
return mp;
}

@Override
public void load() {
load(getData());
}

private Flowable<list>> getData() {
return Flowable.create(new FlowableOnSubscribe<list>>() {
@Override
public void subscribe(FlowableEmitter<list>> emitter) throws Exception {
ArrayList<customdata> data = new ArrayList<>();
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));

data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img2));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));
data.add(new NeoDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));
data.add(new NeoDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img2));
data.add(new NeoDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img2));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataTwo("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataZero("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img1));
data.add(new NeoDataOne("這貨是個標題", "這貨是個內容加描述", R.mipmap.head_img0));

emitter.onNext(data);
emitter.onComplete();
}
}, BackpressureStrategy.BUFFER);
}

@Override
public RecyclerView.ItemDecoration onitemDecoration() {
return new NormaltemDecoration(10);
}
}/<customdata>/<list>/<list>/<list>/<integer>/<integer>/<customdata>/<customdata>/<code>


<code>public class customData {//可以是接口,可以是類,只要有type類型判斷
public int itemType;
public String title;
public String discribe;
public int imgRes;

public customData(String title, String discribe, int imgRes) {
this.title = title;
this.discribe = discribe;
this.imgRes = imgRes;
}

public int getItemType() {
return itemType;
}

public void setItemType(int itemType) {
this.itemType = itemType;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDiscribe() {
return discribe;
}

public void setDiscribe(String discribe) {
this.discribe = discribe;

}

public int getImgRes() {
return imgRes;
}

public void setImgRes(int imgRes) {
this.imgRes = imgRes;
}
}/<code>

大家看NonMultipleActivity這個類,界面沒啥好講。customData這個類中,有一個itemType,反正只要有一個可以判斷item類型的參數就可以,在NonMultiViewModel的泛型中,寫customData。在構造方法中,有一個setSpan()方法,這個方法就是適配器每個item佔幾個的回調,一般情況下,多佈局Grid形式的,並且item所佔格式不同的,基本都要回調這個方法,設置完該方法後,別忘記在佈局中,用

app:cs_brvah_spansize="@{vm.spanSizeLookup}"進行綁定。在構造方法中,還有一個setMultiTypeDelegat方法,這個方法就是設置每個item的類型的回調了,然後在佈局文件中,通過

app:cs_brvah_multiType="@{vm.multiTypeDelegat}"進行綁定,是不是特別簡單。

文章不易,如果大家喜歡這篇文章,或者對你有幫助希望大家多多,點贊,轉發,關注 哦。文章會持續更新的。絕對乾貨!!!

注:

  • 首先,希望以上這些資料能夠給大家帶工作上的來幫助。
  • 其次,為了幫助大家提升進階,實現技能快速突破,打造自身鐵飯碗!以下這些資料也是我多年來的一些收集,我分享一份由幾位大佬一起收錄整理的Android學習PDF+架構視頻+面試文檔+源碼筆記,還有高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料供大家學習進階。(上面的內容也是資料裡的其中一部分哦,資料絕對新和全)
  • 最後願每個程序員都可以工資翻倍!!並且繼續在這條路上越走越遠。

如果你有需要的話,可以私信我【進階】我免費發給你,希望大家一起多多學習交流

喜歡本文的話,不妨給我點個小贊、評論區留言或者轉發支持一下唄~以下資料也是由我多年由於篇幅有限需要這些資料的朋友,幫忙轉發+評論一下我的文章,關注我,私信我【進階】領取pdf吧~

他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了

他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了


他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了


他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了

他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了

他來了,他來了,他帶著MVVM的BRVAH走來了!再不看又錯過了


分享到:


相關文章: