在Android主 - 详细信息模式中,如何让MasterActivity将值传递给DetailFragment的父活动(DetailActivity)?因为DetailActivity是存储NavigationDrawerFragment的文件。
我考虑过的事情:
有更好的方法吗?
我有一个主 - 细节模式,但细节已经改变,以便" up"按钮不再返回主列表,而是打开导航抽屉。
现在,我有"假"代码,所以我的导航抽屉有3个项目,当你第一次点击主列表中的项目时,它们都打开了相同的页面。
我的主要问题是:主列表可以将SongDetailFragment.ARG_ITEM_ID
参数传递给详细信息,但导航抽屉无法访问SongDetailFragment.java中的SongDetailFragment.ARG_ITEM_ID
参数,因为导航抽屉在SongDetailActivity.java中实现。
主列表使用行detailIntent.putExtra(SongDetailFragment.ARG_ITEM_ID, id);
将参数传递给详细信息片段
:
SongListActivity.java
/**
* Callback method from {@link SongListFragment.Callbacks}
* indicating that the item with the given ID was selected.
*/
@Override
public void onItemSelected(String id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(SongDetailFragment.ARG_ITEM_ID, id);
SongDetailFragment fragment = new SongDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.songlist_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, SongDetailActivity.class);
detailIntent.putExtra(SongDetailFragment.ARG_ITEM_ID, id); //<-------- Argument
startActivity(detailIntent);
}
}
但是当我点击导航抽屉中的3个虚拟选项之一时,我无法传递该参数,因为导航抽屉位于SongDetailActivity.java中。
SongDetailActivity.java
//---------- NAVIGATION DRAWER -------------
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.songlist_detail_container, PlaceholderFragment.newInstance(position + 1))
.commit();
}
我尝试将此代码从SongDetailFragment.java的onCreate方法复制并粘贴到SongDetailActivity.java的onCreate方法中,希望我能从SongDetailActivity访问相同的SongDetailFragment.ARG_ITEM_ID
变量,但它有编译错误,如Cannot resolve getArguments()
。我后来意识到,师父只是&#34;额外的&#34;在片段中,而不是活动。
SongDetailFragment.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
if (getArguments().containsKey(ARG_ITEM_ID)) {
// Load the dummy title specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load title from a title provider.
mItem = SongItem.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
}
所以,我需要某种方法让导航抽屉存储来自Master的SongDetailFragment.ARG_ITEM_ID
变量,这样它就可以从模型中为每个视图获取正确的数据。如何我能这样做吗?
共享偏好设置?我考虑过使用共享首选项,但我认为这是一个糟糕的主意,因为很难删除所有离开&#34;细节&#34 ;.我想我需要一些不那么全球化的东西。最好是,如果我可以让Master将参数传递给SongDetailActivity(最终传递给导航抽屉),那将是完美的!
回调?我正在查看我的代码文件,想到了什么,我发现了这个&#34;回调&#34;使用Android Studio的Master-Detail向导生成的内容。当它说&#34时,它听起来很合适;这个机制允许活动被通知项目选择,&#34;但我不确定。欢迎任何有关回调适用性的见解或反馈!
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {@link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onItemSelected(String id) {
}
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(SongItem.ITEMS.get(position).id);
}
getActivity()和Setter方法?我发现了这个问题Passing data between a fragment and its container activity。我会尝试一下,但似乎强烈耦合,就像一个糟糕的解决方案。它只是使用父活动的方法(例如setter)通过片段将数据直接传递给父活动。
答案 0 :(得分:0)
我错误地认为SongListActivity.java
只是为SongDetailFragment.java
创建了一个意图,但它正在为SongDetailActivity.java
创建一个意图。当我看到SongDetailFragment.ARG_ITEM_ID
时,它让我很困惑。
Intent detailIntent = new Intent(this, SongDetailActivity.class);
detailIntent.putExtra(SongDetailFragment.ARG_ITEM_ID, id); //<-------- Argument
startActivity(detailIntent);
我不得不改变很多方法来获得这个解决方案,我不记得我做过的所有事情,但这是最终的结果:
所以,我实际上只需要进入SongDetailActivity.java
的{{1}}方法,然后像这样提取捆绑的参数:
onCreate
然后我必须在mSongId = getIntent().getStringExtra(SongDetailFragment.ARG_ITEM_ID);
的{{1}}方法中编辑它,并让它实际实例化正确的片段,然后传递包中的SongDetailActivity.java
:
onNavigationDrawerItemSelected
现在有效!我希望这有助于某人。
要将一个参数从主文件(mSongId
)传递到详细信息的导航抽屉(@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
//------------ THE DEFAULT CODE THAT WASN'T PASSING THE DATA TO THE FRAGMENT----------
if(position == 1) {
fragmentManager.beginTransaction()
.replace(R.id.songlist_detail_container, PlaceholderFragment.newInstance(position + 1, mSongId)) //<------ I actually do not want a placeholder fragment. I want my SongDetailFragment.
.commit();
}
// ------------THE CODE I ADDED THAT WORKS-------------:
else {
SongDetailFragment sdf = new SongDetailFragment(); //<--------- Correct fragment class that I actually needed.
Bundle args = new Bundle();
args.putString(SongDetailFragment.ARG_ITEM_ID, mSongId); //<-------- PASS ALONG THE PARAMETER
sdf.setArguments(args);
fragmentManager.beginTransaction()
.replace(R.id.songlist_detail_container,sdf)
.commit();
}
}
的{{1}}),我不得不将其作为额外内容从掌握细节,并修改细节的导航抽屉回调以使用参数。就像我想的那样,我不需要将片段中的任何内容传递给它的父活动。