iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
Mobile Development

android studio 30天學習筆記系列 第 15

android studio 30天學習筆記-day 15-databinding 雙向綁定

  • 分享至 

  • xImage
  •  

昨天了解如何使用databinding的單向綁定,把data放到view裡,那反過來當view發生變化,data也能跟著改變呢?
這時就會用到了databinding的雙向綁定。

example

當EditText在進行輸入時TextView也會跟著顯示EditText正在輸入的內容

<TextView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="@{dataItem.name}"
     android:textSize="20sp"/>
<EditText
     android:layout_width="200dp"
     android:layout_height="wrap_content"
     android:text="@={dataItem.name}"
     android:textSize="20sp"/>

跟之前databinding的賦值一樣,只是EditText的text賦值會變成@={dataItem.name}(在@{}中間加個等號),當EditText的text一改變,那麼TextView的text也會及時改變,這是一個簡單的雙向綁定。

使用InverseBindingAdapter

實作:將seekbar隨意調動,TextView會顯示其數字。

@BindingAdapter(value = {"progressNow"})
    public static void setProgressNow(SeekBar seekBar,String progressNum){
        int value = 0;
        try {
            value = Integer.parseInt(progressNum);
        } catch (NumberFormatException e) {

        }
        seekBar.setProgress(value);
    }

自定義屬性app:progressNow,將SeekBar與viewModel做雙向綁定,當app:progressNow發生改變時要如何get app:progressNow的值,這時可以用InverseBindingAdapter去達成。

//@InverseBindingAdapter(attribute = "attribute_name",event="")event屬性:雙向綁定時對view的變化發出通知。

 @InverseBindingAdapter(attribute = "progressNow")
    public static String getProgressNow(SeekBar seekBar){
        return ""+seekBar.getProgress();
    }

1.@InverseBindingAdapter的屬性必須跟BindingAdapter自定義的屬性一樣
2.可以看到@InverseBindingAdapter只配置了一個(attribute = "progressNow"),而event沒有配置,那麼會使用Default:將event的屬性值為"{屬姓名}+AttrChanged" (EX:progressNowAttrChanged)。

@BindingAdapter(value = {"onProgressChanged","progressNowAttrChanged"},requireAll = false)
    public static void setProgressNowAttrChanged(SeekBar seekBar,final SeekBar.OnSeekBarChangeListener listener,final InverseBindingListener attrChange){//註解中屬性的順序與方法中的參數順序要保持一致,也就是說屬性的`onProgressChanged`會對應到`SeekBar.OnSeekBarChangeListener listener`,而`progressNowAttrChanged`對應`InverseBindingListener attrChange`,
        
        if (attrChange ==null){
            seekBar.setOnSeekBarChangeListener(listener);
        }else{
            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                //當seekbar的值改變時,InverseBindingListener會進行 attrChange.onChange()。

                    attrChange.onChange();
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });
        }
    }

設置MODEL

public class DataItem2 {
    public final ObservableField<String> progressNum= new ObservableField<>();
}

設置UI

<SeekBar
      android:layout_width="match_parent"
      android:layout_height="50dp"
      app:progressNow="@={observableData2.progressNum}"/>
<TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@{observableData2.progressNum}"
      android:gravity="center"
      android:textSize="50sp"/>

在seekbar加上@={}

MainActivity2

public class MainActivity2 extends AppCompatActivity {
   ActivityMain2Binding main2Binding;
    DataItem2 dataItem2;
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();

    }
    private void init() {
        main2Binding=DataBindingUtil.setContentView(this,R.layout.activity_main2);
        
        dataItem2=new DataItem2();
        main2Binding.setObservableData2(dataItem2);
    }
}

tip: BindingAdapter當成是setter,InverseBindingAdapter是getter
這樣就完成囉


上一篇
android studio 30天學習筆記-day 14-databinding 單向綁定
下一篇
android studio 30天學習筆記-day 16-databinding Recyclerview
系列文
android studio 30天學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言