android - studio - Usar la biblioteca DataBinding para eventos vinculantes
data binding español (7)
Creo que también deberás vincular los handlers
, tal vez algo así en onCreate
:
MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);
Estoy intentando vincular eventos con vistas en xml usando DataBinding Library incluida con Android M. Estoy siguiendo ejemplos de Android Developers e implementando paso a paso. para los atributos de la vista, como la visibilidad, el texto funciona bien, pero si intento vincularlo con onclick, no funciona como se esperaba. Aquí está el código de muestra que he intentado hasta ahora:
<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}"/>
Actividad principal :
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");
}
}
He escrito solo el código requerido para mejorar la legibilidad. Puede alguien ayudarme con esto.
Deberías hacer
android:onClick="@{() -> handlers.onClickFriend()}"
Estoy publicando esto porque he tenido otra situación en la que esto ocurrió. Si tiene dos actividades que hacen referencia al archivo Layout y una define el evento onclick y la otra no recibe la misma advertencia y de manera extraña en la actividad donde definió el evento.
Para comprobar esto, recomiendo encontrar los usos del archivo de diseño right clicking
sobre el nombre del diseño y presionando find references
. No te olvides de reconstruir los postwords de la aplicación.
Estoy publicando esto solo para cubrir ambas formas de lograr esto. 1. por el oyente vinculante 2. por referencia del método
diseño:
<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>
Actividad:
@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
}
}
Nota:
1.Mientras utilice la referencia de método, la firma del método debe ser la misma que la que escribiría para cualquier otro método de onClick, es decir, público y Ver como parámetro.
2.Mientras utiliza el enlace de escucha, tiene la ventaja de que puede pasar directamente el Objeto también si desea y realiza cualquier operación.
No es obligatorio crear la clase separada MyHandlers
y call setHandlers
para procesar android:onClick
. Solo puede usar los métodos: public void onClickFriend(View view)
y public void onClickEnemy(View view)
en MainActivity
. La vista de actividad:
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");
}
}
Un diseño:
<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}"/>
Eche un vistazo al ejemplo del uso de la Biblioteca de enlace de datos para el patrón MVVM: http://cases.azoft.com/mvvm-android-data-binding
Si va a utilizar su actividad, también podría reemplazar el objeto de context
que está automáticamente enlazado, de lo contrario, está desperdiciando espacio.
Se genera una variable especial llamada contexto para usar en expresiones de enlace según sea necesario. El valor para el contexto es el contexto del getContext () de la vista raíz. La variable de contexto será anulada por una declaración de variable explícita con ese nombre.
binding.setContext(this);
y
<variable name="context" type="com.example.MyActivity"/>
Tenga en cuenta si solo utiliza cadena simple onClick="someFunc"
que no es una funcionalidad de enlace de datos. Esa es una característica anterior que usa un pequeño reflejo para encontrar el método en el contexto.
Usa este formato en tu xml:
android:onClick="@{handlers::onClickFriend}"
Preste atención a ::
, no se preocupe por las líneas rojas en el editor xml, porque actualmente este es un bug abierto para el editor Android Studio xml.
Donde los handlers
son su variable desde la etiqueta de datos:
<data>
<variable name="handlers" type="com.example.databinding.MyHandlers"/>
</data>
y onClickFriend
es tu método:
public class MyHandlers {
public void onClickFriend(View view) {
Log.i(MyHandlers.class.getSimpleName(),"Now Friend");
}
}
ADICIONAL
Para manejar en onLongClick
en xml agregue esto:
android:onLongClick="@{handlers::onLongClickFriend}"
y agrega el método onLongClickFriend
en tu clase de ViewModel:
public class MyHandlers {
public boolean onLongClickFriend(View view) {
Log.i(MyHandlers.class.getSimpleName(),"Long clicked Friend");
return true;
}
}
ADICIONAL
Si necesita mostrar el mensaje de tostado, puede usar la interfaz (mejor variante) o pasar el context
en la clase MyHandlers
en construcción:
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;
}
}