【问题标题】:How to update the List whenever the tabs are changing in view pager无论何时在视图寻呼机中更改选项卡时如何更新列表
【发布时间】:2015-05-14 06:55:37
【问题描述】:

在我的应用程序中,我正在使用使用视图寻呼机的导航选项卡。我已经能够使用发布在以下位置的代码成功绘制标签:

https://github.com/codepath/android_guides/wiki/Sliding-Tabs-with-PagerSlidingTabStrip

在这里,我使用了滑动选项卡和视图寻呼机来获取导航选项卡。一切正常,但是当我移动到另一个选项卡时列表没有更新。 OnResume() 被调用,即使对象列表变量也在调试时得到更新,但视觉列表没有得到更新。

这是我的一些sn-ps代码:

对于 Tab1 :在我的情况下是 ACTIVE 选项卡

 @Override
    public void onResume() {
        super.onResume();

        if(!internetUtil.isConnectedToInternet(getActivity())){
            mSwipeRefreshLayout.setEnabled(false);
        }else{
            mSwipeRefreshLayout.setEnabled(true);
            new GetUsersFromServerTask().execute();  // Here i am making the network calls 
        }
}

在 Tab2 上:这是存档选项卡

 @Override
    public void onResume() {
        super.onResume();
        new GetUsersArchivedFromServerTask().execute(); // Network calls
    }

在 MainActivity 中:

public class MaterialTab extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.material_main_sample);
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new SampleFragmentPagerAdapter(getSupportFragmentManager()));
        PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
        tabsStrip.setViewPager(viewPager);
        tabsStrip.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                if(position == 0){
                   ActiveFragment activeFragment = new ActiveFragment();
                    final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                    ft.detach(activeFragment);
                    ft.attach(activeFragment);
                    ft.commit();
                } if(position == 1){
                    ArchiveFragment archiveFragment = new ArchiveFragment();
                    final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                    ft.detach(archiveFragment);
                    ft.attach(archiveFragment);
                    ft.commit();
                }
            }
        });
    }
}

另外,当我执行 SwipeRefresh 时,列表正在更新。我现在完全困惑为什么会出现这种行为。当我滑动选项卡时,会调用相同的方法并且列表没有更新,但是当我执行 SwipeRefresh 时,它会更新。

这是活动片段:

public class ActiveFragment extends Fragment {

public void updateFragment(){
        new GetUsersArchivedFromServerTask().execute();
    }

 public class GetUsersArchivedFromServerTask extends AsyncTask<User, Void, String> {
        @Override
        protected String doInBackground(Shipment... parmas) {
            // Log.d(TAG, String.valueOf(shipmentDbHandler.getAllActiveShipments().size()));
            _userList1 = userDbHandler.getAllActiveUserByToday(DateTimeUtil.getCurrentTime());
            return "";
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String str) {
            // Set the refresh Listener to false after the list has been loaded with new set of data
            if (mSwipeRefreshLayout.isRefreshing()) {
                mSwipeRefreshLayout.setRefreshing(false);
            }

            if(_userList1.size() == 0){
                ViewGroup parentOne = (ViewGroup) viewOne.getParent();
                if(parentOne != null){
                    parentOne.removeView(viewOne);
                }
            }

            if(_shipmentList1.size() > 0 ){
                mShipmentAdapter = new ShipmentAdapter(getActivity(),_userList1,1); 
                shipmentListView1.setAdapter(mShipmentAdapter);
                setListViewHeightBasedOnChildren(shipmentListView1);
                ViewGroup parentOne = (ViewGroup) viewOne.getParent();
                if(parentOne == null){
                    mainLayoutOne.addView(viewOne);
                }

                mShipmentAdapter.notifyDataSetChanged();
            }
            mSwipeRefreshLayout.setClickable(true);
        }
    }
}   

【问题讨论】:

    标签: android tabs android-viewpager


    【解决方案1】:

    请使用FragmentStatePagerAdapter

    【讨论】:

    • 查看寻呼机也加载侧片段,所以 onResume 方法将被调用,所以当你滑动到那个片段时,onResume 不会再次被调用
    【解决方案2】:

    您的OnPageChangeListener 正在处理碎片。每次选择一个页面时,您都会创建一个新的Fragment 并始终添加它。您试图分离一个尚未附加的新Fragment。它完全一团糟。您的SampleFragmentPagerAdapter 将为您处理这些片段交易。所以只要删除你的setOnPageChangeListener,一切都会好起来的。

    【讨论】:

      【解决方案3】:

      这是一个简单而有效的解决方案。只需像这样替换 setOnPageChangeListener ,这里我们通过 getSupportFragmentManager 访问当前片段的实例并调用相应的片段方法。

          tabsStrip.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
              @Override
              public void onPageSelected(int position) {
                  Fragment currentFragment = getSupportFragmentManager()
                          .findFragmentByTag(
                                  "android:switcher:" + R.id.viewpager + ":"
                                          + mViewPager.getCurrentItem());
                  if (currentFragment instanceof ActiveFragment) {
                      ((ActiveFragment) currentFragment).updateFragment();
                  } else if (currentFragment instanceof ArchiveFragment) {
                      ((ArchiveFragment) currentFragment).updateFragment();
                  }
              }
          });
      

      然后在你各自的片段中放入 updateFragment() 方法。

      public void updateFragment() {
          Toast.makeText(getActivity(), "ActiveFragment", Toast.LENGTH_SHORT)
                  .show();
          // make updates over here
          // new GetUsersArchivedFromServerTask().execute(); // Network calls
      }
      

      参考link

      【讨论】:

      • 我尝试了这种方法,但它为其余元素提供了空指针异常
      • “其余元素”是什么意思?
      • 其余元素意味着在布局中我有 swipeRefresh .. 按钮然后所有这些都给出空指针异常
      • 我请求你把那个片段类放在你的问题中,以便我们有一个清晰的想法。
      • 我已经发布了片段代码......我不能把整个代码,我已经发布了ActiveFragment的sn-ps
      【解决方案4】:
      1. 从页面更改侦听器中删除 onPageSelected(...) 代码,无需手动附加/分离,ViewPager 自动处理此问题。而且你的SampleFragmentPagerAdapter 应该在getItem(...) 中创建每个片段实例。

      2. 应该在每个Fragment的onCreateView中调用new GetUsersFromServerTask().execute(),然后在Asynctask完成后更新视图。


      此外,您应该注意OffscreenPageLimit

      public void setOffscreenPageLimit(整数限制)

      设置在空闲状态下视图层次结构中当前页面任一侧应保留的页面数。超出此限制的页面将在需要时从适配器重新创建。

      这是作为优化提供的。如果您事先知道需要支持的页面数量或在页面上设置了延迟加载机制,则调整此设置可以提高分页动画和交互的感知流畅度。如果您有少量页面 (3-4) 可以同时保持活动状态,那么在用户页面来回切换时,新创建的视图子树的布局将花费更少的时间。

      您应该将此限制保持在较低水平,尤其是当您的网页布局复杂时。此设置默认为 1。

      【讨论】:

      • 我已经删除了片段的附加和分离,但现在片段内部没有调用任何方法。我认为它正在缓存这些片段。
      • 实际上ViewPager 总是将邻居保持在缓存中,这意味着邻居与当前的 Fragment 一起调用。所以当你搬到邻居时,你看不到它正在更新,实际上它已经更新了。
      【解决方案5】:

      在你的片段中使用它。

      @Override
      public void setUserVisibleHint(boolean isVisibleToUser) {
          super.setUserVisibleHint(isVisibleToUser);
      
          if (isVisibleToUser) {
              // Do your code here
          }
      }
      

      每当标签对用户可见时,都会调用此方法。希望这能解决你的问题!!!!

      【讨论】:

      • 谢谢你。这是唯一对我的应用有帮助的东西!
      【解决方案6】:

      尝试使用 notifyDataChange 或 notifyall

      【讨论】:

        【解决方案7】:

        覆盖setPrimaryItem() 并在该位置调用片段的refresh() 方法。每次viewPager 中的选定项目更改时,都会调用setPrimaryItem()。它可能会被多次调用,因此您也必须处理它。 见:setPrimaryItem

        我希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-21
          • 1970-01-01
          • 2015-10-02
          • 1970-01-01
          相关资源
          最近更新 更多