android - 在 Fragment 中传递参数
问题描述
我正在尝试改进我的 Android 应用程序。我在 GridView 3x3 中有主应用程序菜单(带有可能的操作)。我决定添加 ViewPager 来分隔我的网格。在添加 ViewPager 之前,我只有一个带有 GridView 的 Activity。在我的 onCreate 方法中,我使用 DisplayMetrics 计算了窗口高度,以了解我的 GridView 项目应该使用什么高度。
现在我正在尝试将 ViewPager 与 Fragments 一起使用。我有 ViewPager 和 2 个片段的活动。每个 Fragment 都有相同的布局(LinearLayout 中的 GridView)。我试图以这种方式将屏幕高度传递给 Fragment:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_grid_layout);
pageHeight = getHeight();
Log.d("HEIGHT", "Page height: "+pageHeight);
ViewPager viewPager;
viewPager = findViewById(R.id.main_menu_viewpager);
src = new ArrayList<MainPageTableFragment>();
/*Определяем количество страниц меню*/
int pagesCount = 2;
for (int i = 0; i < pagesCount; i++) {
src.add(MainPageTableFragment.newInstance(i, pageHeight));
}
FragmentPagerAdapter adapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), src);
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
tabLayout.setupWithViewPager(viewPager, true);
}
因此,每次启动 onCreate 方法都应该重新创建片段。
在 Fragment 中,我的身高是这样的:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main_grid_fragment, container, false);
gridView = rootView.findViewById(R.id.main_menu_grid);
//PROBLEM IS HERE...
height = this.getArguments().getInt("containerHeight");
pageNum = this.getArguments().getInt("pageNumber");
populateGridItems(); //method to load items in gridview
return rootView;
}
问题是:当我旋转我的设备时,所有的方法都会被调用,但是
height = this.getArguments().getInt("containerHeight");
使用旧值。例如,在第一次启动(垂直屏幕方向)时,它是 690。当我旋转我的设备时,在 onCreate 我计算新高度(382),但我的 Fragment 采用旧值(690)。
我尝试在几个地方(onAttach、onCreate、onActivityCreated)调用 getArguments(),但没有帮助。
谁能解释一下,问题出在哪里,我该怎么办?
谢谢!
UPD:我的 MainPageTableFragment 的代码
public static MainPageTableFragment newInstance(int pageNumber, int height) {
Bundle args = new Bundle();
args.putInt("pageNumber", pageNumber);
args.putInt("containerHeight", height);
MainPageTableFragment fragment = new MainPageTableFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main_grid_fragment, container, false);
gridView = rootView.findViewById(R.id.main_menu_grid);
height = getArguments().getInt("containerHeight");
Log.d("HEIGHT", "Fragment height in onCreateView: "+height);
pageNum = getArguments().getInt("pageNumber");
populateGridItems();
return rootView;
}
private void populateGridItems() {
/*adding items in GridView*/
gridView.setAdapter(new MenuGridAdapter(this.getContext(), items, height));
}
}
解决方案
我不确定,但我认为这是因为supportFragmentManager
and pagerAdapter
。
第一次instantiateItem
它为片段创建了一个名称,destroyItem
它只是分离片段。然后在旋转后instantiateItem
按名称找到片段并使用旧实例而不是新实例。我认为是为了优化等等。
作为一种解决方案,您可以根据需要从中删除所有片段supportFragmentManager
或覆盖instantiateItem/destroyItem
以删除片段。
推荐阅读
- python - 如何为远程 API 在 Jenkins 中触发的构建获取正确的构建号
- python - 从 4D 数组计算 3D 像素方差
- kotlin - 在 Kotlin 中通过引用传递整数
- python-3.x - Google Sheets API v4 不保存 mergeCells
- data-mining - 词关联挖掘如何泛化n-gram语言模型
- javascript - 天气 api 密钥不起作用
- google-contacts-api - Google GCM 弃用 - 使用 GCM 令牌的旧移动客户端
- ubuntu - sed 和重命名文件
- javascript - $(this) 不在委托事件处理程序中选择子元素
- c# - 从 ResourceDirectory 绑定到 ViewModel 中的属性