2017-12-12 12 views
1

databindingを勉強して、私は運動を開始する簡単な活動を作成しました。 そして持って、次のコード:テキストがアクティビティで変化しないのはなぜですか?

MainActivity:クリック用

class MainActivity : AppCompatActivity() { 
    val users = UserProfile("First Name","Last Name","Off",false) 
    val handlerbtn = HandlerButtonClick() 
    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main) 
     binding.user = users 
     binding.handler = handlerbtn 

    } 
} 

クラス:

class HandlerButtonClick { 
    fun onClickButton(view: View, user: UserProfile) { 
     var msg = "" 
     if(!user.isOnline){ 
      msg = "Online" 
      user.firstName = "Henrique" 
      user.lastName = "Mendes" 
      user.status = "Online" 
      user.isOnline = true 

     }else{ 
      msg = "Offline" 
      user.firstName = "First Name" 
      user.lastName = "Last Name" 
      user.status = "Offline" 
      user.isOnline = false 
     } 

     Toast.makeText(view.context, msg, Toast.LENGTH_SHORT).show() 
    } 
} 

のUserProfileクラス:

class UserProfile { 
    var firstName: String = "" 
    var lastName: String = "" 
    var status: String = "" 
    var isOnline: Boolean = false 

    constructor(firstNames: String, lastNames: String, statuss: String, isOnlines: Boolean) { 
     this.firstName = firstNames 
     this.lastName = lastNames 
     this.status = statuss 
     this.isOnline = isOnlines 
    } 
} 

XML:

<?xml version="1.0" encoding="utf-8"?> 

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

    <data> 

     <variable 
      name="user" 
      type="com.dev.bob.testdatabinding2.UserProfile" /> 
     <variable 
      name="handler" 
      type="com.dev.bob.testdatabinding2.HandlerButtonClick" /> 
    </data> 

    <LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     tools:context="com.dev.bob.testdatabinding2.MainActivity"> 

     <View 
      android:layout_width="match_parent" 
      android:layout_height="1.0dp" 
      android:layout_marginBottom="10dp" 
      android:layout_marginTop="10dp" 
      android:background="@{[email protected]/colorGreen : @color/colorAccent}" /> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="10dp" 
      android:text="@{user.firstName}" /> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="10dp" 
      android:text="@{user.lastName}" /> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="10dp" 
      android:text="@{user.status}" /> 

     <Button 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:onClick="@{(view)-> handler.onClickButton(view, user)}"/> 

    </LinearLayout> 
</layout> 

トーストが正常に動作し、それは、変数msg変化です。しかし、画面上の私のテキストは変わらない。それぞれの条件(If/else)に記載されている内容に従って変更するには、どうすればよいですか?私は、ボタンをクリックすることにより、firstNameは(再び)ヘンリーまたは姓に変更されませんされて何と言う

+0

MainActivityの 'user'変数と一致するように' user'の値をチェックするためにデバッグを試しましたか? – nhoxbypass

+0

変数はXMLで明示的であるため、同じです。しかし、どうすればわかるでしょうか?値はHandlerクラスで変更されました –

答えて

3

それは右のように振る舞います。 documentから:

データバインドするために使用することができる

どれでも昔ながらのJavaオブジェクト(POJO)が、 POJOを変更するUIを更新することはありません。 データバインディングの本当の力は、データオブジェクトに、データ変更時に に通知する機能を与えることで使用できます。 3つの異なるデータ変更通知メカニズム、Observableオブジェクト、Observableフィールド、およびObservableコレクションがあります。

それともthis迅速かつ汚いアプローチを使用して結合双方向のデータを試すことができます。

あなたのタグandroid:text@:後、=が不足しています。それはandroid:text="@={user.firstName}"である必要があります。 @={}は、「双方向データバインディング」を意味します。 @{}は片方向データバインディングです。

例:

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginBottom="10dp" 
    android:text="@={user.firstName}" /> 
+0

あなたが言いましたように変更しましたが、うまくいかなかった、私が間違っていることがあります。 –

+0

@HenriqueMendes私は完全なアプローチを忘れていました:https://www.bignerdranch.com/blog/two-way-data-binding-on-android-observing-your-view-with-xml/ – nhoxbypass

+0

私はあなたのPOJOがあなたのために「自動更新」できると思うことを示していますが、それはあなたの質問に答えました。 Btwは、Googleがこのドキュメントで推奨している3つの標準的なアプローチに従ってください。 – nhoxbypass

1

あなただけの変数に新しい値を代入し、UI上の変化を観察することはできません。何らかの形で「データバインド」に通知する必要があります。それを行う方法はいくつかあります。

まず一つはのUserProfileがBaseObservableを拡張し、いくつかのプロパティが変更されたときに通知することです:

class UserProfile : BaseObservable { 

    @get:Bindable 
    var firstName: String = "" 
     set(value) { 
      notifyPropertyChanged(BR.firstName) 
     } 

    @get:Bindable 
    var lastName: String = "" 
     set(value) { 
      notifyPropertyChanged(BR.lastName) 
     } 

    ... do same for other fields ... 

    constructor(firstNames: String, lastNames: String, statuss: String, isOnlines: Boolean) { 

     this.firstName = firstNames 
     this.lastName = lastNames 
     this.status = statuss 
     this.isOnline = isOnlines 
    } 
} 

2つ目は、変更後ActivityMainBindingに新しいUserProfileを割り当てている。

class MainActivity : AppCompatActivity() { 
    val users = UserProfile("First Name","Last Name","Off",false) 
    lateinit var handlerbtn: HandlerButtonClick 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main) 
     binding.user = users 
     handlerbtn = HandlerButtonClick(binding) 
     binding.handler = handlerbtn 
    } 
} 

次にあなたがHandlerButtonClickを変更する必要がありますクラス:

class HandlerButtonClick(val binding: ActivityMainBinding) { 
    fun onClickButton(view: View, user: UserProfile) { 
     var msg = "" 
     if(!user.isOnline){ 
      //changes 
     }else{ 
      //changes 
     } 
     binding.users = user 
     Toast.makeText(view.context, msg, Toast.LENGTH_SHORT).show() 
    } 
} 
+0

非常に良い答え!ありがとうございました! –

関連する問題