数据更新后ViewPager中的java.lang.IllegalStateException [英] java.lang.IllegalStateException in the ViewPager after data update

查看:139
本文介绍了数据更新后ViewPager中的java.lang.IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将数据动态添加到viewPager时出现异常

I get an exception when dinamically add data to the viewPager

02-07 19:21:24.488 5577-5577/com.jamesb.encoderyapp E/AndroidRuntime:致命异常:main 流程:com.jamesb.encoderyapp,PID:5577 java.lang.IllegalStateException:应用程序的PagerAdapter更改了适配器的内容,而没有调用PagerAdapter#notifyDataSetChanged!预期的适配器项数:4,找到的:8寻呼机ID:com.jamesb.encoderyapp:id/pager寻呼机类:类android.support.v4.view.ViewPager有问题的适配器:com.jamesb.encoderyapp.adapters.ViewPagerAdapter类 在android.support.v4.view.ViewPager.populate(ViewPager.java:1000) 在android.support.v4.view.ViewPager.populate(ViewPager.java:952) 在android.support.v4.view.ViewPager $ 3.run(ViewPager.java:251) 在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:767) 在android.view.Choreographer.doCallbacks(Choreographer.java:580) 在android.view.Choreographer.doFrame(Choreographer.java:549) 在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:753) 在android.os.Handler.handleCallback(Handler.java:739) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:135) 在android.app.ActivityThread.main(ActivityThread.java:5254) 在java.lang.reflect.Method.invoke(本机方法) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:903) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

02-07 19:21:24.488 5577-5577/com.jamesb.encoderyapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.jamesb.encoderyapp, PID: 5577 java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 4, found: 8 Pager id: com.jamesb.encoderyapp:id/pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.jamesb.encoderyapp.adapters.ViewPagerAdapter at android.support.v4.view.ViewPager.populate(ViewPager.java:1000) at android.support.v4.view.ViewPager.populate(ViewPager.java:952) at android.support.v4.view.ViewPager$3.run(ViewPager.java:251) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:549) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

我从API-3张图片中获取数据,当这张图片滑动时,我再次调用getContent()方法,此刻我得到了IllegalStateException.

I get data from API - 3 pictures,when this pictures swiped, I call getContent() method again and in this moment i get IllegalStateException .

 try {
        RestClient.getInstance(getActivity()).getContent(date, new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Response response) throws IOException {
                String json = response.body().string();

                GsonBuilder gsonBuilder = new GsonBuilder();
                mGson = gsonBuilder.create();
                jsonParsed = mGson.fromJson(json, JsonParsed.class);
                if (jsonParsed != null) mApodData.add(jsonParsed);
                if (count < iteration) {
                    count++;
                    getContent();
                } else {
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {

                                mAdapter = new ViewPagerAdapter(getActivity(), mApodData);
                                mViewPager.setAdapter(mAdapter);
                                mAdapter.notifyDataSetChanged();
                        }
                    });
                }
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }

查看寻呼机适配器

public class ViewPagerAdapter extends PagerAdapter {

private Activity mActivity;
private ArrayList<JsonParsed> mApodData = new ArrayList<>();
private Utils mUtils;

public ViewPagerAdapter(Activity activity, ArrayList<JsonParsed> mApodData) {
    this.mActivity = activity;
    this.mApodData = mApodData;
    mUtils = new Utils();
}

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

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

@Override
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

@Override
public View instantiateItem(final ViewGroup container, final int position) {

    LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View itemView = inflater.inflate(R.layout.item, container, false);
    final ViewHolder viewHolder = new ViewHolder();
    viewHolder.mPic = (ImageView) itemView.findViewById(R.id.picture);
    viewHolder.mPicTitle = (TextView) itemView.findViewById(R.id.picTitle);
    viewHolder.mDescription = (TextView) itemView.findViewById(R.id.description);
    itemView.setTag(viewHolder);

    JsonParsed item = mApodData.get(position);
    String descr = item.explanation;
    String title = item.title;
    String picUrl = item.hdurl;
    viewHolder.mPicTitle.setText(title);
    viewHolder.mDescription.setText(descr);

    Picasso.with(mActivity)
            .load(String.valueOf(picUrl))
            .into(viewHolder.mPic);

    viewHolder.mPic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mUtils.setImageAsWallpaper(mActivity, viewHolder.mPic);
        }
    });
    container.addView(itemView);
    return itemView;
}

@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
    ((ViewPager) collection).removeView((View) view);

}

static class ViewHolder {
    ImageView mPic;
    TextView mPicTitle;
    TextView mDescription;
}

}

我在Google中看到过类似的问题,但是我不明白我在哪里没有使用notifyDataSetChanged(),这会引发异常.

I've seen similar questions in google ,but I don't understand where I did not use notifyDataSetChanged() and this throws exception.

推荐答案

您的适配器似乎正在与活动/片段共享列表引用.这是什么意思:当此行执行时

It looks like your adapter is sharing the list reference with your activity/fragment. What this means is: when this line executes

                if (jsonParsed != null) mApodData.add(jsonParsed);

适配器中的列表被立即更新,因为它本质上是相同的列表.

the list in the adapter is updated immediately since it is essentially the same list.

ViewPager在执行其操作时,它一次又一次引用适配器.因此,它会检查getCount()和适配器是否未更改以保持内部一致性.

While the ViewPager is doing its thing, it references the adapter again and again. So it checks that getCount() and the adapter haven't changed in order to stay internally consistent.

解决此问题的最佳方法?如果您知道最终会有多少页,请让您的getCount()方法返回该数字.您可以做的另一件事是让适配器创建自己的列表,并在活动中的列表上执行mList.addAll().您还可以在从服务器检索数据时将ViewPager适配器设置为null.

The best way to fix this? if you know how many pages you will end up with, have your getCount() method return that number. Another thing you can do is have the adapter create its own list and do a mList.addAll() on the list from the activity. You could also set the ViewPager adapter to null while retrieving the data from the server.

这篇关于数据更新后ViewPager中的java.lang.IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆