我正在做一个计算器应用程序,想要更新历史在第二个片段,但不能找到一个完美的解决方案更新列表视图在第二个片段。我试过很多种解决办法,但没有一种有效。我正在使用ViewPager在计算器和历史片段之间滑动。我厌倦了bundle类,但如果我在ViewPager的第一个片段(CalculatorFragment)的OnCreat方法中使用bundle,它在启动应用程序后会显示空白屏幕&如果我在Equal按钮中使用bundle类,它会使应用程序崩溃。这里我将viewPager的id作为片段的容器传递。
我看到许多答案在使用Framelayout作为片段容器时都很好地工作,但我想保持ViewPager的滑动功能,我尝试了许多解决方案,但没有一个能在ViewPger上正常工作,我在代码中添加了SharedPreferences但当我使用Calculator时它没有更新(不是实时的)。SharedPreferences似乎起作用了,但当应用程序运行时,它们不会更新历史记录,当我重新启动应用程序时,它会显示我在历史记录片段中的最后一次计算。
我传递了SharedPreferences并获取了第二个片段(历史片段)的onResume/onStart方法中的字符串,但它只显示了关闭应用程序时上次计算的历史
我正在使用自定义ArrayList来存储和显示历史记录片段中的历史记录输出。
我希望每当任何人单击Application中的“=”按钮时,都将数据(显示历史的计算)传递给HistoryFragment。“=”按钮调用calculator应用程序中的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);
}
});
}
我的中有10个选项卡。打开活动后,第一个片段就会显示出来,但下一个片段中的方法(AsyncTask)会被调用。如果我转到下一个选项卡,比如第3个选项卡,那么将调用第4个中的方法,依此类推。 我不理解这种行为。请救命!
我在弄清楚碎片是如何工作的。我有3个类,MainActivity,Fragment1和fragment2。 MainActivity扩展了 Fragment2还扩展了SherlockFragment,但什么也不做,将它膨胀为空。xml
在我的应用程序中,我有两个片段,分别是fragmentA和FragmentB。当我点击fragmetA中的按钮时,fragmentB中会打开一个列表。现在,当我从fragmentB中的列表中选择一个项目时,我希望将结果传递给fragmentA。我只对所有片段使用一个TabActivity。当列表项在fragmentB中被选中时,我将从堆栈中弹出fragmentB,以便直接返回fragmentA。
我有一个事件序列,通过它,我已经将三个片段一个接一个地添加到背景堆栈中。这些片段,每一个都覆盖了活动的全屏。 我已经存储了从Frag1的提交返回。 现在在Frag3中,基于特定的单击,我想直接回到Frag1并丢弃/弹出之间的所有Fragments。 因此,单击此按钮时,我会向活动发送一条消息,该消息执行以下操作: 但我只是得到一个空白屏幕,所以我假设没有加载碎片。 我甚至试过:在commit-
我想按下mainactivity中的一个按钮,该按钮将启动一个包含片段的新活动的意图。我写了一个主要的活动。带有main活动和第二个_活动按钮的xml。带有片段的xml。当我单击按钮时,第二个活动将由于xml中的片段而崩溃。我已经添加了一个标志,但它没有帮助。该应用程序的想法是通过按下主活动中的按钮,在第二个活动中获取谷歌地图。 我希望你能帮助我:/ 主要活动: 亚活性: activity_mai
我已经创建了默认的Android Studio导航抽屉项目。默认情况下,我有一个活动和三个主要片段。(家庭,画廊,幻灯片),我只是尝试与家庭片段。我已经将 从content_main XML替换为 并将MainActivity修改为