使用ViewModel和LiveData递增变量的简单片段示例 - 变量始终为null

问题描述 投票:1回答:1

注意:我是编码的新手,我正在尝试按照标题的一个简单示例。

一切似乎进展顺利,除了我在onClick()Tab1Fragment方法中增加变量时遇到了麻烦。 value变量的值总是出现null

我认为,这与将IntergerLiveData<Integer>混合有关,但我不知道如何处理它。我已经尝试了各种方法将一个方法转换为另一个方法并返回以获取/存储结果。我跟随的指南(link)使用.setValue()方法,但android studio不会让我使用该方法。

我很乐意修改这个,甚至只是一个超级简单的标签片段教程的链接,我可以将粘贴复制到项目中,并检查这一切是如何工作的。我确信有一种更简单的方法可以完成这项任务,但我想了解如何将这个概念用于未来的项目。

谢谢。

tab1fragment.Java

package com.example.android.tabsharer;

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class Tab1Fragment extends Fragment {
    private static final String TAG = "Tab1Fragment";

    public SharedViewModel model;

    public LiveData<Integer> score;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.tab1_fragment, container, false);

//      Get the viewmodel
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

//      Create observer to update the fragment
        TextView score1 = getActivity().findViewById(R.id.score1);

        final Observer<Integer> scoreObserver = new Observer<Integer>() {
            @Override
            public void onChanged(@Nullable Integer newScore) {
                //Update the textview that holds the score
                score1.setText(newScore);
            }
        };

//      Observe the live data
        model.getScore().observe(getActivity(), scoreObserver);

// Create the button in java, set listener on it, increment score, and store to viewmodel
        final Button button = view.findViewById(R.id.editScore1);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
//              Basically every version of this comes up as null
                Integer value = model.getScore().getValue();
                if (value != null){
                    model.storeScore(++value);
                }
                else {
                    model.storeScore(0);
                }

            }
        });

        return view;
    }
}

shared model view.Java

package com.example.android.tabsharer;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import android.util.Log;

public class SharedViewModel extends AndroidViewModel {

    public static final String TAG = "SharedViewModel";

    private MutableLiveData<Integer> mScore = new MutableLiveData<>();

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

    public Integer storeScore(Integer score) {
        Log.d(TAG, "Score is being stored is " + mScore);
        mScore.setValue(score);
        return score;
    }

    public LiveData<Integer> getScore() {
        Log.d(TAG, "Score is being retrieved");
        if (mScore == null){
            mScore = new MutableLiveData<>();
            mScore.setValue(0);
        }
        return mScore;
    }
}

main activity.Java

package com.example.android.tabsharer;

import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;


public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    public SharedViewModel model;

    private SectionsPageAdapter mSectionsPageAdapter;

    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate: Starting.");

        model = ViewModelProviders.of(this).get(SharedViewModel.class);

        mSectionsPageAdapter = new SectionsPageAdapter(getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.container);
        setupViewPager(mViewPager);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

    }

    private void setupViewPager(ViewPager viewPager) {
        SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
        adapter.addFragment(new Tab1Fragment(), "TAB1");
        adapter.addFragment(new Tab2Fragment(), "TAB2");
        viewPager.setAdapter(adapter);
    }


}
android android-fragments android-tabs android-architecture-components
1个回答
0
投票

你的问题是两件事,


问题1 :(可选)

// Observe the live data
model.getScore().observe(getActivity(), scoreObserver);

你在Fragment中使用观察者,所以你应该使用它的LifeCycle观察这样:

// Observe the live data
model.getScore().observe(this, scoreObserver);

问题2:你是否正在使用Integer作为LiveData中的包装器,它在此方法中没有初始化:

public LiveData<Integer> getScore() {
    Log.d(TAG, "Score is being retrieved");
    if (mScore == null){//This code won't execute because you've initialized it globally.
        mScore = new MutableLiveData<>();
        mScore.setValue(0);
    }
    return mScore;
}

所以,尝试将Interger更改为int,它将使用默认值0进行初始化。

因为Integer将在这里null

// Basically every version of this comes up as null
Integer value = model.getScore().getValue();

解决方案:将private MutableLiveData<Integer> mScore = new MutableLiveData<>();更改为private MutableLiveData<int> mScore = new MutableLiveData<>();(它会向您使用LiveData的所有地方显示错误,因此将其更改为int)

© www.soinside.com 2019 - 2024. All rights reserved.