Search code examples
javaandroid-studioandroid-fragmentsandroid-edittextparent-child

Android studio app crashes on the button click


I am working on android studio. I have created some fragments and they are smoothly working. The app would be collecting data from users for order booking. Now, I have a button and on this button click, I am calling another layout to enter the products. The data is selected from the json file. Below is my code

Fragment

Button addProduct;
private LinearLayout mLinearLayout;
public View layout2;
public View view = null;

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

   if (view == null) {
        view = inflater.inflate(R.layout.new_survey_form_layout, container, false); // my main layout
        mLinearLayout = view.findViewById(R.id.ll_prod);// the layout in which I want to call my below layout
        layout2 = inflater.inflate(R.layout.product_layout, mLinearLayout, false);// product layout


        this.initElements(view);// all of my fields against my new_survey_layout_form_layout
        this.initElementsPrd(layout2); // the fields of my second layout
    }
}

 private void initElementsPrd(View view) {
    productAuto = (AutoCompleteTextView) view.findViewById(R.id.tv_product);
    qtyEditText = (EditText) view.findViewById(R.id.prod_qty);
    prodPriceEditText = (EditText)view.findViewById(R.id.prod_price);
    prodSpecsEditText = (EditText)view.findViewById(R.id.prod_specs);
    setProd();// to set the adapters for selecting the product name
}
 private void setProd()
{
    Log.d("Ali", "sub div");
    if (prodArrayList == null) {
        prodArrayList = new ArrayList<String>();
        Log.d("Ali", "prod new");
    } else {
        prodArrayList.clear();
        Log.d("Ali", "prod clear");
    }

    if (isNewSurvey) {
        prodArrayList.addAll(new ProductManager(getActivity()).getAvailableProducts());
        Log.d("Ali", "prod is new booking");
    } else {
        prodArrayList.addAll(new ProductManager(getActivity()).getProducts());
        Log.d("Ali", "sub div edit survey");
    }
    if (prodAdapter == null) {
        Log.d("Ali", "sub div new adapter");
        prodAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, prodArrayList);
        productAuto.setAdapter(prodAdapter);
    } else {
        Log.d("Ali", "sub div notify");
        prodAdapter.notifyDataSetChanged();
    }
}

        addProduct.setOnClickListener(v -> {


        addLayout();

    });

Now when I click the add button for the first time it does show the layout of the product but when I click on the same button for the second time the app crashes. Below is the working

enter image description here

Error Message

The specified child already has a parent. You must call removeView() on the child's parent first.

Solution Tried

Inside add layout function I have done the following

 private void addLayout(){
    layout2 = LayoutInflater.from(mContext).inflate(R.layout.product_layout, mLinearLayout, false);
    productAuto = (AutoCompleteTextView) view.findViewById(R.id.tv_product);
    qtyEditText = (EditText) view.findViewById(R.id.prod_qty);
    prodPriceEditText = (EditText)view.findViewById(R.id.prod_price);
    prodSpecsEditText = (EditText)view.findViewById(R.id.prod_specs);

 }

The product form is shown every time when I click on the Add new Product button. But I can't select a product in this case.

Update 1

I have taken addProduct button in this.initElements(view);

private void initElements(View view) {

    newSurveyScrollview = (ScrollView) view.findViewById(R.id.new_survey_scrollview);
 refNofield1 = (EditText) view.findViewById(R.id.ref_no_field_1);
    consumerNameEditText = (EditText) view.findViewById(R.id.consumer_name);
    consumerAddressEditText = (EditText) view.findViewById(R.id.consumer_address);
    latitudeEditText = (EditText) view.findViewById(R.id.latitude);
    longitudeEditText = (EditText) view.findViewById(R.id.longitude);
    placeEditText = (EditText) view.findViewById(R.id.place);
    subDivisionSpinner = (Spinner) view.findViewById(R.id.sub_division_spinner);
cameraButton = (Button) view.findViewById(R.id.open_camera);
    saveButton = (Button) view.findViewById(R.id.save_survey_form);
    resetButton = (Button) view.findViewById(R.id.survey_reset);
    getRefNoButton = (Button) view.findViewById(R.id.get_ref_no_button);
    getLatLangButton = (ImageButton) view.findViewById(R.id.get_lat_lang_button);
    addProduct = (Button)view.findViewById(R.id.btn_prd);

}

Error Log

Process: com.example.thumbsol.accuratesurvey, PID: 6854
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    at android.view.ViewGroup.addViewInner(ViewGroup.java:5038)
    at android.view.ViewGroup.addView(ViewGroup.java:4869)
    at android.view.ViewGroup.addView(ViewGroup.java:4809)
    at android.view.ViewGroup.addView(ViewGroup.java:4782)
    at com.example.thumbsol.accuratesurvey.fragments.SurveyFormFragment.addLayout(SurveyFormFragment.java:1904)
    at com.example.thumbsol.accuratesurvey.fragments.SurveyFormFragment.lambda$initListeners$1$com-example-thumbsol-accuratesurvey-fragments-SurveyFormFragment(SurveyFormFragment.java:550)
    at com.example.thumbsol.accuratesurvey.fragments.SurveyFormFragment$$ExternalSyntheticLambda3.onClick(Unknown Source:2)
    at android.view.View.performClick(View.java:6608)
    at android.view.View.performClickInternal(View.java:6585)
    at android.view.View.access$3100(View.java:785)
    at android.view.View$PerformClick.run(View.java:25921)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:201)
    at android.app.ActivityThread.main(ActivityThread.java:6810)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

The error comes at below part

 private void addLayout() {

    mLinearLayout.addView(layout2);
}

Update 2

I have removed the second layout part from onCreatView and done the following

private void addLayout() {
   layout2 = LayoutInflater.from(mContext).inflate(R.layout.product_layout, mLinearLayout, false);
    this.initElementsPrd(layout2);
    mLinearLayout.addView(layout2);
}

Below is what I am getting now

enter image description here

The autocomplete is working for the 1st one but for the second or 3rd upto N its not working.

Any help would be highly appreciated.


Solution

  • Following the Gowtham K K answer I have done the following changes in my code

    private void addLayout() {
        layout2 = LayoutInflater.from(mContext).inflate(R.layout.product_layout, mLinearLayout, false);
        productAuto = (AutoCompleteTextView) layout2.findViewById(R.id.tv_product);
        qtyEditText = (EditText) layout2.findViewById(R.id.prod_qty);
        prodPriceEditText = (EditText)layout2.findViewById(R.id.prod_price);
        prodSpecsEditText = (EditText)layout2.findViewById(R.id.prod_specs);
        removeProduct = (Button)layout2.findViewById(R.id.btn_rmv);
       
        setProd();
        
    }
    

    Then in my setProd() function

     prodArrayList = new ArrayList<String>();
        if (isNewSurvey) {
            prodArrayList.addAll(new ProductManager(getActivity()).getAvailableProducts());
            Log.d("Ali", "prod is new booking");
        } else {
            prodArrayList.addAll(new ProductManager(getActivity()).getProducts());
            Log.d("Ali", "sub div edit survey");
        }
        prodAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, prodArrayList);
        productAuto.setAdapter(prodAdapter);
    

    Implementing the above solution my program is working now