一 JetPack之DataBinding基礎使用(Java)

一,前言

百度上搜索了一堆,幾乎全是kotlin語言寫的,雖說看的懂,但是畢竟沒有在項目中實際用過此語言,還是比較吃力的,索性自個對照官方文檔慢慢琢磨.誰知道官網竟然沒有Java的實例,都是kotlin的,這可把我急壞了.!

AndroidStudio版本:3.6.3
SDK:29

二,使用

1,在build.gradle文件中添加, 切記 不可添加成了viewBinding

android {
        ...
        dataBinding {
            enabled = true
        }
    }

如果添加了viewbinding,那就會報如下錯誤.找不到 DataBindingUtil
在這裏插入圖片描述

2,佈局的使用及寫法。

根佈局代碼:

<layout>
    <data>
        <!--String-->
        <variable
            name="name"
            type="String" />
    </data>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        ...
    </LinearLayout>
</layout>
<layout>:只有layout包圍了系統纔會認識
<Data>:所有的變量,數據在此地聲明
<variable>:聲明變量方法

①,name:變量名字
②,type:變量類型

使用這個變量:

   android:text="@{name}"

3,佈局中使用。

當你開啓了enabled = true,並且佈局根使用了layout包圍,那麼系統就會自動生成相對的類綁定
ActicityMainBindding 就是自動生成的。

①Activity 引用佈局 方式 binding = DataBindingUtil.setContentView(this, R.layout.activity_main) ;


public class MainActivity extends AppCompatActivity {
    ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setName("劉備");     
    }
}

②如果您要在 Fragment、ListView 或 RecyclerView 適配器中使用數據綁定項,您可能更願意使用綁定類或 DataBindingUtil 類的 inflate() 方法,如以下代碼示例所示:

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
public class OneFragment extends androidx.fragment.app.Fragment {
    FragmentOneBinding binding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_one, container, false);
        binding.setStr("我是Fragment");
        return binding.getRoot();

    }
}

4,佈局中設置變量的值

如果你在佈局文件中聲明瞭變量,那麼binding不會自動生成get set方法。只有你在view中使用到了這個變量纔會自動生成get,set方法

 binding.setName("劉備");    

那麼開始運行把:如圖
在這裏插入圖片描述

三,導入包,對象及常見運算符的使用

①導入方式

記住導入包,與之前在class中寫法一樣,無非換了一個地方。


2,接下來我們繼續往下走,測試每一個功能
①,給劉備增加一個年齡

<variable
    name="age"
    type="int" />
    <TextView
        ...
        android:text="@{age}"
    >

艾瑪,怎麼會報錯:NotFoundException:String resource ID #0xa28,
找不到異常,找不到ID 是#0xa28的資源?
啥意思呢?我沒有定義字符串啊。
原來是這樣,我們TextView中的Text要接收的是String 類型 我們卻傳了一個int類型 !類型不匹配所以找不到。
在這裏插入圖片描述

解決方式:強制轉換(這個地方很容易忽略哈)

android:text="@{String.valueOf(age)}"

吶,出來了。
在這裏插入圖片描述

②:顯示隱藏View.根據true,false決定是否顯示隱藏

記得要導入上面說的包,

 <import type="android.view.View"/>
<ImageView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:scaleType="fitXY"
    android:src="@drawable/ic_lb"
    android:visibility="@{isShow==true?View.VISIBLE:View.GONE}"
    >

然後傳值:false就會隱藏了
binding.setIsShow(true);

掛在牆上的劉備出來了
在這裏插入圖片描述

③ Null 合併運算符其實就跟三元運算符一樣

 binding.setStr1(null);
 binding.setStr2("張飛");
 //第一種寫法
 android:text="@{str1??str2}"  
 //第二種
 android:text="@{str1==null ? str1:str2}"

④圖片的引入

   <variable name="image" type="Drawable"/>
Drawable drawable= getResources().getDrawable(R.drawable.ic_aa);
binding.setImage(drawable);

<ImageView
    android:layout_width="50dp"
    android:src="@{image}"
    android:layout_height="50dp">

效果圖在這裏插入圖片描述

四,對象,集合,數組的使用

常見的類型

<data>
        <import type="android.util.SparseArray"/>
        <import type="java.util.Map"/>
        <import type="java.util.List"/>
        <variable name="list" type="List&lt;String>"/>
        <variable name="sparse" type="SparseArray&lt;String>"/>
        <variable name="map" type="Map&lt;String, String>"/>
        <variable name="index" type="int"/>
        <variable name="key" type="String"/>
    </data>

①對象的使用

<variable
    name="user"
    type="com.cwj.databindingexample.User" />
    ...
    android:text="@{user.name}"
    ...
    binding.setUser(new User("諸葛亮"));

②數組的使用

<variable
    name="arrays"
    type="String[]" />
    
    
<variable
    name="index"
    type="int" />

③List集合的使用

請注意,
在這裏插入圖片描述

list[index]等於list.get(index),執行結果一樣。
<import type="java.util.List" />

<variable
    name="index"
    type="int" />
  />   
  ①第一種
  沒有指定後面的泛型
<variable
    name="list"
    type="List" />
   需要這樣寫,不然默認是Object類型
   android:text="@{String.valueOf(list[index])}" 
    

②第二種

<variable
    name="list"
    type="List&lt;String>//
     />
     這裏不用強轉
     android:text="@{list[index]}" 
     
     
    Activity 賦值
String arrays []={"呂布","趙子龍","馬超"};
ArrayList<String> list=new ArrayList();
list.add("許褚");
list.add("張遼");
list.add("張郃");
binding.setArrays(arrays);
binding.setList(list);
//下標
binding.setIndex(1);

結果如圖:
在這裏插入圖片描述

④Map 使用

 <import type="java.util.Map" />
<variable
    name="key"
    type="String" />
<variable
    name="map"
    type="Map&lt;String, String>" />
 
 android:text="@{map.get(key)}"
 android:text="@{map[key]}"
 
 
 Map<String ,String > map= new TreeMap<>();
map.put("一","丈八蛇矛");
map.put("二","偃月刀");
map.put("三","青釭劍");
binding.setMap(map);
binding.setKey("二");

在這裏插入圖片描述

注意:官網說的這種寫法,我試了一下出不來

android:text="@{map.key}" 無效

五,資源的引用

① 使用

像下面這種寫法我之前有種疑問,就是不用@{}也可以用啊,爲啥多此一舉?
android:padding="@{@dimen/largePadding}"

②注意,關於多此一舉,主要用於改變UI的時候,比如大小字體,邊距等。

我定義了兩個尺寸

<resources>
    <dimen name="largePadding">20dp</dimen>
    <dimen name="smallPadding">2dp</dimen>
</resources>

<Button
    ...
    android:padding="@{@dimen/largePadding}"
    android:text="資源引用"></Button>

<Button
     ...
    android:paddingLeft="@{number1==1 ? @dimen/largePadding : @dimen/smallPadding}"
    android:text="資源引用大"></Button>

<Button
       ...
    android:padding="@{number1==2 ? @dimen/largePadding : @dimen/smallPadding}"
    android:text="資源引用小"></Button>
    
    bind.setNumber1=1;

結果:可以看出由於,表達式的不同,結果選擇的也不一樣。
在這裏插入圖片描述

某些資源需要顯式類型

在這裏插入圖片描述

六,事件監聽

注意:1)如果您監聽的事件返回類型不是 void 的值,則您的表達式也必須返回相同類型的值。例如,如果要監聽長按事件,表達式應返回一個布爾值。
2)在你的方法中,會發現參數中有一個默認值的View view值 這是啥意思呢,
個人分析:有兩種寫法,第一種寫法是第二種寫法的簡寫,那麼這個theView是啥意思呢?其實就代表着當前view(Button) 然後隨便起個名字。前後對應。讓系統知道你在要在這個view上調用這個方法

① 點擊事件

1,第一種寫法
android:onClick="@{handlers::onClickToast}"
2,第二種寫法
android:onClick="@{(theView)->handlers.onClickToast(theView)}"
<variable
    name="handlers"
    type="com.cwj.databindingexample.MyHandlers" />
    
 public class MyHandlers {
    Context context;

    public MyHandlers(Context context) {
        this.context = context;
    }
    //這個方法的View要有
    public  void onClickToast(View view){
        Toast.makeText(context, "你點擊了我!", Toast.LENGTH_SHORT).show();
        }
      
}

binding.setHandlers(new MyHandlers(this));

在這裏插入圖片描述

②長按事件

第一種
android:onLongClick="@{handlers::onLongClick}"
第二種:
android:onLongClick="@{(a)->handlers.onLongClick(a)}"


public class MyHandlers {
    Context context;

    public MyHandlers(Context context) {
        this.context = context;
    }

    public  void onClickToast(View view){
        Toast.makeText(context, "你點擊了我!", Toast.LENGTH_SHORT).show();
        }
    public  boolean onLongClick(View view){
        Toast.makeText(context, "你長按了了我!", Toast.LENGTH_SHORT).show();
        return true;
        }

}

這會發現,onClick方法和onLongCilck方法的寫法不一樣, 分析:看源碼返回值注意1)

public interface OnClickListener {
    void onClick(View var1);
}

public interface OnLongClickListener {
    boolean onLongClick(View var1);
}

在這裏插入圖片描述

③ 帶有參數的方法

這裏的參數我直接引用的上面的集合中的值。
android:onClick="@{(theView)->handlers.onClickToast(theView,list.get(index))}"

public  void onClickToast(View view,String name){
    Toast.makeText(context, "你點擊了 "+name, Toast.LENGTH_SHORT).show();
}

在這裏插入圖片描述

七,結尾

參考資料 官網

不足或者理解有偏差的地方,請指導。
持續更新。。。
源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章