0

I'm currently updating the source code with the ViewBindings but I'm not getting them to work for child layouts of the other modules which was working previously. I'm on Android Studio 4.1.3. I added viewBinding.enabled = true to app modules build.gradle. But when I try to access a button from the child layouts, it does not give any error but it does not perform the operation also.

main_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">

<com.playerview.TestPlayerView
    android:id="@+id/testPlayerView"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    app:v3PlaybackEnabled="true"
    app:always_show_go_to_live="true"
    app:extra_overlay_layout = "@array/extra_overlays"
    app:server_side_ad_overlay_index = "1"
    app:hide_play_pause_on_live="true"
    app:show_partner_logo="true"
    app:hide_seek_controllers_on_live="true"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:show_subtitle_on_full_screen="true" />

</androidx.constraintlayout.widget.ConstraintLayout>

FragmentBindingProvider.kt

class FragmentBindingProvider private constructor(
val btnPlayNext: Button?,
val testPlayerView: TestPlayerView,
val txtPlaylistPosition: TextView?,
val btnMute: ToggleButton?,
private val root: View
) : ViewBinding {

override fun getRoot(): View = root

companion object {
    fun inflate(isLogoView: Boolean, inflater: LayoutInflater, container: ViewGroup?): FragmentBindingProvider {
        return if (isLogoView) initLogo(inflater, container) else init(inflater, container)
    }

    private fun initLogo(inflater: LayoutInflater, container: ViewGroup?): FragmentBindingProvider {
        val binding = FragmentLogoBinding.inflate(inflater, container, false)
        return FragmentBindingProvider(
            btnPlayNext = binding.btnPlayNext,
            testPlayerView = binding.testPlayerView,
            txtPlaylistPosition = binding.txtPlaylistPosition,
            btnMute = binding.testPlayerView.findViewById(R.id.btnMute),
            root = binding.root
        )
    }
  }
}

player_video_controls.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone"
    tools:visibility="visible">

         <include
        android:id="@+id/player_volume_layout"
        layout="@layout/view_controls_volume"
        android:layout_width="@dimen/player_ad_volume_width"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/bottom_bar"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/bottom_bar" />

</androidx.constraintlayout.widget.ConstraintLayout>

view_controls_volume.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:background="@color/transparent_black_percent_80">

    <ToggleButton
        android:id="@+id/btnMute"
        android:layout_width="@dimen/top_controls_icon_width"
        android:layout_height="@dimen/top_controls_icon_height"
        android:layout_gravity="center"
        android:background="@drawable/ic_volume"
        android:contentDescription="@null"
        android:scaleType="center"
        android:checked="true"
        android:textOff=""
        android:textOn="" />

</FrameLayout>

MainFragment.kt

override fun onStart() {
    super.onStart()
    observeViewModel()

    /*Here calling view of child layout*/
    binding.btnMute?.setOnCheckedChangeListener { v, isChecked ->
        if (isChecked && binding.testPlayerView.isMuted()) {
            binding.testPlayerView.unmute()
        } else {
            binding.testPlayerView.mute()
        }
    }
}

If anyone gets idea please let me know.

Anshul Tyagi
  • 2,076
  • 4
  • 34
  • 65
  • Does [this](https://stackoverflow.com/a/60260556/4587527) answer of mine help? – Somesh Kumar Mar 31 '21 at 09:21
  • No @SomeshKumar it didn't help – Anshul Tyagi Apr 02 '21 at 13:46
  • Did you try debugging your generated binding in runtime? If that button is null then it failed to find it by ID on the player view from binding. I assume you're using `player_video_controls` same way exoPlayer uses its controller layout. If that's the case try to put a breakpoint on the player view constructor and see if how it handles `player_video_controls` – Luke Apr 11 '21 at 12:47

3 Answers3

0

Only answers the problem that the included layout is in another module:

For a quick fix if the player_video_controls.xml is not in the same module as player_video_controls.xml, add it to the same module or instead of including it, add the layout itself (which is awful but it works).

But, if you have many instances of this issue I suggest you read this answer and try to enable ViewbBinding in every module of your project that is a direct or indirect dependency of the module with this problem.

Sina
  • 2,683
  • 1
  • 13
  • 25
0

bindig.playerVolumeLayout.btnMute your can access like this

Abhijith mogaveera
  • 918
  • 10
  • 16
0

Instead of :

binding.testPlayerView.findViewById(R.id.btnMute),

In your FragmentBindingProvider.kt:

   binding.testPlayerView.btnMute

Because after you do binding.btnMute? and may be btnMute is null and setOnCheckedChangeListener won't be trigger. If it's not the solution remove your val btnMute: ToggleButton? to val btnMute: ToggleButton and remove binding.btnMute? by binding.btnMute. But nromaaly viewbinding is null safe so you have a value for your button.

ande
  • 319
  • 2
  • 14