【问题标题】:Toggle Button State in ViewPager when a page is removed删除页面时在 ViewPager 中切换按钮状态
【发布时间】:2017-04-22 20:20:06
【问题描述】:

我有一个切换按钮(在所有页面中),允许用户喜欢页面(viewpager)的内容。

当用户不喜欢某个页面时,该页面将从 viewpager 中删除。

下面是循环

用户“不喜欢” -> 更新 SQLite -> NotifyDatasetChanged() -> 片段 重建 -> Viewpager 显示

问题是假设我在位置 2 并且我“不喜欢” - 页面被删除 - 在其位置放置一个新页面,其切换按钮状态与已删除页面相同,而我希望切换按钮状态根据光标返回的实际值设置。

即使 ToggleButton 的“isChecked()”状态为“true”并且作为 rootview 的一部分在 getItem() 中返回 - 并且还在我创建的模拟 TextView 中显示 - 不知何故“检查”状态从已删除的页面中保留。

适配器

public class CursorPagerAdapter extends FragmentStatePagerAdapter {
    .
    .
    public Fragment getItem(int position) {
        Fragment fragment = null;

            if (mCursor.moveToPosition(position)) {
                Bundle arguments = new Bundle();
                fragment = new myDetailFragment();
                fragment.setArguments(arguments);
            }
        return fragment;

    }
}

人口

     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            ToggleButton addFav = (ToggleButton) rootView.findViewById(R.id.addFavorite);

            .
            .

             if (item_status.equals("0")) {
                addFav.setChecked(false);
                afw.setBackgroundColor(Color.GRAY);
             } else (item_status.equals("1")) {
                addFav.setChecked(true);
                afw.setBackgroundColor(Color.RED);
             }

            .
            .

            addFav.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        final Context ctx = getActivity();
                        ContentValues values = new ContentValues(1);
                        SharedPreferences prefs = getActivity().getSharedPreferences("com.dap.qgit", Context.MODE_PRIVATE);
                        ToggleButton tb = (ToggleButton) v;
                        if (tb.isChecked()) {
                            values.put(DataProvider.COL_ITEM_STATUS, "1");
                        } else {
                            values.put(DataProvider.COL_ITEM_STATUS, "0");
                        }

                        String[] args = new String[1];
                        args[0] = "" + tb.getTag();
                        ctx.getContentResolver().update(DataProvider.CONTENT_URI_ITEM, values, "item_id=?", args);
                        getContext().getContentResolver().notifyChange(DataProvider.CONTENT_URI_TAG_ITEMS,null);

                    }
                });
      }

【问题讨论】:

  • 分享您的代码。适配器和填充部分。
  • @azizbekian 我已经更新了
  • 什么是item_status,它在哪里被初始化?
  • item_status 来自 database/cursor - CursorPagerAdapter 的一部分 - 通过 Argument Bundle 级联到“Population/ItemDetailFragment”

标签: android android-viewpager togglebutton


【解决方案1】:

在将FragmentStatePagerAdapter 实现与Cursor动态 数据集一起使用时,您需要考虑几件事情。

问题

  1. FragmentStatePagerAdapter 来自支持库映射其实例化片段到他们的对应的位置而不是他们的对应ID,
  2. FragmentStatePagerAdapter 默认不支持动态更改数据集,正如您通过始终返回POSITION_UNCHANGEDgetItemPosition(Object object) 的实现所看到的那样

解决方案

  1. 您需要使用FragmentStatePagerAdapter 的实现,它映射其实例化片段到他们的对应的ids来自Cursor并且也是能够通过相应的 id恢复这些片段的状态
  2. 这样的适配器实现还需要根据其关联数据在Cursor 中的位置返回正确的位置片段通过 getItemPosition(Object object) 方法。

现在,您可以从支持库中实现/移植FragmentStatePagerAdapter,因此此类实现提供了通过 id 进行映射和适当的位置解析功能,或者您可以使用一些已经为您提供此类功能的库,例如 this提供第一个功能和第二个功能的库可以由this GitHub Gist简单实现。

【讨论】:

  • 嗨马丁,在我当前的实现中,每个页面的数据都按预期变化 - 只有 CheckBox/ToggleButton 状态被搞砸了 - 假设我有 10 个页面,我不像一个页面,那么只有 9 个页面显示 - 每个页面中的内容都符合预期 - 只有 Checkbox/ToogleButton 的状态不正确 - 即使调用了 getItem 方法并且在 getItem 方法中正确设置了 ToogleButton 的值。
  • 关于您对“...也能够通过其相应的 id 恢复这些片段的状态...”的评论 - 这是否意味着即使我没有恢复 CheckBox/ToggleButton 的状态编写任何明确的“SavedInstanceState”例程
  • 在幕后发生了很多事情,例如FragmentManagerViewPager,以便“正确”管理显示的片段。基本上,像CheckBoxes 这样的所有有状态的小部件都会在适当的时候保存它们的状态。在这种情况下,他们存储的状态与他们对应的Fragment 相关联。现在,假设您在位置 [2]destroy 片段,它的视图状态被保存,为该位置创建一个新片段,并且它的视图状态在同一位置恢复,但该片段已经代表另一个项目,这是不一致
  • PagerAdapter 具有 saveState(...)restoreState(...) 方法,这些方法由附加此类适配器的 ViewPager 调用。 FragmentStatePagerAdapter 实现了这些方法并为其实例化的Fragments 管理保存恢复状态。可以正确恢复片段视图状态的最佳位置是Fragment.onViewStateRestored(...)method,您应该使用片段参数中的数据。但是,如果你使用 Cursor 作为 PagerAdapter 的数据集,你不应该依赖 FragmentStatePagerAdapter 的默认实现。
  • 感谢 Martin - 您对 Android 如何自动尝试保留内置小部件(例如 ToggleButton/CheckBox 等)状态的解释对我很有帮助。我现在在我的布局 xml 中使用了“android:saveEnabled="false" 来暂时规避这个问题 - 这个博客确实帮助了我 - trickyandroid.com/saving-android-view-state-correctly
【解决方案2】:

首先请阅读“Martin Albedinsky”的回复 - 感谢他帮助我隔离问题。

我在布局 XML 中使用以下内容来规避问题:

                 <ToggleButton
                        .
                        .
                        .
                        android:saveEnabled="false"
                        .
                        .
                        .
                  >

虽然我没有亲自尝试过 Martin 的解决方案 - 根据他的解释,这似乎是一种更清洁的方法。

我还不确定这个对我有用的解决方案是否会导致任何性能/不良问题。

【讨论】:

    猜你喜欢
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多