How can I make one ViewModel class return multiple data types to an activity or a fragment

拟墨画扇 提交于 2019-12-11 07:33:39

问题


I'm reading this blog post Using Android Architecture Components with Firebase Realtime Database (Part 2) and I'm implementing the last code snippet, and its working.

private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(HOT_STOCK_REF);
private final MediatorLiveData<HotStock> hotStockLiveData = new MediatorLiveData<>();

public HotStockViewModel() {
    // Set up the MediatorLiveData to convert DataSnapshot objects into HotStock objects
    hotStockLiveData.addSource(liveData, new Observer<DataSnapshot>() {
        @Override
        public void onChanged(@Nullable final DataSnapshot dataSnapshot) {
            if (dataSnapshot != null) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        hotStockLiveData.postValue(dataSnapshot.getValue(HotStock.class));
                    }
                }).start();
            } else {
                hotStockLiveData.setValue(null);
            }
        }
    });
}

I'm actually using it to return an array of HotStockViewModel objects wrapped in LiveData (by looping through the result from the database and I really don't know if I should be doing this data manipulation in a ViewModel class) and returning the array to a fragment which just displays it.

Is it possible to use this same ViewModel class to return an array of only the prices wrapped in LiveData (and still also return an array of the HotStockViewModel objects wrapped in LiveData)?

If it is, how can I achieve this? I don't want to return an array of the HotStockViewModel objects wrapped in LiveData and then loop through it to get the prices in a fragment. I don't want the fragment to do any data manipulation at all, only display data.

I saw this stackoverflow question Can an Android Architecture Components ViewModel compose an object from multiple LiveData returning models? but I don't understand the answer. I'm still a Java beginner.


回答1:


and I really don't know if I should be doing this data manipulation in a ViewModel class

In Android MVVM pattern which i think you are using, it is not advisable to perform data manipulation in the Viewmodel class. Rather create a repo class that should handle this. The viewModel class should only get data from the repo class then passes it to whichever UI components needing it.




回答2:


Is it possible to use this same ViewModel class to return an array of only the prices wrapped in LiveData (and still also return an array of the HotStockViewModel objects wrapped in LiveData)

You can create a data class like e.g

 public class ResponseData {
            private ArrayList<HotStock> hotstockVm;
            private ArrayList<double> prices;

            public ArrayList<double> getPrices(){
              return prices;
            };

            public void setPrices(ArrayList<double>prices ){
              this.prices = prices;
            };
    }

Then you create a repo class

    public class Repo{

    private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(HOT_STOCK_REF);
    private final MediatorLiveData hotStockLiveData = new MediatorLiveData();
    private ResponseData response = new ResponseData();
    private ArrayList<HotStock> hotstock = new ArrayList<>();
    private ArrayList<Double> prices = new ArrayList<>();


    public LiveData<ResponseData> getData() {
        //a mutableLivedata to hold data got
        final MutableLivedata<ResponseData> dataMutableLiveData = new MutableLivedata<>();
        // Set up the MediatorLiveData to convert DataSnapshot objects into HotStock objects
        hotStockLiveData.addSource(liveData, new Observer() {
            @Override
            public void onChanged(@Nullable final DataSnapshot dataSnapshot) {
                if (dataSnapshot != null) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            hotStockLiveData.postValue(dataSnapshot.getValue(HotStock.class));
                            //get each hotstock object from firebase
                            HotStock object = dataSnapshot.getValue(HotStock.class);
                            //get the price from each hotstock object
                            //if class HotStock has arrays of inner class where price is, then loop to get price.
                            //assign price to a new list
                            //assign also hotstock to a new list.
                            prices.add(object.getPrice);
                            hotstock.add(object);

                            //set the value of all
                            response.setHotstock(hotstock);
                            response.setPrices(prices);

                            dataMutableLiveData.postValue(response);

                        }
                    }).start();
                } else {
                    hotStockLiveData.setValue(null);
                }
            }
        });
        return dataMutableLiveData;
    }
}

Then you can create a viewModel class

public class AppViewModel extends ViewModel{

    private LiveData<ResponseData> dataLiveData;
    private Repo appRepo;

    public AppViewModel(){
        appRepo = new Repo();
    }

    public LiveData<ResponseData> getLiveData(){
        if(dataLiveData == null){
              dataLiveData = appRepo.getData();
              return dataLiveData;
        }

    }
}

Usage

public class MainActivity extends Activity{

    AppViewModel appViewModel;

    public void onCreate(Bundle SavedInstanceState){
        super.onCreate(SavedInstanceState);
        appViewModel = ViewModelProviders.of(this).get(AppViewModel.class);

        appViewModel.getLiveData().observe(this,response -> {
            //here response is an object of type ResponseData.
            //in this response object you can get your arraylist of prices and also arraylist of hotstock


        });
    }
}


来源:https://stackoverflow.com/questions/50999751/how-can-i-make-one-viewmodel-class-return-multiple-data-types-to-an-activity-or

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!