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");
}
}
読みやすくするために必要なコードのみを記述しました。誰かがこれで私を助けることができますか?.
handlers
もバインドする必要があると思います。おそらくonCreate
に次のようなものがあります。
MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);
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) {
//
}
}
ご了承ください
onClickLamdaWithObject
の例のような任意のオブジェクトを渡すことができます。View
オブジェクトを渡す必要がある場合は、(v)->
式。さらに読む
https://developer.Android.com/topic/libraries/data-binding/expressions
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;
}
}
アクティビティを使用する場合は、自動的にバインドされるcontext
オブジェクトを置き換えることもできます。そうしないと、スペースが無駄になります。
Contextという名前の特別な変数は、必要に応じて式をバインドするために生成されます。コンテキストの値は、ルートビューのgetContext()のコンテキストです。コンテキスト変数は、その名前の明示的な変数宣言によってオーバーライドされます。
binding.setContext(this);
そして
<variable name="context" type="com.example.MyActivity"/>
単なる文字列onClick="someFunc"
を使用する場合は注意してください。これはデータバインディング機能ではありません。これは、少しのリフレクションを使用してコンテキストのメソッドを見つける古い機能です。
やったほうがいい
Android:onClick="@{() -> handlers.onClickFriend()}"
これを達成するための両方の方法をカバーするために、これを投稿しています。 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.リスナーバインディングを使用している間は、必要に応じてオブジェクトを直接渡し、操作を実行できるという利点があります。
別個のクラスMyHandlers
を作成し、_Android:onClick
_を処理するためにsetHandlers
を呼び出すことは必須ではありません。 MainActivity
のpublic 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
を押すことをお勧めします。アプリのあとがきを再構築することを忘れないでください。