Android 片段更新数据
Android Fragment Update Data
我在尝试更新来自 activity 的片段时遇到问题。
我有一个进度条片段。
public class ProgressFragment extends Fragment {
public static final String TAG = "ProgressFragment";
public static final String KEY_PROGRESS_TEXT = "keyProgressText";
private static final String KEY_PROGRESS = "keyProgress";
private ProgressBar progressBar;
private String progressText;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_progress, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
progressBar = view.findViewById(R.id.progress_bar);
TextView progressBarInfo = view.findViewById(R.id.progress_bar_info);
Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
if (args == null) {
return;
}
int progress = args.getInt(KEY_PROGRESS);
progressText = args.getString(KEY_PROGRESS_TEXT, getString(R.string.progress_info));
progressBar.setProgress(progress);
progressBarInfo.setText(progressText);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_PROGRESS_TEXT, progressText);
outState.putInt(KEY_PROGRESS, progressBar.getProgress());
}
}
在activity中我有这两种方法。 show fragment 方法应显示带有给定文本的进度条片段,无论它现在是否可见。当它已经可见时,我要求最佳实践。
private ProgressFragment getProgressFragment(){
progressFragment = (ProgressFragment)fragmentManager.findFragmentByTag(ProgressFragment.TAG);
if(progressFragment == null){
progressFragment = new ProgressFragment();
}
return progressFragment;
}
private void showProgress(String text) {
progressFragment = getProgressFragment();
if(!progressFragment.isAdded()){
Bundle args = new Bundle();
args.putString(ProgressFragment.KEY_PROGRESS_TEXT,text);
progressFragment.setArguments(args);
}
// How shall I set my text data if the progress fragment is already added
// So it won't pass the lifecycle where I am extracting progress text from args.
fragmentManager.beginTranslaction().replace(.....,TAG).commit();
}
我研究过我认为最好的体验。
我已经实现了 ProgressViewModel
public class ProgressViewModel extends ViewModel {
private final MutableLiveData<String> progressText = new MutableLiveData<>();
public LiveData<String> getText() {
return progressText;
}
public void setText(String text) {
progressText.setValue(text);
}
}
然后在片段
public class ProgressFragment extends Fragment {
public static final String TAG = "ProgressFragment";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_progress, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentActivity activity = requireActivity();
TextView progressBarInfo = view.findViewById(R.id.progress_bar_info);
ProgressViewModel progressViewModel = new ViewModelProvider(activity).get(ProgressViewModel.class);
progressViewModel.getText().observe(activity, progressBarInfo::setText);
}
}
并且在activity
private ProgressFragment getProgressFragment() {
progressFragment = (ProgressFragment) fragmentManager.findFragmentByTag(ProgressFragment.TAG);
if (progressFragment == null) {
progressFragment = new ProgressFragment();
}
return progressFragment;
}
private void showProgress(String text) {
progressFragment = getProgressFragment();
if (!progressFragment.isAdded()) {
fragmentManager.beginTransaction().replace(R.id.container, progressFragment, ProgressFragment.T
TAG).commit();
}
if (progressViewModel == null) {
progressViewModel = new ViewModelProvider(this).get(ProgressViewModel.class);
}
progressViewModel.setText(text);
}
所以新的 mvvm 模式非常适合这个模式。
这个问题的另一面是onSaveInstanceState是怎么做的?
我在尝试更新来自 activity 的片段时遇到问题。 我有一个进度条片段。
public class ProgressFragment extends Fragment {
public static final String TAG = "ProgressFragment";
public static final String KEY_PROGRESS_TEXT = "keyProgressText";
private static final String KEY_PROGRESS = "keyProgress";
private ProgressBar progressBar;
private String progressText;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_progress, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
progressBar = view.findViewById(R.id.progress_bar);
TextView progressBarInfo = view.findViewById(R.id.progress_bar_info);
Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
if (args == null) {
return;
}
int progress = args.getInt(KEY_PROGRESS);
progressText = args.getString(KEY_PROGRESS_TEXT, getString(R.string.progress_info));
progressBar.setProgress(progress);
progressBarInfo.setText(progressText);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_PROGRESS_TEXT, progressText);
outState.putInt(KEY_PROGRESS, progressBar.getProgress());
}
}
在activity中我有这两种方法。 show fragment 方法应显示带有给定文本的进度条片段,无论它现在是否可见。当它已经可见时,我要求最佳实践。
private ProgressFragment getProgressFragment(){
progressFragment = (ProgressFragment)fragmentManager.findFragmentByTag(ProgressFragment.TAG);
if(progressFragment == null){
progressFragment = new ProgressFragment();
}
return progressFragment;
}
private void showProgress(String text) {
progressFragment = getProgressFragment();
if(!progressFragment.isAdded()){
Bundle args = new Bundle();
args.putString(ProgressFragment.KEY_PROGRESS_TEXT,text);
progressFragment.setArguments(args);
}
// How shall I set my text data if the progress fragment is already added
// So it won't pass the lifecycle where I am extracting progress text from args.
fragmentManager.beginTranslaction().replace(.....,TAG).commit();
}
我研究过我认为最好的体验。 我已经实现了 ProgressViewModel
public class ProgressViewModel extends ViewModel {
private final MutableLiveData<String> progressText = new MutableLiveData<>();
public LiveData<String> getText() {
return progressText;
}
public void setText(String text) {
progressText.setValue(text);
}
}
然后在片段
public class ProgressFragment extends Fragment {
public static final String TAG = "ProgressFragment";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_progress, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentActivity activity = requireActivity();
TextView progressBarInfo = view.findViewById(R.id.progress_bar_info);
ProgressViewModel progressViewModel = new ViewModelProvider(activity).get(ProgressViewModel.class);
progressViewModel.getText().observe(activity, progressBarInfo::setText);
}
}
并且在activity
private ProgressFragment getProgressFragment() {
progressFragment = (ProgressFragment) fragmentManager.findFragmentByTag(ProgressFragment.TAG);
if (progressFragment == null) {
progressFragment = new ProgressFragment();
}
return progressFragment;
}
private void showProgress(String text) {
progressFragment = getProgressFragment();
if (!progressFragment.isAdded()) {
fragmentManager.beginTransaction().replace(R.id.container, progressFragment, ProgressFragment.T
TAG).commit();
}
if (progressViewModel == null) {
progressViewModel = new ViewModelProvider(this).get(ProgressViewModel.class);
}
progressViewModel.setText(text);
}
所以新的 mvvm 模式非常适合这个模式。 这个问题的另一面是onSaveInstanceState是怎么做的?