代码之家  ›  专栏  ›  技术社区  ›  dev90

视图模型一直在创建实时数据的实例

  •  4
  • dev90  · 技术社区  · 6 年前

    我在中创建了视图模型的实例 onCreate

        ticketViewModel = ViewModelProviders.of(this).get(TicketViewModel.class);
    

    那我有办法了, AddTicket ,使用 viewModel

     public void addTicket(View view){
    
         ticketViewModel.AddTicket(id).observe(this, response ->{
                            dismissLoadingAnimation();
        } 
    

    现在,在添加一个票证之后,用户可以抑制 Add Ticket 按钮和 addTicket() 方法将再次调用。

    但这次 observer 在ViewModel中定义的调用2次,导致2次网络调用和2次 dismissLoadingAnimation 执行。

    如果我继续按 addTicket 按钮中定义的执行观察者的数目 ViewModel

    这是我的视图模型代码。

    public class TicketViewModel extends AndroidViewModel implements IServiceResponse {
    
        MutableLiveData<String> mObservableResponse = new MutableLiveData<String>();
    
    
        public MutableLiveData AddTicket(String id){
    
            JsonObject jsonObject= new JsonObject();
            jsonObject.addProperty("id",  id);
    
            NetworkUtility networkUtility= new NetworkUtility(this, ADD_TICKET);
            networkUtility.hitService(URL, jsonObject, RequestMethods.POST);
    
            return mObservableResponse;
        }
    
    
         @Override
            public void onServiceResponse(String response, String callType){
    
            if(serviceTag.equalsIgnoreCase(ADD_TICKET)){    
                 mObservableResponse.setValue("success");
            }
        }
    
    }
    
    5 回复  |  直到 6 年前
        1
  •  2
  •   DawidJ    6 年前

    ViewModel onClick() 方法。

    你应该在家里做 onCreate() Activity 或在 onViewCreated 你的碎片的方法。如果你愿意的话,就没必要了 removeObserver Lifecycle 机械装置会帮你盖好的。

    yourViewModel.yourList.removeObservers(this)
    

    经过 this 意味着通过你的 活动 ,或者还有第二种方法:

    yourViewModel.yourList.removeObserver(observer)
    
    val observer = object : Observer<YourObject> {
        override fun onChanged(t: YourObject?) {
            //todo
        }
    }
    
        2
  •  2
  •   Aron_A    6 年前
    • Viewmodel的目的是公开可观察对象(Livedata)
    • 视图(活动/片段)的目的是获取这些可观察的对象并观察它们
    • 每当这些可观察对象(Livedata)发生更改时,更改就会自动发布到活动订阅所有者(Activity/Fragment),因此不需要在onPause/onStop中删除它们,因为这不是必需的

    视图模型

    public class TicketViewModel extends AndroidViewModel implements IServiceResponse {
    
        MutableLiveData<String> mObservableResponse = new MutableLiveData<String>();
    
       public LiveData<String> getResponseLiveData(){
            return mObservableResponse;
            }
    
        public void AddTicket(String id){
    
            JsonObject jsonObject= new JsonObject();
            jsonObject.addProperty("id",  id);
    
            NetworkUtility networkUtility= new NetworkUtility(this, ADD_TICKET);
            networkUtility.hitService(URL, jsonObject, RequestMethods.POST);
    
        }
    
    
         @Override
            public void onServiceResponse(String response, String callType){
    
            if(serviceTag.equalsIgnoreCase(ADD_TICKET)){    
                 mObservableResponse.setValue("success");
            }
        }
    
    }
    

        onCreate(){
        ticketViewModel = ViewModelProviders.of(this).get(TicketViewModel.class);
        observeForResponse();
        }
    
        private void observeForResponse(){
           ticketViewModel.getResponseLiveData().observe(this, response ->{
                                //do what has to be updated in UI
        }
        }
    
    public void addTicket(View view){
         ticketViewModel.AddTicket(id);
        }
    

    希望这有帮助:)

        3
  •  1
  •   MikeL    6 年前

    observe 有一次,我更喜欢在家里做 onResume removeObserver 在里面 onPause

    将给定的观察者添加到观察者列表


    我拿了一个现有的代码样本 Fragment 并重命名了所有内容(我希望),这里没有将数据设置到 ViewModel ticketViewModel.AddTicket(id);

    public class ListFragment extends Fragment {
    
        private MyViewModel viewModel;
        private MyRecyclerViewAdapter recyclerViewAdapter;
        private Observer<List<DatabaseObject>> dataObserver;
        private RecyclerView recyclerView;
    
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
            initRecyclerView(rootView, getContext());
            initObservers();
    
            return rootView;
        }
    
        private void initRecyclerView(View rootView, Context context) {
            recyclerViewAdapter = new MyRecyclerViewAdapter(context);
            recyclerView = rootView.findViewById(R.id.recycler_view);
            recyclerView.setAdapter(recyclerViewAdapter);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.addItemDecoration(new DividerNoLastItemDecoration());
        }
    
        private void initObservers() {
            dataObserver = new Observer<List<DatabaseObject>>() {
                @Override
                public void onChanged(@Nullable final List<DatabaseObject> data) {
                    recyclerViewAdapter.setData(data);
                }
            };
        }
    
        @Override
        public void onResume() {
            super.onResume();
            initViewModel();
        }
    
        private void initViewModel() {
            FragmentActivity activity = getActivity();
            if (activity != null) {
                viewModel = ViewModelProviders.of(activity).get(MyViewModel.class);
                viewModel.getData().observe(activity, dataObserver);
            }
        }
    
        @Override
        public void onPause() {
            super.onPause();
            if (viewModel != null) {
                viewModel.getData().removeObserver(dataObserver);
                viewModel = null;
            }
        }
    
    }
    
        4
  •  1
  •   Jurij Pitulja    6 年前

    我也有类似的问题。你可以试着用 SingleLiveEvent

    或者,在我更复杂的情况下,我不得不使用自定义观察者。它看起来是这样的:

    public class CustomObserver implements Observer<YourType> {
        private MyViewModel mViewModel;
    
        public CustomObserver (){}
    
        public void setViewModel(MyViewModel model) {
            mViewModel = model;
        }
    
        @Override
        public void onChanged(@Nullable YourType object) {
            mViewModel.AddTicket(id).removeObserver(this); // removing previous 
            mmViewModel.refreshTickets(); // refreshing Data/UI
            // ... do the job here
            // in your case it`s: dismissLoadingAnimation();
        } 
    }
    

    使用它就像:

    public void addTicket(View view){
    
         ticketViewModel.AddTicket(id).observe(this, myCustomObserver);
    }
    
        5
  •  0
  •   Pavan Varma    6 年前

    LiveData用于包含视图的属性值


    在ViewModel中

    public class TicketViewModel extends AndroidViewModel implements IServiceResponse {
    
        private MutableLiveData<Boolean> showLoadingAnimationLiveData = new MutableLiveData<String>();
    
        public LiveData<Boolean> getShowLoadingAnimationLiveData(){
            return showLoadingAnimationLiveData;
        }
    
        public void addTicket(String id){
    
            JsonObject jsonObject= new JsonObject();
            jsonObject.addProperty("id",  id);
    
            NetworkUtility networkUtility= new NetworkUtility(this, ADD_TICKET);
            networkUtility.hitService(URL, jsonObject, RequestMethods.POST);
            showLoadingAnimationLiveData.setValue(true);
        }
    
    
        @Override
        public void onServiceResponse(String response, String callType){
            if(serviceTag.equalsIgnoreCase(ADD_TICKET)){    
                showLoadingAnimationLiveData.setValue(false);
            }
        }
    
    }
    

    在活动/片段的“onCreate”中

    ticketViewModel.getShowLoadingAnimationLiveData().observe(this,showLoadingAnimation->{
        if(showLoadingAnimation != null && showLoadingAnimation){
            startLoadingAnimation();
        }else{
            dismissLoadingAnimation();
        }
    })
    

    主要概念是划分责任, 活动/片段不需要知道哪个进程正在进行,它们只需要知道这些子视图的当前属性/状态。

    活动/片段对流程的唯一责任是触发它并忘记它,ViewModel需要处理所有事情(比如通知存储库执行工作和更改视图属性)。

    就你而言, 关于这个过程的活动/片段的唯一责任就是触发它。