简体   繁体   中英

How to observe ViewModel LiveData in a DialogFragment?

I want to share a ViewModel between a fragment and a dialogFragment. Before launching the DialogFragment I update ViewModel liveData with a setter method. When I try to observe the value in DialogFragment, the value is null. I tried sending the value through a bundle's parcelable and it worked.

This is how I call from fragment,

myViewModel.setBitmap(myResult.getBitmap());
            BottomSheetFragment bottomSheetFragment = BottomSheetFragment.getNewInstance(args);
            bottomSheetFragment.setTargetFragment(this, EDIT_FROM_OVERLAY);
            bottomSheetFragment.setListener(this);
            bottomSheetFragment.show(fragmentManager, BottomSheetFragment.TAG);

Dialog Fragment:

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
    {
        super.onViewCreated(view, savedInstanceState);

        myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
        myViewModel.getBitMap().observe(this, bitmap ->
        {
            dialogBitmap = bitmap;
        });

        imageView = view.findViewById(R.id.overlay_image);
        imageView.setImageBitmap(dialogBitmap);
    }

I tried to initializing ViewModel in the onCreateDialog method as well. Still the same result. I want to send a bitmap to the dialogFragment from fragment through ViewModel. What am I missing here? Why I couldn't get the bitmap image that I set in fragment in the dialogFragment? Any pointers would be helpful.

Thanks

Update: Adding View model code,

public class MyViewModel extends AndroidViewModel
{
    private final MutableLiveData<Bitmap> bitmap = new MutableLiveData<>();

    public BitmapViewModel(@NonNull Application application)
    {
        super(application);
    }

    public LiveData<Bitmap> getBitmap()
    {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap)
    {
        bitmap.setValue(bitmap);
    }

    public void clear()
    {
        bitmap.setValue(null);
    }
}

It's because you set the liveData value before creating the dialogFragment.

Do this myViewModel.setBitmap(myResult.getBitmap()); after bottomSheetFragment.show(fragmentManager, BottomSheetFragment.TAG);

@Ali Rezaiyan's suggestion made me realize that i am not setting value right at fragment. So i moved setting bitmap inside observe in dialog fragment.

bitmapViewModel.getBitmap().observe(this, bitmap ->
        {
            imageView.setImageBitmap(bitmap);
        });

Adding it here for future reference.

You're doing this the wrong way. Using your approach, the value of bitmap / dialogBitmap would always be null when you perform imageView.setImageBitmap(dialogBitmap) .

A better approach would be to place the setImageBitmap call inside your LiveData observe call. Also, remember to always check for null . Here's a code snippet that illustrates what I mean:

// initialize your imageView
imageView = view.findViewById(R.id.overlay_image);

// observe your data
myViewModel.getBitMap().observe(this, bitmap ->
    {
        // check for null and set your imageBitmap accordingly
        if(bitmap != null) imageView.setImageBitmap(bitmap);
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM