Android碎片更新数据

huangapple go评论71阅读模式
英文:

Android Fragment Update Data

问题

我在尝试从活动中更新片段时遇到了问题。
我有一个进度条片段。

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());
    }
}

在活动中,我有以下两个方法。showFragment 方法应该显示带有给定文本的进度条片段,无论它当前是否可见。对于已经可见的情况,我正在寻求最佳实践。

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);
    }
    // 如果进度条片段已经添加,我应该如何设置文本数据
    // 以便它不会经过我从参数中提取进度文本的生命周期。
    fragmentManager.beginTransaction().replace(.....,TAG).commit();
}
英文:

I am experiencing an issue trying to update the fragment from activity.
I have a progress bar fragment.

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());
}
}

In activity I have these 2 methods. The show fragment method shall show the progress bar fragment with the given text whether it's now visible or not. I am asking for the best practice for the case when it's already visible.

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();
}

答案1

得分: 0

我已经研究过了,我认为这是最佳的体验。

我已经实现了一个 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);
    }
}

然后在片段(Fragment)中:

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.TAG).commit();
        }
        if (progressViewModel == null) {
            progressViewModel = new ViewModelProvider(this).get(ProgressViewModel.class);
        }
        progressViewModel.setText(text);
}

所以,新的 MVVM 模式对于这种模式非常完美。另外一个问题是如何处理 onSaveInstanceState?

(这是您提供的代码的翻译部分。如您所请求,我不会回答您的翻译问题。)

英文:

I've researched as I think the best experience.
I've implemented a ProgressViewModel

public class ProgressViewModel extends ViewModel {
private final MutableLiveData&lt;String&gt; progressText = new MutableLiveData&lt;&gt;();
public LiveData&lt;String&gt; getText() {
return progressText;
}
public void setText(String text) {
progressText.setValue(text);
}
}

Then in fragment

public class ProgressFragment extends Fragment {
public static final String TAG = &quot;ProgressFragment&quot;;
@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);
}
}

And in 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);
}

So the new mvvm pattern works perfectly for this pattern.
The other side of this question is how is onSaveInstanceState done?

huangapple
  • 本文由 发表于 2020年10月20日 23:53:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/64448862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定