Using DataBinding library for binding events

前端 未结 9 627
小鲜肉
小鲜肉 2020-12-05 01:52

I\'m trying to bind events with views in xml using DataBinding Library shipped with Android M. I\'m following examples from Android Developers and implement

相关标签:
9条回答
  • 2020-12-05 02:13

    I'm posting this because I've had an other situation in which this occurred. If you have two activities referencing to the Layout file and one defines the onclick event and the other doesn't you get the same warning and strangely in the activity where you defined the event.

    To check this I recommend finding the usages of the layout file by right clicking on the layout name and press find references. Don't forget to rebuild the app afterwords.

    0 讨论(0)
  • 2020-12-05 02:17

    You should do

    android:onClick="@{() -> handlers.onClickFriend()}"
    
    0 讨论(0)
  • 2020-12-05 02:20

    It is not obligatory to create the separate class MyHandlers and call setHandlers for processing android:onClick. You can just use the methods: public void onClickFriend(View view) and public void onClickEnemy(View view) in MainActivity. The activity 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");
        }
    }
    

    A layout:

    <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}"/>
    

    Take a look at the example of using the Data Binding Library for the MVVM pattern: http://cases.azoft.com/mvvm-android-data-binding

    0 讨论(0)
  • 2020-12-05 02:22

    For those who are having trouble in handling long click events:

    First create a view in your layout with an id.

    <data>
            <variable
                name="tempDesc"
                type="String" />
            <variable
                name="activity"
                type="com.naruto.trangoapp.MainActivity" />
    </data>
    
    <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{(view) -> activity.changeDescText(view)}"
                android:text="@{tempDesc}" />
    

    In your onCreate method use the id name of the view to set any listener:-

    binding.textView.setOnLongClickListener(this::onLongClick);
    

    then just create a boolean method with the same name, i.e., onLongClick like this:-

    private boolean onLongClick(View l) {
            Toast.makeText(this, "Description", Toast.LENGTH_SHORT).show();
            return true;
        }
    

    That's all!!

    Note: You can also set any method to any view in your layout by setting context to the activity variable in your onCreate method:-

    binding.setActivity(this);
    

    Then, define and pass the method name with view in your layout to use it in your Activity file. Like I have used a method changeDescText(v) with variable name "activity" for my Textview. Here is my method in Activity file:-

    public void changeDescText(View view) {
            binding.setTempDesc("Description Changed");
        }
    
    0 讨论(0)
  • 2020-12-05 02:23

    I'm posting this just to cover both ways to achieve this. 1. by Listener binding 2. by method refernce

    layout:

    <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>
    

    Activity:

    @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
    }
    
    }
    

    Note:
    1.While using method reference the method signature should be same as you would write for any other onClick's method ie public and View as parameter.

    2.While using listener binding you have benefit that you can directly pass the Object also if you want and do any operation.

    0 讨论(0)
  • 2020-12-05 02:24

    Use this format in your xml:

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

    Pay attention to the ::, do not worry about the red lines in xml editor, because is currently this is open bug for the Android Studio xml editor.

    Where handlers is your variable from data tag:

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

    and onClickFriend is your method:

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

    ADDED

    For handle onLongClick in xml add this:

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

    and add onLongClickFriend method in your ViewModel class:

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

    ADDED

    If you need to show toast message, you can use interface (better variant), or pass context in the MyHandlers class in construction:

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题