0

how to fix crashing apps while using viewBinding, databinding , viewModel and fragment -  My app crash after installed on emulator ,



import android.annotation.SuppressLint
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import com.example.guessinggame.databinding.FragmentGameBinding

class GameFragment : Fragment() {
    private var _binding: FragmentGameBinding? = null
    private val binding get() = _binding!!
    private lateinit var viewModel: GameViewModel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = activity?.run {
            ViewModelProvider(this,)[GameViewModel::class.java]
        } ?: throw Exception("Invalid Activity")
    }

    @SuppressLint("SetTextI18n")
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {

        _binding = FragmentGameBinding.inflate(inflater, container, false)
       // _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_game, container, false)
        val view = binding.root
       // viewModel = ViewModelProvider(this,)[GameViewModel::class.java]

        binding.gameViewModel = viewModel
        binding.lifecycleOwner = viewLifecycleOwner

        viewModel.gameOver.observe(viewLifecycleOwner, Observer { newValue ->
            if (newValue) {
                val action = GameFragmentDirections
                    .actionGameFragmentToResultFragment(viewModel.wonLostMessage())
                view.findNavController().navigate(action)
            }
        })

        binding.guessButton.setOnClickListener() {
            viewModel.makeGuess(binding.guess.text.toString().uppercase())
            binding.guess.text = null
        }
        return view
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }





This is xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".GameFragment">

    <data>

        <variable
            name="gameViewModel"
            type="com.example.guessinggame.GameViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="20sp">

        <TextView
            android:id="@+id/word"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:letterSpacing="0.1"
            android:text="@{gameViewModel.secretWordDisplay}"
            android:textSize="36sp" />

        <TextView
            android:id="@+id/lives"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/lives_left(gameViewModel.livesLeft)}"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/incorrect_guesses"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/incorrect_guesses(gameViewModel.incorrectGuesses)}"
            android:textSize="16sp" />

        <EditText
            android:id="@+id/guess"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="Guess a letter"
            android:inputType="text"
            android:maxLength="1"
            android:textSize="16sp" />

        <Button
            android:id="@+id/guess_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Guess!" />

        <Button
            android:id="@+id/finish_game_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:onClick="@{() -> gameViewModel.finishGame()}"
            android:text="Finish Game" />
    </LinearLayout>
</layout>


In build gradle

    buildFeatures {
        dataBinding = true
        //viewBinding = true
    }

string xml

<resources>
    <string name="app_name">GuessingGame</string>
    <!-- TODO: Remove or change this placeholder text -->
    <string name="hello_blank_fragment">Hello blank fragment</string>
    <string name="guess_a_letter">Guess a letter</string>
    <string name="guess_now">Guess Now</string>
    <string name="start_new_game">Start New Game</string>
    <string name="welcome_to_result">Welcome To Result</string>
    <string name="incorrect_guesses_s">Incorrect Guesses : %s</string>
    <string name="finish_game">Finish Game</string>
    <string name="lives_left">You have %d lives left</string>
    <string name="incorrect_guesses">Incorrect guesses: %s</string>
</resources>

I try many way to fix it . But still can't fix . Plz, help than in advance.

The error i got from logcat

FATAL EXCEPTION: main Process: com.example.guessinggame, PID: 9110 java.lang.RuntimeException: view must have a tag at com.example.guessinggame.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:39) at androidx.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:79) at androidx.databinding.DataBindingUtil.bind(DataBindingUtil.java:199) at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:130) at androidx.databinding.ViewDataBinding.inflateInternal(ViewDataBinding.java:1409) at com.example.guessinggame.databinding.FragmentGameBinding.inflate(FragmentGameBinding.java:78) at com.example.guessinggame.databinding.FragmentGameBinding.inflate(FragmentGameBinding.java:64) at com.example.guessinggame.GameFragment.onCreateView(GameFragment.kt:34) at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3114) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:557) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1455) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3034) at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2945) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3148) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:588) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1455) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3034) at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2952) at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:263) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:350) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:251) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1467) at android.app.Activity.performStart(Activity.java:8079) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3710) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2252) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7842) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 2023-08-04 13:53:42.803 9110-9121 System com.example.guessinggame W A resource failed to call close.

1

1 Answer 1

1

Ur using both ViewBinding & DataBinding

  @SuppressLint("SetTextI18n")
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
_binding = FragmentGameBinding.inflate(inflater, container, false)
   // _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_game, container, false)
    val view = binding.root
   // viewModel = ViewModelProvider(this,)[GameViewModel::class.java]

From Above Code u enabled Viewbinding, commented DataBinding(disabled)

But in .xml file implemented DataBinding

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".GameFragment">

<data>

    <variable
        name="gameViewModel"
        type="com.example.guessinggame.GameViewModel" />
</data>

Remove This Part in .xml, means remove "</layout/>" tag, </data/> tags , bind the model object from GameFragment class Rebuild project & Run

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your comments. Yes I try to use both viewbinding to acess xml and databinding to assign data to xml. but still don't work. Here is link if you want to check insdie - mega.nz/file/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.