编程知识 cdmana.com

Android從零開始搭建MVVM架構(1),全網首發

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_baseuse);
baseuseBinding = DataBindingUtil.setContentView(this, R.layout.activity_baseuse);
baseuseBinding.setTextStr(“這裏就能設置數據”);
baseuseBinding.setOnClickListener(this);
}

@Override
public void onClick(View v) {
baseuseBinding.txt.setText(“點擊設置的數據”);
}
}

這裏還能調用類裏的方法,且需要特別注意,在使用DataBinding的時候,包名一定是小寫,不然找不到包名,假設我們這裏定義個類,然後調用類裏的方法。

public class OnClickUtil {

public void onClickWithMe(View view) {
Toast.makeText(view.getContext(), “調用類裏的方法”, Toast.LENGTH_SHORT).show();
}
}

其他步驟都一樣,唯一不同的是,調用類裏方法的寫法不同。假設button點擊調用。用::錶示調用,後面接的是方法名。

<Button

android:onClick=“@{onClickUtil::onClickWithMe}”
/>

1.2、<import>和別名alias的使用

這裏我們先定義同名的2個類User。放在不同包裏。

public class User {
private String name;
private int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}
}

之前我們的<data>標簽就可以用<import>。

<data>
<import type=“com.lihang.databindinglover.bean.User”/>

<variable
name=“use_first”
type=“User” />
</data>

<import>的用法是在同一個xml裏需要用到多次User的時候,type類型只需要寫<import>的類名就可以代錶了,就不需要總是寫包名.類型。但這個時候也就出現2個同名不同包的類是需要用到alias別名,不然類名重複了。

<data>
<import type=“com.lihang.databindinglover.bean.User”/>

<import
alias=“loverUser”
type=“com.lihang.databindinglover.User”/>

<variable
name=“user_first”
type=“User” />

<variable
name=“user_second”
type=“loverUser” />
</data>

Activity裏的使用都是非常簡單的,如果有不明白,稍後放出鏈接。

這裏還有特殊功能,比如我們再布局預覽頁面。通常會使用 **tools:text=“中間的”**來預覽布局,這個時候可以通過

<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@{user.name,default = 預覽文字}”
/>

使用default的時候,即使是studio3.5裏,也不提示,不過不影響。還有一點,在DataBinding裏,已經處理了null。所以這個時候你在Activity裏給user設置為null。也不會崩潰

二、DataBinding在Fragment和RecyclerView裏的使用

在Fragment的使用和Activity裏的使用一樣。獲取根目錄的方式如下。

//注意獲取根布局是
View view = activityAlisBinding.getRoot();

這裏重點介紹下再recyclerView裏的用法。我們以前是不是寫ViewHolder寫的煩了?用上了DataBinding後,這麼告訴你一個ViewHolder就能搞定一切需要的ViewHolder

先看下我們的唯一的ViewHolder。首先提下,自動生成的Binding的父類都是ViewDataBinding。我是把ViewHolder單獨拉出來了。這樣大家都能用:

public class NewViewHolder extends RecyclerView.ViewHolder {
public ViewDataBinding binding;

public NewViewHolder(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}

在Adapter裏只需要職業

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
ItemNewOrderBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.item_new_order, viewGroup, false);
return new NewViewHolder(binding);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
NewViewHolder newViewHolder = (NewViewHolder) viewHolder;
//如果是多布局,那麼對binding進行一個 instansof的一個判斷就好。這樣我們的ViewHolder永遠只需要一個
ItemNewOrderBinding binding = (ItemNewOrderBinding) newViewHolder.binding;
binding.txtName.setText(“這樣就能使用了!!”);
}

三、單向數據綁定

單向綁定可以理解為,改變了bean對象裏的數據,就會自動改變我們xml的顯示。這裏涉及到3個類: BaseObservable、ObservableField、ObservableCollection。看這個名字就知道有點類似觀察者模式

3.1、BaseObservable

首先我們定義個以Dog類

public class Dog extends BaseObservable {

//如果是public修飾的,直接用@Bindable
@Bindable
public String name;
//如果是private修飾的,則在get方法使用@Bindable
private String color;

public void setDataOnlyName(String name, String color) {
this.name = name;
this.color = color;
//只刷name字段
notifyPropertyChanged(com.lihang.databindinglover.BR.name);
}

public void setDataAll(String name, String color) {
this.name = name;
this.color = color;
//刷新全部字段
notifyChange();
}
…//省略部分代碼
}

這裏我同事改變了name和color的顏色,說明

  • bean對象需要繼承 BaseObservable
  • @Bindable 標注用來錶示哪個字段需要單向綁定。public修飾的可以直接用@Bindable綁定。private修飾的需要在get()方法上用@Bindable標注
  • notifyChange();刷新所有字段,notifyPropertyChanged(com.lihang.databindinglover.BR.name);刷新單個字段。注意這裏說的刷新全是被@Bindable綁定的。如果BR.name出不來。建議build下項目
  • 還有不明白的可以在末尾鏈接demo看:單向數據綁定 – BaseObservable.

Android從零開始搭建MVVM架構(1),全網首發_程序員

繼承了BaseObservable的bean對象,還可以監聽刷新了哪

dog.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (propertyId == com.lihang.databindinglover.BR.name) {
Log.e(“看看刷新了哪”, “刷新了name”);
} else if (propertyId == com.lihang.databindinglover.BR._all) {
Log.e(“看看刷新了哪”, “全部全部”);
} else {
Log.e(“看看刷新了哪”, “未知錯誤~”);
}
}
});

3.2、ObservableField

其實這個ObservableField就是對BaseObservable的簡化,不用繼承,不用主動調刷新代碼。
這個時候我們頂一個Human類

public class Human {
//這裏必須是常量,ObservableField<參數類型>
//其實寫上了下面一句,就是BaseObservable,set,get, @Bindable,刷新都封裝了。直接看構造方法
public final ObservableField<String> name = new ObservableField<>();
//其中也封裝了基本數據類型:ObservableInt等
public final ObservableInt age = new ObservableInt();

public Human(String name,int age){
this.name.set(name);
this.age.set(age);
}

}

Activity和xml裏的操作和之前的一樣,改變數據,自動改變xml只需要:

//簡直太方便了吧
human.name.set(“玉璣子”);
human.age.set(15);

3.3、ObservableCollection

一看就是集合,這裏和我們常用的 List Map一樣。只不過這裏的ObservableList、ObservableMap是封裝好的。當我們改變集合裏的數據時。xml也會改變。唯一要注意的是,在xml裏引用這些集合的時候<類型>,這些符號,會影響xml格式所以要轉義。用< 代錶<;用&gt代錶>(這些轉義符,同樣支持Mark Down);想了解更多可自行百度 DataBinding轉義符。

<layout xmlns:android=“ http://schemas.android.com/apk/res/android”>

<data>

<variable
name=“list”
type=“androidx.databinding.ObservableList<String>” />

<variable
name=“map”
type=“androidx.databinding.ObservableMap<String,String>” />

<variable
name=“index”
type=“int” />

<variable
name=“key”
type=“String” />
</data>

<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”>

<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@{list[index],default = 哈哈}” />

<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@{map[key],default = 呵呵}” />

</LinearLayout>
</layout>

這裏遇到一個坑,就是你的default = “默認值” 這個默認值最好不是data裏的引用。不然會報錯哦。這裏我們帶入index = 0 帶入,把key = name。代入,然後動態改變,集合裏這2個值:

@Override
public void onClick(View v) {
int randowInt = new Random().nextInt(100);
switch (v.getId()){
case R.id.btn_index:
//改變list的第一項
list.add(0,“list的值” + randowInt);
break;
case R.id.btn_key:
map.put(“name”,“map的值” + randowInt);
break;
}
}

Android從零開始搭建MVVM架構(1),全網首發_移動開發_02

四、雙向數據綁定

意思就是你改變bean對象裏的值,他會主動改變xml的顯示,改變xml的裏的值,他會把bean對象裏的屬性改變了。 這裏我們用1個TextView顯示數據;用1個EditTextView綁定bean對象,再用1個Button可以動態查詢bean對象裏的屬性值

<layout xmlns:android=“ http://schemas.android.com/apk/res/android”>

<data>
<variable
name=“human”
type=“com.lihang.databindinglover.bean.Human” />
</data>

<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”>

<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@{human.name}” />

<EditText
android:layout_width=“match_parent”
android:layout_height=“60dp”
android:layout_marginTop=“20dp”
android:text=“@={human.name}” />

<Button
android:id=“@+id/btn_search”
android:layout_marginTop=“60dp”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“動態查詢屬性”
/>
</LinearLayout>
</layout>

bean對象綁定xml顯示:單向綁定是@{屬性值},雙向綁定則是@={屬性值},效果如下:

Android從零開始搭建MVVM架構(1),全網首發_程序員_03

五、在include 和 viewStub中使用

5.1 在include中使用。

include的布局如下:

<layout xmlns:android=“ http://schemas.android.com/apk/res/android”>

<data>

<variable
name=“user”
type=“com.lihang.databindinglover.bean.User” />

</data>

<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”>

<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@{user.name}” />

</LinearLayout>
</layout>

Activity裏引用include這樣:

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

<data>

<variable
name=“user”
type=“com.lihang.databindinglover.bean.User” />

</data>

<RelativeLayout
android:layout_width=“match_parent”
android:layout_height=“match_parent”>

<include
layout=“@layout/include_item”
app:user=“@{user}” />

</RelativeLayout>
</layout>

注意:app:user=“@{user}”。第一個user是include裏name的引用。第二user是當前傳入的值。

5.2、viewStub中的使用

簡單介紹下viewStub:被viewStub包裹的。即使頁面顯示的時候,被包裹的布局也不會加載,除非調用inflate。這樣算是對布局卡頓的優化了。include則算是代碼裏的布局優化。

直接放Activity布局了。被包裹的布局和上面的include一樣

最後

總而言之,成功是留給准備好的人的。無論是參加什麼面試,都要做好充足的准備,注意好面試的禮儀和穿著,向面試官錶現出自己的熱忱與真誠就好。即使最後沒有過關,也要做好經驗的總結,為下一次面試做好充足准備。

這裏我為大家准備了一些我在面試後整理的面試專題資料,除了面試題,還總結出了互聯網公司Android程序員面試涉及到的絕大部分面試題及答案,並整理做成了文檔,以及系統的進階學習視頻資料,免費分享給大家,希望能幫助到你面試前的複習,且找到一個好的工作,也節省大家在網上搜索資料的時間來學習。

畢竟不管遇到什麼樣的面試官,去面試首先最主要的就是自己的實力,只要實力够硬,技術够强,就不怕面試拿不到offer!

想要面試順通嘛,趕緊領取下面的面試資料為之後的面試做足准備叭!這裏提前祝各比特面試成功!

資料領取方式:?? Android架構設計

Android從零開始搭建MVVM架構(1),全網首發_移動開發_04

Android從零開始搭建MVVM架構(1),全網首發_Android_05

為什麼某些人會一直比你優秀,是因為他本身就很優秀還一直在持續努力變得更優秀,而你是不是還在滿足於現狀內心在竊喜!希望讀到這的您能點個小贊和關注下我,以後還會更新技術幹貨,謝謝您的支持!

Android從零開始搭建MVVM架構(1),全網首發_程序員_06

版权声明
本文为[mb61c1dbbb44788]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/01/202201150218513090.html

Scroll to Top