想要用SharePreferences更新第二个片段中的数据,但第二个碎片没有更新



我正在制作一个计算器应用程序,希望在第二个片段中更新历史记录,但无法找到更新第二个碎片中ListView的完美解决方案。我尝试了很多解决方案,但没有一个能正常工作我正在使用ViewPager在计算器和历史片段之间滑动。我厌倦了bundle类,但如果我在ViewPager的第一个Fragment(CalculatorFragment(的OnCreat方法中使用bundle,它会在启动应用程序后显示我的空白屏幕;如果我在Equal Button中使用Bundle类,它会使应用程序崩溃。在这里,我将viewPager的id作为片段的Container传递。

当他们使用Framelayout作为碎片容器时,我看到许多答案都能完美地工作,但我想保留ViewPager的滑动功能,我尝试了许多解决方案,但没有一个能与ViewPger一起正常工作,我在代码中添加了SharedPreferences,但当我使用计算器时,它不会更新(不实时(。SharedPreferences似乎有效,但当应用程序运行时,它们不会更新历史记录当我重新启动应用程序时,它会显示我在历史片段中的最后一次计算。

我传递了SharedPreferences,并在第二个片段(History片段(的onResume/onStart方法中获取字符串,但它只显示了我关闭应用程序时最后一次计算的历史

我正在使用Custom ArrayList在History Fragment中存储和显示我的History输出。

每当有人点击"时,我想将数据(显示历史的计算(传递给HistoryFragment="按钮。"按钮调用计算器应用程序中的equal方法。

发生的情况示例如果我在计算器中进行此计算,则不会更新

在历史记录中,它显示了我关闭应用程序时的最后一个

以下是我迄今为止所做的

这是使用SharedPreferences在CalculatorFragment.java(第一个片段(中保存答案的代码

我也不知道该用.appy((还是.commit((

public View onCreatView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_calculator, container, false);
SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor mEditor = mPreferences.edit();
/*
other code
*/
public void Equals() {
String calc = etCalc.getText().toString();
if (calc.split("\+").length == 2) {
String[] calculation = calc.split("\+");
String Ans = String.valueOf(Double.parseDouble(calculation[0]) + 
Double.parseDouble(calculation[1]));
etCalc.setText(Ans);
tvCalc.setText(calc);
mEditor.putString("key",calc+"="+Ans);
mEditor.apply();
}
}

HistoryFragment.java

import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;

public class HistoryFragment extends Fragment {
ArrayList<HistoryList> historyLists;
SharedPreferences mPreferences;
String History = "";
View rootView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_history, container, false);
return rootView;
}
public void onResume(){
super.onResume();
SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
History = mPreferences.getString("key", "");
if (History.split("=").length == 2) {
historyLists = new ArrayList<>();
historyLists.add(new HistoryList(History.split("=")[0], History.split("=")[1]));
}
HistoryAdapter adapter = new HistoryAdapter(getActivity(), historyLists);
ListView listView = rootView.findViewById(R.id.history);
listView.setAdapter(adapter);
}
}

MainActivity.java

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
ViewPager viewPager;
pageAdapter pageAdapter;
Button btnEqual;
@RequiresApi(api = Build.VERSION_CODES.M)
@SuppressLint({"SetTextI18n", "UseCompatLoadingForDrawables"})
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewPager);
//Get rid of ActionBar
ActionBar actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.hide();
pageAdapter = new pageAdapter(getSupportFragmentManager(), 2);
viewPager.setAdapter(pageAdapter);
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

如果您需要任何其他应用程序代码,请进行注释。

我找到了这个问题的解决方案。我们可以使用SharedViewModel通过片段传递数据,而无需使用SharedPreferences。我们可以将文本设置为ViewModel,并在第二个片段中获取它,即使两个片段都处于恢复状态(因为这里使用的是简单的ViewPager,所以两个片段均处于恢复状态(。

我在下面发布我的代码以供参考,我是如何更新第二个片段中的数据的。

将此代码添加到MainActivity.java文件中。添加两个片段是必要的,如果只添加任何一个片段,它将不会有ViewPager的幻灯片效果。

getSupportFragmentManager().beginTransaction().add(R.id.viewPager, new CalculatorFragment()).add(R.id.viewPager, new HistoryFragment()).commit();

CalculatorFragment.java文件中将文本设置为ViewModel。

public void Equals() {
String calc = etCalc.getText().toString();
if (calc.split("\+").length == 2) {
String[] calculation = calc.split("\+");
String Ans = String.valueOf(Double.parseDouble(calculation[0]) + 
Double.parseDouble(calculation[1]));
etCalc.setText(Ans);
viewModel.setText(Ans);
}
//to send data to ViewModel
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(Objects.requireNonNull(getActivity())).get(SharedViewModel.class);
}
}

创建一个名为SharedViewModel.java的类

package com.shashank.calculator;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class SharedViewModel extends ViewModel {
private final MutableLiveData<CharSequence> text = new MutableLiveData<>();
public void setText(CharSequence input) {
text.setValue(input);
}
public LiveData<CharSequence> getText() {
return text;
}
}

最后在第二个HistoryFragment.java中从ViewModel中获取数据

public class HistoryFragment extends Fragment {
ArrayList<HistoryList> historyLists;
HistoryAdapter adapter;
SharedViewModel viewModel;
String History;
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_history, container, false);
listView = rootView.findViewById(R.id.history);
historyLists = new ArrayList<>();
return rootView;
}
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// getting data from SharedViewModel and setting it to ListView
viewModel = ViewModelProviders.of(Objects.requireNonNull(getActivity())).get(SharedViewModel.class);
viewModel.getText().observe(getViewLifecycleOwner(), charSequence -> {
History = String.valueOf(charSequence);
adapter = new HistoryAdapter(Objects.requireNonNull(getActivity()), historyLists);
historyLists.add(0,History);
listView.setAdapter(adapter);
}
});
}

最新更新