android - Android - Fragments 和 Tabs 通信
问题描述
我对Android很陌生。
这是我的场景:我有一个带有 3 个选项卡的简单应用程序。在每个选项卡中,我想使用一个或多个片段。这是这种情况:
- 表 1:
- 片段 A
- 选项卡 2:
- 片段 B
- 片段 C
- 片段 D
- 表 3:
- 片段 E
- 片段 F
在“Tab 1”中我没有问题。一切都很好。当我需要进入“Tab 2”和“Tab 3”时会出现问题。
在选项卡 2 中,我必须将一些参数从“片段 B”传播到“片段 C”,从“片段 C”传播到“片段 D”。
然后,当用户单击“片段 D”中的某个按钮时,我必须传递到“选项卡 3”,并且必须将一些参数从“片段 D”传播到“片段 E”。
在我的标签处理主要活动中,我使用了这些组件:
- android.support.design.widget.TabLayout
- android.support.v4.view.ViewPager
- android.support.v4.app.FragmentStatePagerAdapter(我创建了一个自定义类)
- android.support.design.widget.TabLayout.OnTabSelectedListener (我创建了一个自定义类)
我非常简单的FragmentStatePagerAdapter
扩展是:
public class MyOwnPageAdapter extends FragmentStatePagerAdapter {
private int numeroTab;
public MyOwnPageAdapter(FragmentManager fm, int numeroTab) {
super(fm);
this.numeroTab = numeroTab;
}
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new FragmentA() ;
case 1:
return new FragmentB() ;
case 2:
return new FragmentC() ;
default:
return null;
}
}
@Override
public int getCount() {
return numeroTab;
}
}
我非常简单的TabLayout.OnTabSelectedListener
扩展是:
public class TabSelectedListener implements TabLayout.OnTabSelectedListener {
private ViewPager viewPager;
public TabSelectedListener(ViewPager viewPager){
this.viewPager = viewPager;
}
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
我可以在选项卡 2 中的选项卡内切换片段,我可以从片段 B 切换到片段 C,依此类推。我在片段之间传递参数时遇到问题,尤其是从选项卡 2 中的片段 D 到选项卡 3 中的片段 E
在我的 Fragments 实现中,android.support.v4.app.FragmentManager
我可以通过执行以下操作来添加和删除视图(例如片段):
mFragmentManager.beginTransaction().add(rootView.getId(),mListaEdificiFragment, "BUILDS").addToBackStack(null).commit();
问题是参数传播,因为FragmentStatePagerAdapter
似乎缓存视图,所以片段构造函数被调用,但onCreate
不再onCreateView
被调用,所以我无法处理传播的参数。
有什么解决办法吗?还是我的导航模式完全错误?我想避免在一个“大视图”中折叠 Fragment B、Fragment C 和 Fragment D 以隐藏某些部分(对于 Fragment E e Fragment F 相同)
任何建议都更受欢迎
安杰洛
解决方案
最后我得到了解决方案。由于主要问题是碎片通信,我遵循了官方文档
假设我有带有文章列表的片段 A 和片段 B 在哪里可以查看所选文章的详细信息,在我的片段 A 中我写道:
public class FragmentA extends Fragment {
private OnArticleSelectionListener mCallback;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
@Override
public void onStart() {
super.onStart();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activityedifici, container, false);
return rootView;
}
public interface OnArticleSelectionListener {
void onArticleSelection(String articleId);
}
@Override
public void onDetach() {
super.onDetach();
mCallback = null;
}
public void setOnArticleSelectionListener(OnArticleSelectionListener mCallback) {
this.mCallback = mCallback;
}
}
如您所见,我声明了以下接口
public interface OnArticleSelectionListener {
void onArticleSelection(String articleId);
}
这是文章选择监听器。
在我的主要活动中,我写了以下内容:
public class MainActivity implements FragmentA.OnArticleSelectionListener{
//All my own stuffs
@Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof FragmentA){
FragmentA ef = (FragmentA)fragment;
ef.setOnArticleSelectionListener(this);
}
}
@Override
public void onArticleSelection(String articleId) {
if( getSupportFragmentManager().findFragmentByTag(TAG_ARTICLE_DETAIL) != null ){
//FragmentB is the article detail and it has already been created and cached
FragmentB dcf = (FragmentB)getSupportFragmentManager().findFragmentByTag(TAG_ARTICLE_DETAIL);
dcf.updateArticleDetail( articleId );
}else{
//FragmentB is the article detail and it has never been created I create and replace the container with this new fragment
FragmentB dcf = new FragmentB();
//Parameter propagation
Bundle args = new Bundle();
args.putString(FragmentB.ARG_ARTICLE_ID, articleId);
dcf.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container_articles, dcf, TAG_ARTICLE_DETAIL);
transaction.addToBackStack(null);
transaction.commit();
}
}
}
通过这种方式,我能够拦截 FragmentA 中的事件并将它们传播到 FragmentB;当我需要打开一个选项卡时,一切都保持不变,最后(在transaction.commit()
或之后dcf.updateArticleDetail( articleId )
)我执行以下操作 tabLayout.getTabAt(2).select();
,第三个选项卡(选项卡索引从 0 开始)打开并显示详细信息。
我希望这会很有用
安杰洛
推荐阅读
- flutter - 将网页部署到 firebase 主机不会反映所做的所有更改,具体取决于加载页面的设备。颤振网页
- linux - 如何在 /usr/bin 中设置可执行文件的路径?
- c# - 定时器功能在一段时间后自动停止
- powerbi - Power BI - 数据模型不返回匹配键的值,而是返回所有记录
- javascript - 多个 js dom 事件在谷歌开发控制台上不起作用
- elasticsearch - 在弹性搜索查询中获取路径下的嵌套对象不是嵌套类型
- ios - iOS Firebase 推送通知不适用于带有 Xcode 11.5 和 iOS 13 的模拟器
- swiftui - 如何在SwiftUI中使用符合View in ForEach的协议列表
- html - 角度js数据表修复标题滚动条
- selenium - 如何在 JMeter 中声明通用方法以在多个线程中使用脚本