【问题标题】:Refresh/Reload/Re instantiate a Fragment in an android tab system在 android 选项卡系统中刷新/重新加载/重新实例化 Fragment
【发布时间】:2014-05-27 13:53:44
【问题描述】:

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

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

我试过了:

  1. 在 onTabSelected 中分离附加片段(没有任何反应)
  2. 在 onTabSelected 中删除添加片段(没有任何反应)
  3. setOffscreenPageLimit(0)(什么都没有发生)
  4. 刷新功能 在要调用 onTabSelected 的每个片段内(给出 nullPointerException)

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

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

【问题讨论】:

  • 尝试在ViewPager的onPageSelected中调用每个fragment里面写的刷新函数。确保不要在 onPageSelected 中创建新片段。重用 ViewPager 创建的现有片段
  • 好的。我想我现在对这个问题有了更好的了解。我正在使用 FragmentPagerAdapter。我使用 getItem 方法返回片段的新实例。我需要获取当前存在的片段。问题是我必须使用 findFragmentById 或 findFragmentByTag。但我不确定如何在实例化时使用 getItem 设置 id 或标记,以便我可以在 onPageSelected 中检索它。 FragmentPagerAdapter 使用 getItem 设置片段,所以我不知道如何使用 FragmentTransaction 以编程方式设置标签或 id。

标签: android android-fragments tabs android-viewpager


【解决方案1】:

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

活动中:

@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);

        }

}

还有你的片段:

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();
    }
}

【讨论】:

  • 感谢为我工作
  • 有史以来最好的解决方案!
  • 谢谢!你救了我的命
【解决方案2】:

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

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

希望对你有帮助:)

【讨论】:

  • 我实际上尝试了完全相同的代码,这段代码非常有意义,但由于某种原因它没有在滑动时更新片段。但也许是因为我有一些愚蠢的错误。无论如何,我会将此标记为正确答案。
  • 您可以在片段中使用onStart() 方法可能对您有所帮助。
【解决方案3】:

这是最紧凑的方法,仅涉及 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();
    }
  }
}

【讨论】:

  • 怎么会有人不投票这个答案,这就是我想要的。非常感谢。
【解决方案4】:

请试试这个鳕鱼:

@Override
public void setMenuVisibility(boolean visible) {
    super.setMenuVisibility(visible);

    if (isVisible()) {
        //refresh your page
    }
}

【讨论】:

    【解决方案5】:

    我遇到这个问题超过一天,而且我尝试了所有关于这个的解决方案,但在我的情况下没有任何解决方案..

    考虑到我的情况,我在 MVVM 架构中完成了它,我有一个选项卡片段,其中有两个子片段...我必须 更新我的片段,当我切换选项卡和滑动时tab...由于发帖时FragmentStatePagerAdapter and FragmentPagerAdapter is deprecated from API 27,所以我选择了 FragmentStateAdapter ,我找到了两个解决方案

    1. 在我切换标签时有效,但在滑动时无效,
    2. 适用于切换/滑动选项卡的两种情况..

    解决方案,

    案例 1:我的 viewpager impl 与 this from github.. 一样。进入刷新状态 在代码下方切换标签对我有用,但是 当你滑动标签时它不会工作...

    In your TabFragment.kt
    
    fun onViewCreated (...){
             .....
             .....
            viewPager.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback(){
                override fun onPageScrolled(
                    position: Int,
                    positionOffset: Float,
                    positionOffsetPixels: Int
                ) {
                    super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                }
    
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                //Whenever switching tabs, call coms here and our respective child 
                //fragment reloads
                    adapter.notifyItemChanged(position)
                }
    
                override fun onPageScrollStateChanged(state: Int) {
                    super.onPageScrollStateChanged(state)
                }
            })
    }
    

    案例 2: 如果您是遵循 MVVM 架构 的人,并且面临刷新标签的问题,当您 切换/滑动标签 时,以下解决方案将适合您,请执行此操作在你的孩子片段中......

              
        override fun onResume() {
            super.onResume()
           //our fragment willbe in onResume state , after it created, so every time 
          //when i switch/swipe onResume method of respective fragment will be called, 
         //so i called respective method to load my viewmodel ,so that it refresh/update 
         //everytime
            viewModel.yourRespectiveMethod(param1,param2)
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多