1

In one of my event handler on a button, I am using lambda expression but it evaluate wrong result at the time of event happens. My flow is to check whether a view (In my case it is TextView) is visible or not in the expression. If view is visible then I am printing true else false. But my code is always giving me true response. Blow is my code:

public class MainActivity extends AppCompatActivity implements MethodReferenceHandler, ____ListenerBindingEventHandler {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    User kkr = new User();
    kkr.setAge("20");
    kkr.setName("Vinit Saxena");
    activityMainBinding.setUser(kkr);
    activityMainBinding.setEventHandler(this);
    activityMainBinding.setMethodreferencehandler(this);
    TextView textView = (TextView) findViewById(R.id.name_tv);
    textView.setVisibility(View.GONE);
    activityMainBinding.setView(textView);
}

@Override
public void onClickViaMethodReferenceHandler(View v) {
    Log.i(getClass().getName(), "---->onClickViaMethodReferenceHandler");
}

@Override
public void eventHandlerViaListenerBinding() {
    Log.i(getClass().getName(), "---->eventHandlerViaListenerBinding");
}

@Override
public void eventHandlerViaListenerBinding(boolean isThisTrue) {
    Log.i(getClass().getName(), "---->eventHandlerViaListenerBinding - isThisTrue : " + isThisTrue);
}
}

<data>

    <import type="android.view.View" />

    <variable
        name="user"
        type="com.mds.binding.User" />

    <variable
        name="methodreferencehandler"
        type="com.mds.binding.MethodReferenceHandler" />

    <variable
        name="eventHandler"
        type="com.mds.binding.____ListenerBindingEventHandler" />

    <variable
        name="view"
        type="android.view.View" />

</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.mds.binding.MainActivity">

    <TextView
        android:id="@+id/name_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.name}"
        android:visibility="visible" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.age}" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="@{methodreferencehandler::onClickViaMethodReferenceHandler}"
        android:text="Method Reference" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="@{(view)-> view.getVisibility() == View.VISIBLE ? eventHandler.eventHandlerViaListenerBinding(true) : eventHandler.eventHandlerViaListenerBinding(false)}"
        android:text="Listener Binding" />
</LinearLayout>

Please help where am I doing mistake? Thanks in advance.

Vinit Saxena
  • 683
  • 2
  • 11
  • 27
  • it seems "view" variable in lambda expression is Button which is not TextView. – Luong Dinh Feb 18 '17 at 12:03
  • try like this: android:onClick="@{()-> eventHandler.eventHandlerViaListenerBinding(view.getVisibility() == View.VISIBLE)}" – Luong Dinh Feb 18 '17 at 12:05
  • @LuongDinh: You are right, It is working fine. But I did not understand the exact meaning of the empty bracket or having some parameters in the bracket i.e. difference between ()-> and (view)->. Can you please explain a lit bit about the same? – Vinit Saxena Feb 18 '17 at 18:06

2 Answers2

1

you can try:

this: android:onClick="@{()->   eventHandler.eventHandlerViaListenerBinding(view.getVisibili‌​ty() ==   View.VISIBLE)}" 

Because your lambda expression correspond to:

         private View view;
         button.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {eventHandler.eventHandlerViaListenerBinding(view.getVisibility() == View.VISIBLE);
         }
     });

In this case, onClick method has 1 argument which is clicked button. And local "view" variable is used instead of global "view" variable. if you name this variable to the other variable name, it's ok.

So you can you your lambda to "@{()->" or "@{(v)->".

Luong Dinh
  • 569
  • 4
  • 17
1

You're not using the binding to its full extend. One purpose is to never use findViewById() again. So the following

TextView textView = (TextView) findViewById(R.id.name_tv);
textView.setVisibility(View.GONE);

should be done as

activityMainBinding.nameTv.setVisibility(View.GONE);

since all views with an id are provieded as a member on the binding.

As a second advantage you can even access this variable within the binding itself. So you could just remove

<variable
    name="view"
    type="android.view.View" />

all completely and implement the onClick listener as

android:onClick="@{(view) -> eventHandler.eventHandlerViaListenerBinding(nameTv.getVisibility() == View.VISIBLE)}"

Additionally you don't really need the ?: conditional operator.

tynn
  • 38,113
  • 8
  • 108
  • 143