繁体   English   中英

如何从onRestart方法刷新TabbedActivity的视图 如何从其他类访问片段的view元素

[英]How to refresh TabbedActivity's View from onRestart method | How to access fragment's view element from other class

我已经从TabbedActivity模板(在Android Studio中)创建了活动: 在此处输入图片说明
该模板使用FragmentFragmentPagerAdapter来处理选项卡。

这是两个类的代码, 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类中,全局有一个SectionsPagerAdapterViewPager的实例:

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

我已经尝试做:

  1. 这只是行不通的:

     @Override protected void onRestart() { super.onRestart(); mSectionsPagerAdapter.notifyDataSetChanged(); } 
  2. 由于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中有一个列表。 有几种方法可以解决您的问题,建议您使用第一种方法,因为这是最简单的方法。

  1. 片段具有生命周期回调,这些回调与包含该片段的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 } } 
  2. 另一种选择是获取活动中您的片段的引用。 我通常使用的解决方案是保留对适配器内部片段的引用。 它类似于您问题中的第二个选项。 解决方案的唯一问题是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(); } 
  3. 每当活动中有片段时,无论是否在ViewPager中,都可以使用FragmentManager获得对该片段的引用。 检查对有关ViewPager选项的详细信息。

上面的所有代码都非常简单明了,如果您希望在Kotlin中实现它,则不需要任何特殊的Kotlin习惯用法。 您可以先在android studio中转换类。 去做吧:

  • 导航到您的Java类
  • 在Windows上按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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM