【问题标题】:Refresh Viewpager from within the DrawerLayout从 DrawerLayout 中刷新 Viewpager
【发布时间】:2016-12-17 23:34:38
【问题描述】:

背景: 我有一个drawerLayout,其中包含我从Realm 获得的城市列表。 ViewPager 已经在显示该列表。你可以直接从 DrawerLayout 中删除一个城市

问题: 当我从 DrawerLayout 中删除一个城市时,我调用 mViewPager.getAdapter().notifyDataSetChanged,viewPager 没有重新加载。由于 drawerLayout 显示在 ViewPager 上,因此当您关闭它时不会重新加载,并且当我导航返回时,ViewPager / Realm 返回一个java.lang.ArrayIndexOutOfBoundsException: rowIndex > available rows: 4 > 4

你有什么线索可以解决这个问题吗?

为了提供信息,下面是它的工作原理: **在 BaseActivity 中,包含 DrawerLayout **

mCityListAdapter = new CityListAdapter(getBaseContext(), RealmHelper.getStoredCities(), new CityListAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(int position) {
            mPager.setCurrentItem(position);
            mDrawerLayout.closeDrawers();
        }
    }, new CityListAdapter.OnItemLongClickListener() {
        @Override
        public void onItemLongClick(final int position) {
            final CharSequence[] items = {getString(R.string.action_delete_city)};
            AlertDialog.Builder builder = new AlertDialog.Builder(BaseActivity.this);
            builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    RealmHelper.removeCity(RealmHelper.getStoredCities().get(position));
                    mPager.getAdapter().notifyDataSetChanged();
                }
            });
            builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.cancel();
                }
            });

            builder.setTitle(getString(R.string.delete_city_label));
            builder.show();
        }
    });

在包含 viewPager 的 Activity 中

@Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        getLayoutInflater().inflate(R.layout.fragment_pager, mFrameLayout);

        mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
        mPager.addOnPageChangeListener(this);

        mAdapter = new FragmentStatePageSupportAdapter(getSupportFragmentManager(), RealmHelper.getStoredCities().size(), this, RealmHelper.getStoredCities());
        mPager.setAdapter(mAdapter);
        mPager.setOffscreenPageLimit(0);

    }

编辑

我确实覆盖了 getItemPosition 并且它被调用了。所以不是问题。

The @Override
    public int getItemPosition(Object object) {
        Log.v("results", "called getitempostion");
        return POSITION_NONE;
    }  

【问题讨论】:

  • 在 viewPager 上调用 notifyDataSetChanged() 不会重新创建您的片段,因此您必须告诉您的片段刷新其数据。所以你可以使用 LocalBroadCastManager 告诉你的片段刷新数据。
  • 听起来不错的解决方案。所以我把 LocalBroadcast 放在了地方,它工作得很好,但是你会如何强迫他们重新创建呢?通过再次实例化 ViewPager?谢谢
  • 我也遇到了同样的问题,但我从来没有让 viewPager 强制重新创建片段。
  • 也许问题是与领域相关的问题。我调查。
  • 我想我正面临一个已知的错误github.com/realm/realm-java/issues/875

标签: android android-viewpager reload drawerlayout


【解决方案1】:

您应该仅在实际发生更改时才通知数据集,例如

mRealmChangeListener = new RealmChangeListener() {
    @Override
    public void onChange(Object element) {
        mCityListAdapter.notifyDataSetChanged();
    }
}

RealmHelper.getStoredCities().addChangeListener(mRealmChangeListener);

还有

mCityListAdapter = new CityListAdapter(getBaseContext(), RealmHelper.getStoredCities(), new CityListAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(int position) {
       ...
    }
}, new CityListAdapter.OnItemLongClickListener() {
    @Override
    public void onItemLongClick(final int position) {
        ...
        AlertDialog.Builder builder = new AlertDialog.Builder(BaseActivity.this);
        builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                RealmHelper.removeCity(RealmHelper.getStoredCities().get(position));
                ////mPager.getAdapter().notifyDataSetChanged(); // remove this
            }
        });
        ...
    }
});

编辑:好的,我想在这种情况下你应该走更长的路:

mRealmChangeListener = new RealmChangeListener() {
    @Override
    public void onChange(Object element) {
        mCityListAdapter.notifyDataSetChanged();
    }
}

RealmResults<City> listenerSet;
Realm realm;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    realm = Realm.getDefaultInstance();
    listenerSet = realm.where(City.class).findAll();
    listenerSet.addChangeListener(mRealmChangeListener);
}

或类似的东西。

【讨论】:

  • 感谢您的光临。如果我的 ViewPager 不使用 RealmAdapter 而是使用经典的,这会是一个问题吗?
  • 您不需要RealmAdapter,但您必须在RealmChangeListener 中调用notifyDataSetChanged,而不是在事务之后直接调用。
  • 好的,我正在测试你的答案:)
  • 由于某种原因,在检查日志后,删除我的城市 T-T 我关闭时不会调用 onChange
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多