0

Trying to run method in a layout file from my view model but, I keep getting error: cannot find symbol class ViewModels from my layout file. The layout file is a fragment. I tried invalidating the cache and resyncing but, it did not help. Do i need to add anything to the fragment itself? I seen people use data binding to launch the fragment but, I've read its optional.

Update: Took out OnClick method to test and it is still throwing error. I guess the problem is with my deceleration but, idk why. When i am editing the layout the path shows up when I type the view model name in.

Update2: Tried setting type in variable equal to path of activity that launches fragment for testing and it built just fine. There must be a way to add an import that is not my activity.

Layout file

<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
    <variable
        name="viewTest"
        type="rangers.socmanv2.ViewModels.BattleRhythmViewModel" />
</data>
<android.support.constraint.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:id="@+id/battleRhythmMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragments.BattleRhythmFrag">

<Button
    android:id="@+id/newBattle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="76dp"
    android:layout_marginLeft="76dp"
    android:layout_marginTop="88dp"
    android:text="New Battle Rhythm"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
  />


<Button
    android:id="@+id/editBattle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="76dp"
    android:layout_marginLeft="76dp"
    android:layout_marginTop="50dp"
    android:text="Edit Battle Rhythm"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/newBattle" />

<Button
    android:id="@+id/deleteBattle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="76dp"
    android:layout_marginLeft="76dp"
    android:layout_marginTop="50dp"
    android:text="Delete Battle Rhythm"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/editBattle" />

</android.support.constraint.ConstraintLayout>

</layout>

Fragment

public class BattleRhythmFrag extends Fragment {

private BattleRhythmViewModel mViewModel;
private View view;
private Button test;

public static BattleRhythmFrag newInstance() {
    return new BattleRhythmFrag();
}

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {


    view =  inflater.inflate(R.layout.battle_rhythm_fragment, container, false);

    mViewModel = new BattleRhythmViewModel();



    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mViewModel = ViewModelProviders.of(this).get(BattleRhythmViewModel.class);
    // TODO: Use the ViewModel
}


}

View model


public class BattleRhythmViewModel extends ViewModel {


    public void launchNewFragment(FragmentManager fragM)
    {
        Log.d("viewmodel","hitting launchNewFrag");
        HomeFrag test = new HomeFrag();
        fragM.beginTransaction().replace(R.id.homeContent,test,"launched"+test);

    }

    public void test()
    {Log.d("viewmodel","hitting test");
    }


    }

4
  • Did you add gradle configuration like that *dataBinding { enabled = true } in build.gradle? Commented Jun 24, 2019 at 22:57
  • your onclick method lambda has error change android:onClick="@{() -> viewTest.test()}" with android:onClick="@{(v) -> viewTest.test()}" add your view in lambda Commented Jun 25, 2019 at 7:05
  • Yes @JonathasNascimento build.gradle has that enabled. Commented Jun 25, 2019 at 20:32
  • @mahdishahbazi I took out that line and now just my variable deceleration is giving me the error Commented Jun 25, 2019 at 20:33

1 Answer 1

1

Your error is in viewModel constructor. you must add a default constructor beacuse you don't added any factory ViewModelProvider.Factory but your BattleRhythmViewModel dosen't have any default constructor.

ANSWER 1:


public class BattleRhythmViewModel extends ViewModel {

    public void launchNewFragment(){
    }

    public void test()
    {Log.d("viewmodel","hitting test");
    }
    }
 }

ANSWER 2: better than answer 1 beacuse you don't need add default and can use your fragment in model


public class Factory implements ViewModelProvider.Factory {
    private FragmentManager fragM;

    public Factory(FragmentManager fragM) {
        this.fragM= fragM;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass.isAssignableFrom(BattleRhythmViewModel.class)) {
            return (T) new BattleRhythmViewModel(fragM);
        }
        throw new IllegalArgumentException("Unknown ViewModel class");
    }
}

change your viewmodel creator line to

    Factory factory = new Factory(this)
    mViewModel = ViewModelProviders.of(this,factory).get(BattleRhythmViewModel.class);
Sign up to request clarification or add additional context in comments.

Comments

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.