简体   繁体   中英

java.lang.IllegalStateException while using ViewPager in Android

I have a ViewPager which is a part of a popup window. When I open a popup window for the first time, everything works well, but when I open it for the second time with the same data, I have a IllegalStateException error.

Here is a stack trace:

04-08 15:17:48.370: E/AndroidRuntime(10929): FATAL EXCEPTION: main 04-08 15:17:48.370: E/AndroidRuntime(10929): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.addViewInner(ViewGroup.java:3337) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.addView(ViewGroup.java:3208) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.support.v4.view.ViewPager.addView(ViewPager.java:920) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.addView(ViewGroup.java:3165) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.addView(ViewGroup.java:3145) 04-08 15:17:48.370: E/AndroidRuntime(10929): at com.componentix.imwizard.SamplePagerAdapter.instantiateItem(SamplePagerAdapter.java:22) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:649) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.support.v4.view.ViewPager.populate(ViewPager.java:783) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1280) 04-08 1 5:17:48.370: E/AndroidRuntime(10929): at android.support.v4.view.ViewPager.computeScroll(ViewPager.java:1176) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.drawChild(ViewGroup.java:2729) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.View.buildDrawingCache(View.java:10693) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.drawChild(ViewGroup.java:2747) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.View.draw(View.java:10981) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.View.getDisplayList(View.java:10417) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.View.getDispl ayList(View.java:10380) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:842) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewRootImpl.draw(ViewRootImpl.java:1910) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.os.Handler.dispatchMessage(Handler.java:99) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.os.Looper.loop(Looper.java:137) 04-08 15:17:48.370: E/AndroidRuntime(10929): at android.app.ActivityThread.main(ActivityThread.java:4430) 04-08 15:17:48.370: E/AndroidRuntime(10929): at java.lang.reflect.Method.invokeNative(Native Method) 04-08 15:17:48.370: E/AndroidRuntime(10929): at java.lang.reflect.Method.invoke(Method.java:511) 04-08 15:17:48.370: E/AndroidRun time(10929): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792) 04-08 15:17:48.370: E/AndroidRuntime(10929): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559) 04-08 15:17:48.370: E/AndroidRuntime(10929): at dalvik.system.NativeStart.main(Native Method)

Here is my code:

public void showPopupWindow(Drawable picture)
{
    int imageResource = R.drawable.background;
    Drawable image = getResources().getDrawable(imageResource);
    popupLayout = new LinearLayout(context);
    popupLayout.setOrientation(LinearLayout.VERTICAL);
    popupLayout.setBackgroundResource(R.drawable.background);
    LayoutInflater ltInflater = getLayoutInflater();
    RelativeLayout rl = (RelativeLayout)ltInflater.inflate(R.layout.viewpager_layout, null);
    PagerContainer pagerContainer = (PagerContainer)(rl.getChildAt(0));
    CirclePageIndicator circlePageIndicator = (CirclePageIndicator)(rl.getChildAt(1));
    Button button = (Button)(rl.getChildAt(2));

    int maxWidth = 1;
    int maxHeight = 1;
    for (Drawable drawable: bigImages) {
        Bitmap bmp = drawableToBitmap(drawable);
        maxWidth = Math.max(maxWidth, bmp.getWidth());
        maxHeight = Math.max(maxHeight, bmp.getHeight());
    }

    ViewPager viewPager = pagerContainer.getViewPager();
    //viewPager.setBackgroundDrawable(image);

    ArrayList<ImageView> tmpImageViewsWithScreenshots = (ArrayList<ImageView>) imageViewsWithScreenshots.clone();
    SamplePagerAdapter pagerAdapter = new SamplePagerAdapter(tmpImageViewsWithScreenshots);
    viewPager.setAdapter(pagerAdapter);
    viewPager.setCurrentItem(imageIndex);
    circlePageIndicator.setViewPager(viewPager);
    circlePageIndicator.setCurrentItem(imageIndex);

    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            int childCount = checkboxLayout.getChildCount();
            for (int i = 0; i < childCount; ++i) {
                RelativeLayout currentLayout = (RelativeLayout) checkboxLayout
                        .getChildAt(i);
                int innerChildCount = currentLayout
                        .getChildCount();
                for (int j = 0; j < innerChildCount; ++j) {
                    View view = currentLayout.getChildAt(j);
                    view.setEnabled(true);
                }
            }
            imageViewLayout.setEnabled(true);
            lockableScrollView.setmScrollable(true);
            back.setEnabled(true);
            next.setEnabled(true);
            popupWindow.dismiss();
        }
    });
    popupLayout.addView(rl);
    LinearLayout.LayoutParams nlp= new LinearLayout.LayoutParams(450, 600);
    rl.setLayoutParams(nlp);
    popupWindow = new PopupWindow(popupLayout,
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);
    int childCount = checkboxLayout.getChildCount();
    for (int i = 0; i < childCount; ++i) {
        RelativeLayout currentLayout = (RelativeLayout) checkboxLayout
                .getChildAt(i);
        int innerChildCount = currentLayout.getChildCount();
        for (int j = 0; j < innerChildCount; ++j) {
            View view = currentLayout.getChildAt(j);
            view.setEnabled(false);
        }
    }
    next.setEnabled(false);
    back.setEnabled(false);
    imageViewLayout.setEnabled(false);
    lockableScrollView.setmScrollable(false);
    popupWindow
            .showAtLocation(mainLayout, Gravity.CENTER, 0, 0);
    }

And here is code of my adapter:

public class SamplePagerAdapter extends PagerAdapter{

    List<ImageView> pages = null;

    public SamplePagerAdapter(List<ImageView> pages){
        this.pages = pages;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position){
        View v = pages.get(position);
        //((ViewPager) collection).addView(v, 0);
        container.addView(v);
        return v;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object){
        container.removeView((View)object);
    }

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

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

}

Any ideas?

The problem is that in your adapters method instantiateItem
you call container.addView(v);

but every View can have only one parent,
so it can be added only one time to a container via addView(...) .

When you open the popup the first time, everything works, because v
doesn't have a parent that time. But when you open your popupwinow the second time,
it adds the view again to the container. That cerates the error.

Try to destroy the view if you close the popup view or remove all children views from it with
container.removeAllViews()

it should work then.

The problem is when you add View v in container.addView(v) for second time.

I've found the solution adding this:

        if(v.getParent()!=null)
        ((ViewGroup)v.getParent()).removeView(v);

before container.addView(v)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM