【发布时间】:2020-07-16 04:46:32
【问题描述】:
我是 Android 和 Fragment 的新手,请帮助我。我的应用正在使用导航栏菜单,其中包括主页 (HomeFragment) 和历史记录 (HistoryFragment)。
当用户从主页导航到导航栏并单击历史记录时,我想将 ArrayList (existingRecords) 和记录对象 (todayRecord) 从 HomeFragment 传递到 HistoryFragment。我已配置为将existingRecords 发送到MainActivity 类,如下所示。我不知道如何将todayRecord 传递到意图中。
HomeFragment.class:
@Override
public void onStop() {
super.onStop();
//compare if the date of last record is the same as today
//if same, update today's record
Log.d(msg, "The onStop() event");
if(recordExist){
updateLastRecord(todayRecord);
Log.d(msg, "existing record updated");
}
//if record not found, add new record
else {
addRecord(todayRecord);
Log.d(msg, "New record added");
}
sendDataToMainActivity();
}
public void sendDataToMainActivity(){
Log.d("Android: ", "HomeFragment: Sending Data to MainActivity");
Intent intent = new Intent(getActivity().getBaseContext(), MainActivity.class);
intent.putParcelableArrayListExtra("existingRecords", existingRecords);
getActivity().startActivity(intent);
}
当用户点击导航栏菜单上的历史记录 (R.id.nav_history) 时,我不知道如何调用 sendReceiveData()。
MainActivity.class:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_history, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
loadAdmob();
}
public void sendReceiveData(){
//receive data from HomeFragment
Intent intent = getIntent();
existingRecords = intent.getParcelableArrayListExtra("existingRecords");
//send data to History fragment
Bundle bundle=new Bundle();
bundle.putParcelableArrayList("existingRecords", existingRecords);
//set Fragmentclass Arguments
HistoryFragment fragobj=new HistoryFragment();
fragobj.setArguments(bundle);
}
我已将 HistoryFragment.class 配置为接收数据,但是当我运行代码时,bundle 为 null,因为我无法在 MainActivity 中传递 bundle。
HistoryFragment.class:
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
historyViewModel = ViewModelProviders.of(this).get(HistoryViewModel.class);
View root = inflater.inflate(R.layout.fragment_history, container, false);
Bundle bundle = this.getArguments();
if(bundle!=null){
// handle your code here.
existingRecords = savedInstanceState.getParcelableArrayList("existingRecords");
txtThisMonthSummary = root.findViewById(R.id.txtThisMonthSummary);
txtThisWeekSummary = root.findViewById(R.id.txtThisWeekSummary);
txtThisMonthSummary = root.findViewById(R.id.txtYearSummary);
Log.d("Android: ", "HistoryFragment: Data received");
summary = new History(existingRecords);
txtThisWeekSummary.setText(summary.getWeeklySum());
txtThisMonthSummary.setText(summary.getMonthlySum());
txtThisYearSummary.setText(summary.getYearlySum());
}
return root;
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_zikir"
android:title="@string/menu_home" />
<item
android:id="@+id/nav_history"
android:icon="@drawable/ic_achievement"
android:title="@string/menu_history" />
<item
android:id="@+id/nav_slideshow"
android:icon="@drawable/ic_menu_slideshow"
android:title="@string/menu_achievement" />
</group>
</menu>
【问题讨论】:
-
最简单的方法是在 MainActivity 中使用 ViewModel,并通过 getActivity().getterFunctionForVoewModel() 在两个 Fragment 中使用相同的 ViewModel 实例。如果您将现有记录和今天记录存储在 ViewModel 中,片段和活动都将始终可以访问这些变量的最新值。这也将允许观察它们的值并通过使用 LiveData 包装它们来对更改做出反应。我相信你可以很容易地在网上找到如何做到这一点,如果不是这样的话,这个问题甚至可能是重复的
-
@Rinat 向技术新手推荐 ViewModel !!!
-
出于好奇:你不是将数据保存在某个地方作为历史片段吗?像 sqlite 或远程服务器?
-
@kelvin 是的 HomeFragment 我使用 SharedPreferences 存储现有记录。我可以在 HistoryFragment 中找回它吗?
-
你说的记录如果有多条记录我建议你使用Sqlite,Sharedpreds用于键值对存储。
标签: java android android-fragments