web-dev-qa-db-ja.com

イベントのバインドにDataBindingライブラリを使用

DataBinding Libraryを使用してxmlのビューにイベントをバインドしようとしていますAndroid M. Android Developers からの例とステップバイステップの実装。可視性などのビューの属性に対して、テキストは正常に機能しますが、onclickでバインドしようとすると、期待どおりに動作しません。これまでに試したコード:

 <data>
    <import type="Android.view.View"/>
    <variable name="user" type="com.example.databinding.User"/>
    <variable name="handlers" type="com.example.databinding.MyHandlers"/>
</data>

 <TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@{user.firstName}"
    Android:visibility="@{user.isFriend ? View.VISIBLE : View.GONE}" />
 <Button
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="Click Me"
    Android:id="@+id/button"
    Android:layout_gravity="left"
    Android:onClick="@{handlers.onClickFriend}"/>

主な活動 :

  public class MainActivity extends AppCompatActivity {

  User user;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding binding = 
    DataBindingUtil.setContentView(this,R.layout.activity_main);
    user = new User("Pankaj","Kumar",true,true);
    binding.setUser(user);
   }
 }

MyHandlers:

public class MyHandlers {
public void onClickFriend(View view){
    Log.i(MyHandlers.class.getSimpleName(),"Now Friend");
}

public void onClickEnemy(View view){
    Log.i(MyHandlers.class.getSimpleName(),"Now Enemy");
  }
}

読みやすくするために必要なコードのみを記述しました。誰かがこれで私を助けることができますか?.

42
Pankaj

handlersもバインドする必要があると思います。おそらくonCreateに次のようなものがあります。

MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);
94
Minhtdh

クリックを設定する多くの方法

1)ハンドラーをバインディングに渡します。

ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
Hander handler = new Handler();
binding.setHandlers(handlers);

2)クリック数を設定(以下のいずれかを使用)

Android:onClick="@{handler::onClickMethodReference}"

OR

Android:onClick="@{handler.onClickMethodReference}"

OR

Android:onClick="@{() -> handler.onClickLamda()}"

OR

Android:onClick="@{(v) -> handler.onClickLamdaWithView(v)}"

OR

Android:onClick="@{() -> handler.onClickLamdaWithView(model)}"

理解するためにHandlerクラスを参照してください。

public class Handler {
    public void onClickMethodReference(View view) {
        //
    }
    public void onClickLamda() {
        //
    }
    public void onClickLamdaWithView(View view) {
        //
    }
    public void onClickLamdaWithObject(Model model) {
        //
    }
}

ご了承ください

  • 属性onClickと同じ引数がある場合、Method Reference(::)を使用できます。
  • onClickLamdaWithObjectの例のような任意のオブジェクトを渡すことができます。
  • Viewオブジェクトを渡す必要がある場合は、(v)->式。

さらに読む

https://developer.Android.com/topic/libraries/data-binding/expressions

20
Khemraj

Xmlで次の形式を使用します。

Android:onClick="@{handlers::onClickFriend}"

::に注意してください。現在は開いているので、xmlエディターの赤い線を心配する必要はありません bug for Android Studio xml editor 。

handlersは、データタグからの変数です。

<data>
    <variable name="handlers" type="com.example.databinding.MyHandlers"/>
</data>

onClickFriendはメソッドです:

public class MyHandlers {
    public void onClickFriend(View view) {
        Log.i(MyHandlers.class.getSimpleName(),"Now Friend");
    }
}

[〜#〜] added [〜#〜]

XmlのハンドルonLongClickの場合、これを追加します。

Android:onLongClick="@{handlers::onLongClickFriend}"

viewModelクラスにonLongClickFriendメソッドを追加します。

public class MyHandlers {
    public boolean onLongClickFriend(View view) {
        Log.i(MyHandlers.class.getSimpleName(),"Long clicked Friend");
        return true;
    }
}

[〜#〜] added [〜#〜]

トーストメッセージを表示する必要がある場合は、インターフェイス(より良いバリアント)を使用するか、構築中のcontextクラスでMyHandlersを渡すことができます。

public class MyHandlers {

    private Context context;

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

    public boolean onLongClickFriend(View view) {
        Toast.makeText(context, "On Long Click Listener", Toast.LENGTH_SHORT).show();
        return true;
    }
}
14
walkmn

アクティビティを使用する場合は、自動的にバインドされるcontextオブジェクトを置き換えることもできます。そうしないと、スペースが無駄になります。

Contextという名前の特別な変数は、必要に応じて式をバインドするために生成されます。コンテキストの値は、ルートビューのgetContext()のコンテキストです。コンテキスト変数は、その名前の明示的な変数宣言によってオーバーライドされます。

binding.setContext(this);

そして

<variable name="context" type="com.example.MyActivity"/>

単なる文字列onClick="someFunc"を使用する場合は注意してください。これはデータバインディング機能ではありません。これは、少しのリフレクションを使用してコンテキストのメソッドを見つける古い機能です。

4
androidguy

やったほうがいい

Android:onClick="@{() -> handlers.onClickFriend()}"
4
Mladen Rakonjac

これを達成するための両方の方法をカバーするために、これを投稿しています。 1.リスナーバインディングによる2.メソッドリファレンスによる

レイアウト:

<layout...>
<data>

        <variable
            name="handlers"
            type="com.example.databinding.MyPresenter" />
        <variable name="user" type="com.example.databinding.User"/>
</data>

<LinearLayout
  Android:layout_width="wrap_content"
  Android:layout_height="wrap_content">

    <Button
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="32dp"
            Android:text="Using Listener Binding"
            Android:onClick="@{() -> handlers.onLisClick(user)}"/>

     <Button
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="32dp"
            Android:text="Using Method Ref"
            Android:onClick="@{handlers::onButtonClicked}"/>            

</LinearLayout>
</layout>

アクティビティ:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding =
                DataBindingUtil.setContentView(this, R.layout.activity_main);
        MyPresenter presenter = new MyPresenter();
        User user = new User("Alex","RJ")
        binding.setUser(user);
        binding.setHandlers(presenter);
    }

MyPresenter:

public class MyPresenter{

//using listener binding
public void onLisClick(User user){
//do something..
}


//using method reference
public void onButtonClicked(View view){

// do something
}

}

注意:
1。メソッド参照を使用している間、メソッドシグネチャは、他のonClickのメソッド(つまり、publicおよびView as parameter)に対して記述するものと同じである必要があります。

2.リスナーバインディングを使用している間は、必要に応じてオブジェクトを直接渡し、操作を実行できるという利点があります。

3
Man

別個のクラスMyHandlersを作成し、_Android:onClick_を処理するためにsetHandlersを呼び出すことは必須ではありません。 MainActivitypublic void onClickFriend(View view)およびpublic void onClickEnemy(View view)メソッドのみを使用できます。アクティビティビュー:

_public class MainActivity extends AppCompatActivity {
    User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding =
                DataBindingUtil.setContentView(this, R.layout.activity_main);
        user = new User("Pankaj", "Kumar", true, true);
        binding.setUser(user);
    }

    public void onClickFriend(View view) {
        Log.i(MyHandlers.class.getSimpleName(), "Now Friend");
    }

    public void onClickEnemy(View view) {
        Log.i(MyHandlers.class.getSimpleName(), "Now Enemy");
    }
}
_

レイアウト:

_<data>
    <import type="Android.view.View"/>
    <variable name="user" type="com.example.databinding.User"/>
</data>

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@{user.firstName}"
    Android:visibility="@{user.isFriend ? View.VISIBLE : View.GONE}" />

<Button
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="Click Me"
    Android:id="@+id/button"
    Android:layout_gravity="left"
    Android:onClick="@{onClickFriend}"/>
_

MVVMパターンにデータバインディングライブラリを使用する例を見てみましょう: http://cases.azoft.com/mvvm-Android-data-binding

これが発生した他の状況があったため、これを投稿しています。レイアウトファイルを参照する2つのアクティビティがあり、1つがonclickイベントを定義し、もう1つがイベントを定義したアクティビティで奇妙なことに同じ警告を受け取らない場合。

これを確認するには、レイアウト名のright clickingでレイアウトファイルの使用法を見つけ、find referencesを押すことをお勧めします。アプリのあとがきを再構築することを忘れないでください。

1
jobbert