How to create dynamically several times the same layout?

Asked

Viewed 457 times

2

I created a layout called with a "+" button at the end so that I would like, when clicking the button, to be added a new Linearlayout below the current layout with the same content, allowing the registration of more than one item without generating new screens.

I hardly know where to begin...

From what I understand, in the Onclick event of the "+" button, I need to create a new Linearlayout and position below the layout that contains the current button after inflating it with the content of the "address" layout using Inflate. But I can’t encode that. Could someone help me?

My Layout:

    <LinearLayout
    style="@style/Layout_Fragment_Port"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

<LinearLayout
    style="@style/Layout_Fragment_Port"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <EditText
        android:id="@+id/regpet_edt_name"
        style="@style/EditText"
        android:hint="@string/label_name"
        android:inputType="textPersonName" />

    <Spinner
        android:id="@+id/regpet_spn_pettype"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Spinner
        android:id="@+id/regpet_spn_petbreed"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/regpet_lbl_petsize"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:text="@string/label_petsize"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/regpet_txt_petsize"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/regpet_lbl_petsize"
            android:layout_toEndOf="@+id/regpet_lbl_petsize"
            android:layout_toRightOf="@+id/regpet_lbl_petsize" />

        <TextView
            android:id="@+id/regpet_lbl_hairsize"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/regpet_lbl_petsize"
            android:layout_toLeftOf="@+id/regpet_txt_hairsize"
            android:layout_toStartOf="@+id/regpet_txt_hairsize"
            android:text="@string/label_hairsize"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/regpet_txt_hairsize"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true" />

        <ImageButton
            android:id="@+id/regpet_btn_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/regpet_txt_hairsize"
            android:background="@color/colorPetCareLight"
            android:contentDescription="@string/img_content_description"
            android:src="@mipmap/ic_delete"
            android:visibility="invisible" />

        <ImageButton
            android:id="@+id/regpet_btn_newpet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/regpet_txt_hairsize"
            android:background="@color/colorPetCareLight"
            android:contentDescription="@string/img_content_description"
            android:src="@mipmap/ic_new" />

    </RelativeLayout>

</LinearLayout>

<LinearLayout
    android:id="@+id/regpet_frame"
    style="@style/Layout_Fragment_Port"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
</LinearLayout>

</LinearLayout>

The event of the button:

    @Override
public void onClick(View v) {
    LinearLayout newlayout = new LinearLayout(getContext());
    newlayout.setOrientation(LinearLayout.VERTICAL);
    newlayout.setLayoutParams(new ViewGroup.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    ConfigFragment.openFragment(new RegPetFragment(), newlayout.getId(), getFragmentManager(), getString(R.string.title_reg_pet));
    Toast.makeText(getContext(), "clicou no botao", Toast.LENGTH_LONG).show();
}

Contents of Configfragment.openFragment:

    public static void openFragment(Fragment fragment, @IdRes int containerViewId, FragmentManager manager, String tag){
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(containerViewId, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

The error message:

Can't add fragment RegPetFragment{977258d} with tag null to container view with no id
  • You can add the code to your layout?

2 answers

1

I got!!!

    @Override
public void onClick(View v) {
    LinearLayout newlayout = new LinearLayout(getContext());
    newlayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    newlayout.setId(ConfigFragment.generateViewId());
    LinearLayout parentlayout = (LinearLayout) view.findViewById(R.id.regpet_frame_main);
    parentlayout.addView(newlayout);
    ConfigFragment.openFragment(new RegPetFragment(), newlayout.getId(), getChildFragmentManager(), getString(R.string.title_reg_pet));
}

Surely new doubts will arise!

1

Follow a simple example of what I understood :

We have a button to add and a LinearLayout that will receive the EditText for the user to add a new address:

activity_main.xml

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageButton
        android:id="@+id/adicionar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_input_add"
        android:text="" />
    <Button
        android:id="@+id/valores"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_input_add"
        android:text="VALORES" />
</LinearLayout>

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:layout_weight="1">
    <LinearLayout
        android:id="@+id/containerAddress"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    </LinearLayout>
</ScrollView>

Mainactivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    /**
     * Componentes da tela
     */
    private LinearLayout containerAddress;
    private ImageButton adicionar;
    private Button valores;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        adicionar = ImageButton.class.cast(findViewById(R.id.adicionar));
        valores = Button.class.cast(findViewById(R.id.valores));
        containerAddress = LinearLayout.class.cast(findViewById(R.id.containerAddress));


        adiconar.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                addEditText();
            }
        });

        valores.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                getValues();
            }
        });
    }


    /**
     * Adiciona um EditText no containerAddress!
     */
    private void addEditText(){
        //Criamos o EditText
        final EditText editText = new EditText(getApplicationContext());
        //Seta os parametros
        editText.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT ));
        //adiciona no containerAddress
        containerAddress.addView(editText);
    }


    /**
     * Pegamos os valores dos EditText' adicionados na tela
     */
    private void getValues(){
        // Pegamos a quantidade de filhos que o containerAddress tem..
        int total = containerAddress.getChildCount();
        Log.d("MainActivity", "Total de itens: "+total);

        //Vamos iterar os filhos de containerAddress
        for(int pt=0; pt < total; pt++){
            // Pegamos o item
            final View view = containerAddress.getChildAt(pt);
            //Cast para um EditText
            final EditText editText = EditText.class.cast(view);
            //pegamos o valor
            final String addressText = editText.getText().toString();
            Log.w("MainActivity", addressText);
        }
    }
}
  • Man, this code is fantastic... it’s already given me some insight into how this thing works... As I have a slightly more complex layout than some simple Edittexts, it would be possible to do the thing table with a ready layout instead of putting the components individually one by one?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.