注意:我是编码的新手,我正在尝试按照标题的一个简单示例。
一切似乎进展顺利,除了我在onClick()
的Tab1Fragment
方法中增加变量时遇到了麻烦。 value
变量的值总是出现null
。
我认为,这与将Interger
与LiveData<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);
}
}
你的问题是两件事,
问题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)