Remove View Containing an AlertDialog java.lang.IllegalStateException: You must call removeView() on the child's parent first

Android logcat:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
W/System.err:     at android.view.ViewGroup.addViewInner(ViewGroup.java:4168)
W/System.err:     at android.view.ViewGroup.addView(ViewGroup.java:4018)
W/System.err:     at com.android.internal.app.AlertController.setupTitle(AlertController.java:547)
W/System.err:     at com.android.internal.app.AlertController.setupView(AlertController.java:474)
W/System.err:     at com.android.internal.app.AlertController.installContent(AlertController.java:240)
W/System.err:     at android.app.AlertDialog.onCreate(AlertDialog.java:356)
W/System.err:     at android.app.Dialog.dispatchOnCreate(Dialog.java:373)
W/System.err:     at android.app.Dialog.show(Dialog.java:274)
W/System.err:     at SingleView.showDialog(MyActivity.java:201)
W/System.err:     at MyActivity$4.onItemClick(MyActivity.java:354)
W/System.err:     at MyAdapter$MyViewHolder.onClick(MyAdapter.java:47)
W/System.err:     at android.view.View.performClick(View.java:5076)
W/System.err:     at android.view.View$PerformClick.run(View.java:20279)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err:     at android.os.Looper.loop(Looper.java:135)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5910)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

In MyActivity line 201 is:

alert.show();

Line 354 is

showDialog();

In MyAdapter line 47 is:

mOnMyItemClickListener.onItemClick(v, getAdapterPosition());

This is MyAdapter class:

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter .MyViewHolder>{
        public interface OnMyItemClickListener{
            void onItemClick(View v, int position);
        }

        private OnMyItemClickListener mOnMyItemClickListener;

        private List<String> customTitles;
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.amenities_card, parent, false);
            return new MyViewHolder(itemView);
        }
        public MyAdapter( List<String> customTitles, OnMyItemClickListener OnMyItemClickListener) {//Context context,
            //this.mContext = context;
            this.placeTitles = customTitles;
            mOnMyItemClickListener = OnMyItemClickListener;
        }
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.textName.setText(customTitles.get(position));
        }
        @Override
        public int getItemCount() {
            return customTitles.size();
        }
        public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
            public TextView textName;
            public MyViewHolder(final View view) {
                super(view);
                placeName = (TextView) view.findViewById(R.id.customTitle);
                view.setOnClickListener(this);
            }
            @Override
            public void onClick(View v) {
                mOnMyItemClickListener.onItemClick(v, getAdapterPosition());
            }
        }
    }
In MyActivity, this is the adapter's onClickListener:

    MyAdapter        aAdapter = new AmenitiesAdapter(customTitles, new MyAdapter.OnMyItemClickListener(){
                @Override
                public void onItemClick(View v, int position) {
                    //your code goes here
                    final TextView textName = (TextView) v.findViewById(R.id.customTitle);
                    String text1= textName.getText().toString();
                    String[] mText1= v.getRootView().getContext().getResources().getStringArray(R.array.text_1);
                    String type = mText1[position];
                    //Toast.makeText(MyActivity.this, text1, Toast.LENGTH_LONG).show();
                    //Toast.makeText(MyActivity.this, "At position"+position, Toast.LENGTH_LONG).show();
                    try {
                        //
                    }
                    catch(NullPointerException e){
                        e.printStackTrace();
                    }
                    try {
                        showDialog();
                    }
                    catch (IllegalStateException e){
                        e.printStackTrace();
                    }
                }
            });

This is the method to show the dialog:

public void showDialog(){
    title.setText(R.string.title_text);
    // title.setBackgroundColor(Color.DKGRAY);
    title.setPadding(10, 10, 10, 10);
    title.setGravity(Gravity.CENTER);
    title.setTextColor(Color.WHITE);
    title.setTextSize(18);
    final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.DialogStyle);
    builder.setCustomTitle(title)
            .setCancelable(true)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                   // dialog.dismiss();
                    Toast.makeText(SingleView.this,"my text",Toast.LENGTH_LONG).show();
                }
            })
            .setNegativeButton("NOTHING", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });
    alert = builder.create();
    alert.show();
}

This is the onBackPressed method:

@Override
    public void onBackPressed(){
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer != null && slidingDrawer!=null){
            if (drawer.isDrawerOpen(GravityCompat.START)) {
                drawer.closeDrawer(GravityCompat.START);
            }
            else if (slidingDrawer.isOpened()) {
                slidingDrawer.close();
            }
            else {
                if(i.getStringExtra("prev_activity").equals("Main")){
                    Intent intent = new Intent(MyActivity.this, MainActivity.class);
                    startActivity(intent);
                }
                if(alert.isShowing()){alert.hide();alert.cancel();alert.dismiss();}
                super.onBackPressed();
            }
        }
    }

This is the situation: My recycler view is in a sliding drawer. When I click an item in the recyclerview, a alert dialog shows, if I dismiss the popup by pressing the back button, and click on the recyclerview item, the alert dialog does not show and the app crashes and gives the IllegalState exception. Please help.

Could I please ask how you then destroy the Dialog if dismissing it is insufficient? I tried removing all child elements because I thought it was the only child element using

((ViewGroup) linearlayout.getParent()).removeAllViews(); 

but when I checked using

((ViewGroup) linearlayout.getParent()).removeViews(0, ll.getChildCount());

I found that there were 9 child views, whether the alert dialog was displaying or not. How do I destroy the Alert Dialog completely?

I also tried:

((ViewGroup) ll.getParent()).removeView(alert.getWindow().getDecorView()); ((ViewGroup) ll.getParent()).removeView(alert.getWindow().peekDecorView());

but the exception is still throwing.

Upvotes: 0

Views: 330

Answers (0)

Related Questions