我正在做一个项目,我必须在片段之间传递数据。所有数据都是从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/

10-09 12:47