在android标签系统中刷新/重新加载/重新实例化一个片段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23891384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:34:19  来源:igfitidea点击:

Refresh/Reload/Re instantiate a Fragment in an android tab system

androidandroid-fragmentstabsandroid-viewpager

提问by Pacemaker

I have an activity with a viewpager that has 3 tabs and 3 fragments, inside each tab is a fragment. I know that the fragment manager stores the initial instances of the fragments so that if I swipe away from a tab then return to that tab, it is loaded in memory and no updates are applied to it.

我有一个带有 3 个选项卡和 3 个片段的 viewpager 的活动,每个选项卡内都有一个片段。我知道片段管理器存储片段的初始实例,因此如果我从选项卡上滑开然后返回到该选项卡,它会加载到内存中,并且不会对其应用任何更新。

I need the opposite to happen, that is: Every time I swipe to a tab, a new instance of the fragment in that tab needs to load so that data will be updated.

我需要相反的情况发生,即:每次我滑动到一个选项卡时,需要加载该选项卡中片段的一个新实例,以便更新数据。

I have tried:

我试过了:

  1. detach attach fragment in onTabSelected (nothing happens)
  2. remove add fragment in onTabSelected (nothing happens)
  3. setOffscreenPageLimit(0) (Nothing happens)
  4. refresh function inside each fragment to be called onTabSelected (gives nullPointerException)
  1. 在 onTabSelected 中分离附加片段(什么也没发生)
  2. 删除 onTabSelected 中的添加片段(什么也没发生)
  3. setOffscreenPageLimit(0)(什么也没发生)
  4. 每个片段内的刷新函数在 onTabSelected 上调用(给出 nullPointerException)

I have been struggling with this problem for a week with no progress. I appreciate any help, be it a hint, a comment, a suggestion.

我一直在为这个问题苦苦挣扎一周,但没有任何进展。我感谢任何帮助,无论是提示、评论还是建议。

Let me know what code should I post, Thanks.

让我知道我应该发布什么代码,谢谢。

采纳答案by Michele La Ferla

I would use something similar to the following:

我会使用类似于以下内容的内容:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {

    private ViewPager ViewPager;
    private TabsPagerAdapter SectionsPagerAdapter;
    private ActionBar actionBar;

    private String[] tabs = { "Event Details", "Line-up", "Donations", };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     // Initialisation
        ViewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        SectionsPagerAdapter = new TabsPagerAdapter(getSupportFragmentManager());

        ViewPager.setAdapter(SectionsPagerAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
        }

        ViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
    }

    @Override
    public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {

    }

    @Override
    public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
        ViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {

    }

//Attaching the fragments to the tabPagerAdapter
public class TabsPagerAdapter extends FragmentPagerAdapter {

        public TabsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int index) {

            switch (index) {
            case 0:
                return new EventFragment();
            case 1:
                // Points to the Lineup class
                return new LineupFragment();
            case 2:
                // Points to the 
                return new DonationFragment();
            case 3:

                return new ConcertFragment();
            }

            return null;
        }
@Override
        public int getCount() {
            // get item count - equal to number of tabs
            return 4;
        }
    }

//Add your fragments here

Hope this helps you :)

希望这对你有帮助:)

回答by Edwin Wachs

I know the answer is old, but... I found a solution. I can not tell if it's the best one, but in my case, solved.

我知道答案很旧,但是...我找到了解决方案。我不知道它是否是最好的,但就我而言,已经解决了。

In Activity:

在活动中:

@Override
public void onTabSelected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    mViewPager.setCurrentItem(tab.getPosition());


        if (tab.getPosition() == 0) {

            LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
            Intent i = new Intent("TAG_REFRESH");
            lbm.sendBroadcast(i);

        }

}

And your Fragment:

还有你的片段:

public class MyFragment extends Fragment {

MyReceiver r;
public void refresh() {
    //yout code in refresh.
    Log.i("Refresh", "YES");
}

public void onPause() {
    super.onPause();
    LocalBroadcastManager.getInstance(context).unregisterReceiver(r);
}

public void onResume() {
    super.onResume();
    r = new MyReceiver();
    LocalBroadcastManager.getInstance(context).registerReceiver(r,
            new IntentFilter("TAG_REFRESH"));
}

private class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        MyFragment.this.refresh();
    }
}

回答by Zon

Here is the most compact approach, touching a single method in your Fragment class only:

这是最紧凑的方法,仅涉及 Fragment 类中的单个方法:

public class MyFragment extends Fragment {

  @Override
  public void setUserVisibleHint(boolean isVisibleToUser) {

    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser) {

      // Refresh tab data:

      if(getFragmentManager() != null) {

        getFragmentManager()
        .beginTransaction()
        .detach(this)
        .attach(this)
        .commit();
    }
  }
}