【问题标题】:Java.lang.IllegalStateException: The application PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged androidJava.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android
【发布时间】:2017-05-23 17:06:22
【问题描述】:

我正在尝试使用静态类将值传递给视图,而不是使用意图,因为我必须传递大量数据。有时我会收到此错误,但无法找出主要原因

错误:-

java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 101, found: 200

我的寻呼机课程

public class MemeDetailActivity extends AppCompatActivity implements OnDialogClickListner<Void> {
    private ViewPager mPager;
    private List<Datum> mList;
    private ScreenSlidePagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_meme_detail);
        mList = DataResult.getInstance().getData();
        DataResult.getInstance().resetData();
        if (mList != null)
            startPager(selected_position);
        else
            Toast.makeText(this, "Error loading data", Toast.LENGTH_SHORT).show();
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    private void startPager(int position) {
        pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(pagerAdapter);
        pagerAdapter.notifyDataSetChanged();
        mPager.setOffscreenPageLimit(0);
        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                new Interactors(MemeDetailActivity.this).updateView(Util.getAccessToken(), mList.get(position).getId(), new OnFinishListner<ViewsRM>() {
                    @Override
                    public void onFinished(ViewsRM result) {

                    }

                    @Override
                    public void onFailed(String msg) {
                    }
                });
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        mPager.setCurrentItem(position);
    }

    public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

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


        //todo entry point 3 : showing the image in the viewpager
        @Override
        public Fragment getItem(int position) {
            Fragment fragment = new fragment_mypager_new();
            Bundle bundle = new Bundle();
            if (frmMyMemes)
                bundle.putParcelable("MY_DATA", myList);
            bundle.putSerializable("DATA", mList.get(position));
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

        @Override
        public int getCount() {
            return mList.size();
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment fragment = (Fragment) super.instantiateItem(container, position);
            registeredFragments.put(position, fragment);
            return fragment;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            registeredFragments.remove(position);
            super.destroyItem(container, position, object);
        }

        public Fragment getRegisteredFragment(int position) {
            return registeredFragments.get(position);
        }
    }

}

我的静态类

public class DataResult<T> {

    private static DataResult instance;
    private List<T> data = null;

    protected DataResult() {

    }

    public static synchronized DataResult getInstance() {
        if (instance == null) {
            instance = new DataResult();
        }
        return instance;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public void resetData() {
        data = null;
    }
}

我如何称呼活动

    Intent intent = new Intent(getActivity(), MemeDetailActivity.class);
    DataResult.getInstance().setData(mListA);

【问题讨论】:

  • mListA 中的数据在调用DataResult.getInstance().setData(mListA); 之后是否曾经修改(添加到)?
  • David Wasser 的评论指出了正确的解决方案 - 您不应该使用静态字段在 Activity/Fragment 之间进行通信。像你应该做的那样使用意图、内容提供者等。然后,您可以稍后根据需要进行优化。如果您在静态类中有此列表,并且在适配器中设置它之后正在对其进行修改,则它准确地解释了您遇到的错误。否则,请按照此问题中的步骤操作:stackoverflow.com/questions/22943658/…

标签: java android android-intent static singleton


【解决方案1】:

看看你的代码:

 @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

此代码用于在视图更改时刷新视图。也叫notifyDataSetChanged()

它的可选 ovverride 方法,因此您可以将其删除。

看看这个答案:ViewPager PagerAdapter not updating the View

否则您可以将FragmentStatePagerAdapter 更改为FragmentPagerAdapter

【讨论】:

  • 对我不起作用。它仍然崩溃。我发现的问题是,每当我从 api 获取数据时,我将其添加到列表中,如果同时用户单击一个项目,那么我将传递列表的所有数据。因此,如果当前列表中有 100 个数据并且用户单击一个项目,同时列表更新了 99 个数据,那么数据总数就会发生冲突。它与我在问题中提供的代码相同。您能否建议我如何解决此问题。
  • 你应该先将mList存储到适配器,然后调用notifydatasetchange();我找不到您将 mList 存储到适配器的任何地方。
  • 你的问题是这一行.. pagerAdapter.notifyDataSetChanged();,
  • 所以你的意思是我必须删除 pagerAdapter.notifyDataSetChanged() 代码?
  • 我已将数据设置为适配器,但未提供问题中的代码。 mAdaptor = new DetailViewAdaptor(this.mList, this); mRecyclerView.setAdapter(mAdaptor);
【解决方案2】:

有时会发生此错误。

这是我的建议:

在你的DataResult->getData()

返回数据的副本。

DataResult 是一个单例并保存数据。当您的视图获取数据时,视图将获取 DataResult 持有的数据引用。然后setData() 将更改data 引用。来了 IllegalStateException。

希望它会起作用:)

【讨论】:

    【解决方案3】:

    我认为你的DataResult 类是没有必要的。

    根据您的评论,您在更新数据集时遇到了错误。我认为您正在从某个 REST API 或其他 Web 服务获取数据。然后将您从 API 获取的数据分配给一个临时数组列表,并在您获取新数据时更新该临时数组列表。在完成接收数据之前,请勿触摸 mListA 变量。从API获取数据完成后,将你使用的临时数组列表直接赋值给mListA。

    mListA = tmpList;
    

    然后再次调用

    mList = mListA;
    pagerAdapter.notifyDataSetChanged();
    

    这应该可以解决您的错误。

    【讨论】:

      【解决方案4】:

      尝试使用以下方式:

      mList=new ArrayList<Datum>();
              mList.addAll(DataResult.getInstance().getData());
              DataResult.getInstance().resetData();
      

      【讨论】:

        【解决方案5】:

        这可能是因为您首先在方法initUI() 中使用setAdapter() 和notifyDataSetChanged;

        然后,在方法@​​987654325@ 中实例化List&lt;?&gt; 数据,这两个方法在片段的不同生命周期中。

        是fragment生命周期的问题

        【讨论】:

          【解决方案6】:
          @Override
          public void restoreState(Parcelable state, ClassLoader loader) {}
          @Override
          public Parcelable saveState() {return null;}
          #Add in your adapter after getCount();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-26
            相关资源
            最近更新 更多