我正在开发一个项目,我必须在片段之间传递数据.所有数据都是从我的DatabaseHandler class
(SQLiteOpenHelper)提供的.我正在手写这篇文章,所以忽略语法错误,如果有的话.
这是我的Activity
样子(包含SelectionFragment和InfoFragment):
选择片段(包含一个GridView
)
信息片段(ViewPager
约5-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然后从我的数据库访问对象.我真的很困惑:/再次感谢!
我认为你面临着另一个问题.
您需要创建以下组件:
在片段中实现的接口.
实现该接口的侦听器列表.
添加/删除该列表中的项目.
最终通知您的听众发生了什么事.
我将概述一个超简化版本.
界面: 这很简单:
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已检索到新数据,必须通知适配器等.
使用类似的东西重新思考你的问题,事情会容易得多.