Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android dataBinding - TextView not visible depending on a boolean value

I'm trying to make a TextView visible depending on when a boolean's value is set to true and a LinearLayout's visibility depending on the false value of the same boolean variable using dataBinding. The problem is that only LinearLayout's visibility is set and not of the TextView's although when I log the boolean's value it's state is changing as per the control flow.

Below is my code any help is much appreciated as I'm stuck with this since last night and sorry if this is a noob question as I'm new to dataBinding. I'm setting the value twice in both onCreateView and onActivityCreated just to test the flow and log

fragment layout

    <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
  <data>
    <variable
        name="isLoading"
        type="boolean"
        />
    <variable
        name="profileViewModel"
        type="com.example.siddhi.mvvm_login.viewmodel.ProfileViewModel"
        />
  </data>
  <FrameLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      >
    <TextView
        android:id="@+id/logging_in"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="@string/logging_in"
        android:textAlignment="center"
        app:visibleGone="@{isLoading}"
        />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginEnd="@dimen/item_horizontal_margin"
        android:layout_marginStart="@dimen/item_horizontal_margin"
        android:gravity="center_vertical|center_horizontal"
        android:orientation="vertical"
        android:padding="5dp"
        android:paddingTop="@dimen/activity_vertical_margin"
        app:visibleGone="@{!isLoading}"
        >

      <ImageView
          android:id="@+id/imageView"
          android:layout_width="@dimen/logo_width"
          android:layout_height="@dimen/logo_height"
          android:src="@drawable/gfee_logo"
          />

      <TextView
          android:id="@+id/emp_pk"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:contentDescription="Emp_pk"
          android:paddingBottom="5dp"
          android:text="@{profileViewModel.emp_pk}"
          android:textAlignment="center"
          android:textSize="20sp"
          android:textStyle="bold"
          />

      <TextView
          android:id="@+id/emp_lic"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:contentDescription="Emp_lic"
          android:paddingBottom="5dp"
          android:text="@{profileViewModel.emp_lic}"
          android:textAlignment="center"
          android:textSize="20sp"
          />

    </LinearLayout>

  </FrameLayout>
</layout>

CustomBindingAdapter

public class CustomBindingAdapter {
  @BindingAdapter("visibleGone") public static void showHide(View view, boolean show) {
    view.setVisibility(show ? View.VISIBLE : View.GONE);
    Log.e("show", "" + show);
  }
}

Java Fragment

public class ProfileFragment extends Fragment {
  private ProfilefragmentBinding binding;

  public ProfileFragment() {
    // Required empty public constructor
  }

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    binding = DataBindingUtil.inflate(inflater, R.layout.profilefragment, container, false);
    Log.e("FirstTimeIsLoading","" + binding.getIsLoading());
    binding.setIsLoading(true);
    Log.e("SecondTimeIsLoading","" + binding.getIsLoading());
    return binding.getRoot();
  }

  @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    final ProfileViewModel viewModel = ViewModelProviders.of(this).get(ProfileViewModel.class);
    binding.setProfileViewModel(viewModel);
    Log.e("ThirdTimeIsLoading","" + binding.getIsLoading());
    binding.setIsLoading(true);
    Log.e("FourthTimeIsLoading","" + binding.getIsLoading());
    observeViewModel(viewModel);
  }

  private void observeViewModel(final ProfileViewModel viewModel) {
    viewModel.getObservableProfile().observe(this, new Observer<List<UserInfo>>() {
      @Override public void onChanged(@Nullable List<UserInfo> userInfos) {
        if (userInfos != null) {
          binding.setIsLoading(false);
          Log.e("isloadingFalse","" + binding.getIsLoading());
          viewModel.setEmp_pk(userInfos.get(0).getEmpPk());
          viewModel.setEmp_lic(userInfos.get(0).getEmpLicenceType());
        } else {
          Log.e("userInfos is null", "");
        }
      }
    });
  }
}

My logcat of the boolean value

E/FirstTimeIsLoading: false
E/SecondTimeIsLoading: true
I/art: Background sticky concurrent mark sweep GC freed 15486(3MB) AllocSpace objects, 0(0B) LOS objects, 28% free, 8MB/12MB, paused 11.385ms total 63.940ms
E/ThirdTimeIsLoading: true
E/FourthTimeIsLoading: true

                       [ 03-02 01:18:22.091  5874: 5874 D/         ]
                       HostConnection::get() New Host Connection established 0xd98cd400, tid 5874


                       [ 03-02 01:18:22.110  5874: 5874 W/         ]
                       Process pipe failed
E/show: true
E/show: false
E/isloadingFalse: false
E/setEmp_pk: 166
E/show: false
E/show: true

logcat after adding Log.e("show", "" + show + " " + view.getClass().getName()); to CustomBindingAdapter

03/02 14:08:07: Launching app
$ adb install-multiple -r -t D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_4.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_5.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_0.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_6.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_9.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_8.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_7.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_1.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\dep\dependencies.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_3.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\intermediates\split-apk\debug\slices\slice_2.apk D:\Siddhi\Local Projects\MVVM_Login\app\build\outputs\apk\debug\app-debug.apk 
Split APKs installed
$ adb shell am start -n "com.example.siddhi.mvvm_login/com.example.siddhi.mvvm_login.view.ui.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Client not ready yet..Connected to process 3170 on device genymotion-google_pixel_xl___7_1_0___api_25___1440x2560-192.168.87.101:5555
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
W/System: ClassLoader referenced unknown path: /data/app/com.example.siddhi.mvvm_login-1/lib/x86
I/InstantRun: starting instant run server: is main process
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
E/FirstTimeIsLoading: false
E/SecondTimeIsLoading: true
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
E/ThirdTimeIsLoading: true
E/FourthTimeIsLoading: true

                       [ 03-02 03:45:18.242  3170: 3170 D/         ]
                       HostConnection::get() New Host Connection established 0xd6e2d140, tid 3170


                       [ 03-02 03:45:18.250  3170: 3170 W/         ]
                       Process pipe failed
E/show: true android.support.v7.widget.AppCompatTextView
E/show: false android.widget.LinearLayout
D/libEGL: Emulator has host GPU support, qemu.gles is set to 1.
E/libEGL: load_driver(/system/lib/egl/libGLES_emulation.so): dlopen failed: library "/system/lib/egl/libGLES_emulation.so" not found
D/libEGL: loaded /system/lib/egl/libEGL_emulation.so
D/libEGL: loaded /system/lib/egl/libGLESv1_CM_emulation.so
D/libEGL: loaded /system/lib/egl/libGLESv2_emulation.so

          [ 03-02 03:45:18.361  3170: 3194 D/         ]
          HostConnection::get() New Host Connection established 0xd6e2d5c0, tid 3194
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
E/EGL_emulation: tid 3194: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xd6bea500, error=EGL_BAD_MATCH
W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
E/response_data: com.example.siddhi.mvvm_login.service.model.LoginResponse@649f367
E/isloadingFalse: false
E/setEmp_pk: 166
E/show: false android.support.v7.widget.AppCompatTextView
E/show: true android.widget.LinearLayout

Debugger screenshot enter image description here

LoginRepo code where I'd made a mistake of setting the thread delay to 200 rather than 2000

    public LiveData<List<UserInfo>> getUserLiveData(String id, String password, String device_id, String token) {
    final MutableLiveData<List<UserInfo>> user = new MutableLiveData<>();
    final MutableLiveData<String> emp_pk = new MutableLiveData<>();

    gfeeLoginService.getProfileDetails(id, password,"","").enqueue(new Callback<LoginResponse>() {
      @Override public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
        simulateDelay();
        Log.e("response_data","" + response.body());
        user.setValue(response.body().getUserInfo());
        emp_pk.setValue(response.body().getUserInfo().get(0).getEmpPk());
      }

      @Override public void onFailure(Call<LoginResponse> call, Throwable t) {
        user.setValue(null);
        Log.e("Data", "is NULL! " + t);
      }
    });
    return user;
  }

  private void simulateDelay() {
    try {
      Thread.sleep(2000); //mistake of adding 200 rather than 2000
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
like image 513
Siddhivinayak Avatar asked Nov 18 '22 18:11

Siddhivinayak


1 Answers

You can make observable boolean in model class and set true and false as your requirement.

e.g

<TextView
        android:id="@+id/logging_in"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="@string/logging_in"
        android:visibility="@{profileViewModel.isLoading ? View.GONE : View.VISIBLE}"/>
like image 80
Amar Pal Singh Avatar answered Dec 16 '22 01:12

Amar Pal Singh