我正在做一个项目,我必须在片段之间传递数据。所有数据都是从myDatabaseHandler class
(sqliteopenhelper)提供的。我是手工写这篇文章的,所以忽略语法错误,如果有的话。
下面是myActivity
的样子(包含selectionfragment和infofragment):
选择片段(包含GridView
)
信息片段(ViewPager
带about5-6 child fragments
)
儿童碎片1
儿童碎片2
儿童碎片3
…
我到目前为止所做的是:
selectfrag扩展片段:
MyCommunicator communicator;
GridView myGrid;
onItemSelected(... int position, ...) {
communicator.respond("The id i get from getTag()..");
}
public void setCommunicator(MyCommunicator communicator) {
this.communicator = communicator;
}
public interface MyCommunicator {
public void respond(String id);
}
活动扩展碎片活动实现selectfrag.mycommunicator:
FragmentManager manager;
SelectFrag selectFrag;
InfoFrag infoFrag;
onCreate() {
manager = getSupportFragmentManager();
selectFrag = (SelectFrag) manager.findFragmentById(...);
selectFrag.setCommunicator(this);
}
@Override
public void respond(String id) {
DatabaseHandler db = new DatabaseHandler(this);
try {
CustomObject obj = db.getObj(id);
} finally {
db.close();
}
infoFrag = (InfoFrag) manager.findFragmentById(...);
if(obj != null)
infoFrag.changeObj(id)
setTitle(obj.getName();
}
infofrag扩展片段:
ViewPager pager;
Context context;
MyObj obj;
public void changeObj(String id) {
DatabaseHandler db = new DatabaseHandler(context);
this.obj = db.getObj(id);
db.close();
}
protect class MyPagerAdapter extends FragmentPagerAdapter{
public Fragment getItem(int i) {
Fragment frag = null;
switch(i) {
case 0:
frag = new ChildFrag1();
break;
case 1:
frag = new ChildFrag2();
break;
... Goes to case 6 for now.
}
return frag;
}
}
以下是我的布局:
选择“frag.xml”
<RelativeLayout 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=".SelectFrag" >
<GridView
android:id="@+id/selectGridView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="56dp"
android:background="#dd5500"
android:horizontalSpacing="5dp"
android:numColumns="auto_fit"
android:paddingLeft="10dp"
android:paddingRight="2dp"
android:paddingTop="3dp"
android:stretchMode="columnWidth"
android:verticalSpacing="5dp" >
</GridView>
</RelativeLayout>
主要活动.xml:
<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=".MyActivity"
android:orientation="vertical" >
<fragment
android:id="@+id/selectFragment"
android:name="my.package.SelectFragment"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="3" />
<fragment
android:id="@+id/infoFragment"
android:name="my.package.InfoFragment"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="7" />
</LinearLayout>
信息碎片.xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/myPager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.PagerTitleStrip
android:id="@+id/my_pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
该应用程序当前将信息从selectfrag传递到activity,activity将信息传递给infofrag。我想让这个身份证一直到孩子的碎片。我在考虑可能实现infofrag的mycommunicator并将数据传递给子片段,但这不会对不可见的子片段抛出nullpointerexception。
*注意:*selectfrag和infofrag在活动中始终可见。当在selectfrag的gridview中选择新项时,infofrag必须刷新。
谢谢你的帮助!
编辑:我试过使用“通讯接口”,但每次都会迷路:(哈哈…)有人能给我一个简单的方法吗?我所有的孩子片段都能从selectfrag实现通信器吗?如果是,这是正确的方法吗?我认为infofragment应该实现接口并将数据传递给它的子级。但我不知道该怎么做才能让孩子们振作起来。我想做的另一件事是在sharedpreferences中存储lastitemclicked,然后从我的db访问对象。我真的很困惑。/再次感谢!
最佳答案
我想你面临的是另一个问题。
您需要创建以下组件:
要在片段中实现的接口。
实现该接口的侦听器的列表。
从该列表中添加/删除项。
最后告诉你的听众发生了什么事。
我将概述一个超级简化的版本。
接口:
这很简单:
public interface DataChangeListener {
void onDataChanged();
}
监听器列表:这也很简单…在你的控制器/活动/单例或任何你需要执行操作和通知监听器的地方…
protected List<DataChangeListener> mListeners = new ArrayList<DataChangeListener>();
public void addDataChangeListener(DataChangeListener listener) {
if (listener != null && !mListeners.contains(listener)) {
mListeners.add(listener);
}
}
public void removeDataChangeListener(DataChangeListener listener) {
if (listener != null) {
mListeners.remove(listener);
}
}
那么你的碎片…(例如)
public class YourFragment extends Fragment implements DataChangeListener {
private SomeControllerForExample mController;
@Override
public void onPause() {
super.onPause();
mController.removeDataChangeListener(this);
}
@Override
public void onResume() {
super.onResume();
mController.addDataChangeListener(this);
}
}
到目前为止,在恢复时注册,在不再可见时移除。
你还需要实现这个方法…
@Override
public void onDataSetChanged() {
// DO WHATEVER YOU NEED TO DO
}
最后,在控制器中有一个notify方法(与列表中的方法相同)
private void notifyListeners(){
for (DataChangeListener listener : mListeners) {
if (listener != null) {
listener.onDataSetChanged();
}
}
}
这个模式适用于任何事情,这是一个很好的简单的方法,让你的用户界面知道你已经检索了新数据,适配器必须被通知,等等。
用这样的方法重新思考你的问题,事情会容易得多。
关于android - 在嵌套 fragment 之间传递数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20775691/