在嵌套片段之间传递数据

 林伯勋玉萍竣梅 发布于 2023-02-08 10:47

我正在开发一个项目,我必须在片段之间传递数据.所有数据都是从我的DatabaseHandler class(SQLiteOpenHelper)提供的.我正在手写这篇文章,所以忽略语法错误,如果有的话.

这是我的Activity样子(包含SelectionFragment和InfoFragment):

选择片段(包含一个GridView)

信息片段(ViewPager5-6 child fragments)

childFragment1

childFragment2

childFragment3

...

这是我到目前为止所做的:

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);
}



Activity扩展FragmentActivity实现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;
    }
}

这是我的布局:

select_frag.xml



    
    


main_activity.xml:



    

    


info_fragment.xml:



    


该应用程序当前将信息从selectFrag传递给Activity,后者将其传输到infoFrag.我希望这个ID能够一直到达子片段.我在考虑将InfoCom的MyCommunicator实现并将数据传递给子Fragments,但不会为不可见的childFragments抛出NullPointerException.

*注意:* selectFrag和InfoFrag始终在Activity中可见.在selectFrag的GridView中选择新项目时,InfoFrag必须刷新.

谢谢你的帮助!

编辑:
我已经尝试使用"通信界面",但我每次都迷路了:(大声笑..有人可以给我一个简短的方法来做这个吗?我的所有孩子都可以从selectFrag实现传播者吗?如果是的话,是这是正确的方法吗?我认为InfoFragment应该实现接口并将数据传递给它的孩子们.但我不知道如何做到这一点并刷新孩子.我想做的另一件事是存储lastItemClicked sharedPreferences然后从我的数据库访问对象.我真的很困惑:/再次感谢!

1 个回答
  • 我认为你面临着另一个问题.

    您需要创建以下组件:

      在片段中实现的接口.

      实现该接口的侦听器列表.

      添加/删除该列表中的项目.

      最终通知您的听众发生了什么事.

    我将概述一个超简化版本.

    界面: 这很简单:

    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
    }
    

    最后,在你的控制器中有一个通知方法(具有列表的那个)

    private void notifyListeners(){
        for (DataChangeListener listener : mListeners) {
            if (listener != null) {
                 listener.onDataSetChanged();
            }
        }
    }
    

    这种模式适用于任何事情,这是一种简单明了的方法,可以通知您UI已检索到新数据,必须通知适配器等.

    使用类似的东西重新思考你的问题,事情会容易得多.

    2023-02-08 10:49 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有