[英]How to refresh TabbedActivity's View from onRestart method | How to access fragment's view element from other class
我已经从TabbedActivity
模板(在Android Studio中)创建了活动:
该模板使用Fragment
和FragmentPagerAdapter
来处理选项卡。
这是两个类的代码, PlaceholderFragment extends Fragment
,而SectionsPagerAdapter extends FragmentPagerAdapter
:
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list_view, container, false);
int scnum = getArguments().getInt(ARG_SECTION_NUMBER);
final ListView listView = (ListView) rootView.findViewById(R.id.products_list);
// here refresh my listView trough internet
return rootView;
}
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
}
在onCreateView
方法中,我刷新了ListView
。 当我切换标签时会调用此方法。
但是我不需要在用户切换选项卡时刷新ListView
,而是:
1.每10秒
2.当用户回到此活动时( onRestart()
方法)
我不知道如何在onCreateView
方法之外访问我的ListView
。
我已经尝试了许多来自Internet的解决方案,以从onRestart
方法调用onCreateView
方法,并且仅从onRestart()
访问ListView
。 他们都没有工作。
在Activity类中,全局有一个SectionsPagerAdapter
和ViewPager
的实例:
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
通过以下方式将它们初始化为onCreate
:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
我认为,有两种可能的解决方案,访问我的Fragment的视图或仅调用onCreateView
。
我已经尝试做:
这只是行不通的:
@Override protected void onRestart() { super.onRestart(); mSectionsPagerAdapter.notifyDataSetChanged(); }
由于NullPointerException,这使应用程序崩溃:
@Override protected void onRestart() { super.onRestart(); Fragment f = mSectionsPagerAdapter.getItem(0); // tab with my list view is first tab. ( getItem(1) also does not work ) View v = f.getView(); // v is null here, however f isn't. final ListView listView = v.findViewById(R.id.products_list); // v is null, NullPointerException is thrown. // here refresh my listView trough internet }
编辑:
自从我开始使用Kotlin以来,基于该语言的答案也将被接受。 但是,我是Kotlin的新手,因此需要更详细的答案。
因此,您在ViewPager内部的Fragment中有一个列表。 有几种方法可以解决您的问题,建议您使用第一种方法,因为这是最简单的方法。
片段具有生命周期回调,这些回调与包含该片段的Activity的生命周期回调一起触发。 它涵盖了大多数方法,但不幸的是,它不onRestart
您要查找的onRestart
。 但这不是一个大问题。 实际上,您几乎不需要onRestart
因为您拥有onStart
方法,该方法可从Fragments和Activity中访问。 每次重新启动活动+第一次启动活动时都会调用它。 正如我们所看到的,这正是您所需要的。 因此,要使您的列表每次都更新,只需从onCreate
方法中删除更新代码,然后将其放入Fragment的onStart
方法中即可。
public static class PlaceholderFragment extends Fragment { private static final String ARG_SECTION_NUMBER = "section_number"; private ListView listView = null; public PlaceholderFragment() { } public static PlaceholderFragment newInstance(int sectionNumber) { PlaceholderFragment fragment = new PlaceholderFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_list_view, container, false); int scnum = getArguments().getInt(ARG_SECTION_NUMBER); listView = (ListView) rootView.findViewById(R.id.products_list); return rootView; } @Override public void onStart() { // here refresh your listView trough internet using the listView class field } }
另一种选择是获取活动中您的片段的引用。 我通常使用的解决方案是保留对适配器内部片段的引用。 它类似于您问题中的第二个选项。 解决方案的唯一问题是mSectionsPagerAdapter.getItem(0);
始终创建一个新片段,而您需要获取对现有片段的引用。
public class SectionsPagerAdapter extends FragmentPagerAdapter { private PlaceholderFragment fragmentZero = null; public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { PlaceholderFragment tabFragment = PlaceholderFragment.newInstance(position + 1); if (position == 0) { fragmentZero = tabFragment; } return tabFragment; } @Override public int getCount() { return 3; } public PlaceholderFragment getFragmentZero() { return fragmentZero; } }
您还需要将列表更新逻辑移至PlaceholderFragment中的单独方法:
private ListView listView = null; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_list_view, container, false); int scnum = getArguments().getInt(ARG_SECTION_NUMBER); listView = (ListView) rootView.findViewById(R.id.products_list); refreshListView(); return rootView; } public void refreshListView() { // here refresh your listView trough internet }
此时,您可以执行以下操作:
@Override protected void onRestart() { super.onRestart(); Fragment listFragment = mSectionsPagerAdapter.getFragmentZero(); listFragment.refreshListView(); }
每当活动中有片段时,无论是否在ViewPager中,都可以使用FragmentManager获得对该片段的引用。 检查这对有关ViewPager选项的详细信息。
上面的所有代码都非常简单明了,如果您希望在Kotlin中实现它,则不需要任何特殊的Kotlin习惯用法。 您可以先在android studio中转换类。 去做吧:
Control + Shift + A
或在Mac上按Command + Shift + A
Convert Java File to Kotlin File
您最好使用给定类的Kotlin代码。 唯一可能与Java完全不同的是处理ARG_SECTION_NUMBER
因为Kotlin没有静态字段,而是使用了Companion对象 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.