单击基于 MVVM 的架构不起作用的片段 XML 中的按钮侦听器

Click Listener of button from the XML of a fragment that is MVVM based architecture not working

不知道为什么我的注销按钮无法通过数据绑定从 XML 工作。

ProfileFragment.java

这只是查看个人资料的片段。

 public class ProfileFragment extends Fragment {

private ProfileViewModel profileViewModel;
private FragmentProfileBinding binding;

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    profileViewModel =
            new ViewModelProvider(requireActivity()).get(ProfileViewModel.class);

    binding = FragmentProfileBinding.inflate(inflater, container, false);
    binding.setLifecycleOwner(this);
    View root = binding.getRoot();
    //        binding.btnLogout.setOnClickListener(v -> {
    ////            logout(v); from here it works but I want to perform this from XML
    //        });
    profileViewModel.getModelLiveData().observe(getViewLifecycleOwner(), new 
    Observer<UserModel>() {
        @Override
        public void onChanged(UserModel profileViewModel) {
            binding.username.setText(profileViewModel.getUsername());
            binding.email.setText(profileViewModel.getEmail());
            binding.phone.setText(profileViewModel.getPhone());
            binding.cnic.setText(profileViewModel.getCnic());
            binding.adress.setText(profileViewModel.getAdress());
        }
    });
    return root;
}

public void logout(View view) {
    Toast.makeText(view.getContext(), "logout clicked", Toast.LENGTH_SHORT).show();
    FirebaseAuth.getInstance().signOut();
    Intent intent = new Intent(view.getContext(), Login.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    view.getContext().startActivity(intent);
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}
}

ProfileViewModel.java

Profile View 模型先前已填充,然后制作 XML 以查看该文本

public class ProfileViewModel extends ViewModel {

public MutableLiveData<String> username = new MutableLiveData<>();
public MutableLiveData<String> email = new MutableLiveData<>();
public MutableLiveData<String> cnic = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
public MutableLiveData<String> phone = new MutableLiveData<>();
public MutableLiveData<String> adress = new MutableLiveData<>();
public MutableLiveData<String> img = new MutableLiveData<>();

private MutableLiveData<UserModel> userMutableLiveData;

public MutableLiveData<UserModel> getModelLiveData() {

    if (userMutableLiveData == null) {
        userMutableLiveData = new MutableLiveData<>();
    }
    return userMutableLiveData;
}

public ProfileViewModel() {
    UserModel userModel = UserAfterLogin.getUserModel();
    getModelLiveData().setValue(userModel);

}

//the following method needs to be in working with the fragment xml click listener
//    android:onClick="@{(v) -> ProfileFragment.logout(v)}"
public void logout(View view) {
    Toast.makeText(view.getContext(), "clicked", Toast.LENGTH_SHORT).show();
    FirebaseAuth.getInstance().signOut();
    Intent intent = new Intent(view.getContext(), Login.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    view.getContext().startActivity(intent);
}

}

fragment_profile.xml

我的 XML 片段中出现了主要问题。

android:onClick="@{(v) -> ProfileFragment.logout(v)}"

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

<data>

    <variable
        name="ProfileFragment"
        type="com.fyp.utilitymoan.ui.profile.ProfileViewModel" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:background="@drawable/background"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".ui.profile.ProfileFragment">

    <de.hdodenhof.circleimageview.CircleImageView 
     xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/profile_image"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_margin="10dp"
        android:src="@drawable/ic_baseline_person_24"
        app:civ_border_color="@color/white"
        app:civ_border_width="2dp" />

    <EditText
        android:id="@+id/username"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/btn_background"
        android:gravity="center"
        android:hint="Username"
        android:text="@={ProfileFragment.username}"
        android:textColor="@color/white" />

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/btn_background"
        android:gravity="center"
        android:hint="Email"
        android:text="@={ProfileFragment.email}"
        android:textColor="@color/white" />


    <EditText
        android:id="@+id/cnic"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/btn_background"
        android:gravity="center"
        android:hint="CNIC"
        android:inputType="numberDecimal"
        android:text="@={ProfileFragment.cnic}"
        android:textColor="@color/white" />

    <EditText
        android:id="@+id/phone"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/btn_background"
        android:gravity="center"
        android:hint="Phone"
        android:inputType="numberDecimal"
        android:text="@={ProfileFragment.phone}"
        android:textColor="@color/white" />


    <EditText
        android:id="@+id/adress"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/btn_background"
        android:gravity="center"
        android:hint="Address"
        android:text="@={ProfileFragment.adress}"
        android:textColor="@color/white" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:gravity="center"
        android:orientation="horizontal">


        <Button
            android:id="@+id/btnLogout"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="@drawable/btn_background"
            android:clickable="true"
            android:fontFamily="serif"
            android:onClick="@{(v) -> ProfileFragment.logout(v)}"
            android:padding="12dp"
            android:text="Logout"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textStyle="bold" />


        <Button
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="@drawable/btn_background"
            android:fontFamily="serif"
            android:padding="12dp"
            android:text="Save"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textStyle="bold" />


    </LinearLayout>


</LinearLayout>
</layout>

如果您想使用数据绑定从 xml 调用 viewmodel 方法,首先您需要在片段中为 xml 设置 viewmodel 对象。

profileViewModel =
            new ViewModelProvider(requireActivity()).get(ProfileViewModel.class);
    binding = FragmentProfileBinding.inflate(inflater, container, false);
    binding.setLifecycleOwner(this);
    binding.setProfileFragment(profileViewModel);