Pablo R.
Pablo R.

Reputation: 723

Add multiple TextView to View dinamically

I need to add indeterminate number of textview to a view, and I would love if it can be auto adjust to the screen.

What I tried is to add horizontal LinearLayouts to a vertical parent LinearLayout, but this way I can add maybe 2 items or 3 per line but it doesn't have this unordered effect.

Is there any way to achieve this?

enter image description here

Upvotes: 1

Views: 1221

Answers (2)

MDG
MDG

Reputation: 91

If you want to use LinearLayouts, you can go into your xml and add only a Vertical LinearLayout.

After this, you can add Horizontal LinearLayouts for your rows, to which you'll add cells, TextViews in your case.

In the "OnCreate" I'm only getting the Views and calling the methods used to add rows and cells to specified row.

public class MainActivity extends AppCompatActivity {

/**
 * @verticalLayout
 * Contains the rows of your String matrix
 */

LinearLayout verticalLayout;

/**
 * @rowCellDivisor
 * Contains the horizontal layout of each row
 */

LinkedList<LinearLayout> rows;


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

    verticalLayout = findViewById(R.id.verticalLayout);

    addRow();
    addRow();
    addRow();
    addRow();

    addTextViewToRow(0);
    addTextViewToRow(0);
    addTextViewToRow(0);
    addTextViewToRow(1);
    addTextViewToRow(1);
    addTextViewToRow(2);
    addTextViewToRow(2);
    addTextViewToRow(2);
    addTextViewToRow(2);
    addTextViewToRow(2);

}

There we create a row, which is nothing more than a LinearLayout with Horizontal orientation.

private void addRow(){

    LinearLayout row
            = new LinearLayout(
                    getApplicationContext()
    );

    row.setOrientation(LinearLayout.HORIZONTAL);
    row.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);

    verticalLayout.addView(row);

}

This creates the TextView to add in the specified row.

private void addTextViewToRow(int rowAtPosition){

    TextView textView = new TextView(getApplicationContext());
    textView.setText("StartLongTextaaaaaaaaaaaaaaaaaaaaaaaa" +
            "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +
            "ccccccccccccccccccccccccccccccLongTextEnd");

     /**
     * Third entry for params is for weight, so that you can
     * decide how much space the cell will occupy in the row
     * when there will be more than one view in the same row.
     */

    LinearLayout.LayoutParams layoutParams
            = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT,
            1f
    );

    /**
     * setMargins e.g. between cells of the row and screen
     * borders
     */

    layoutParams.setMargins(25, 0, 25, 25);

    textView.setLayoutParams(
            layoutParams
    );

    LinearLayout view = (LinearLayout) 
    verticalLayout.getChildAt(rowAtPosition);
    view.addView(textView);

}

}

Upvotes: 0

Dak28
Dak28

Reputation: 259

What i suggest is to not create dynamically a horizontal layout (if you are doing that).

instead you can create a horizontal layout resource like this:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:weightSum="2">

    <TextView
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="start"
        android:layout_weight="1"
        android:text="ONE" />

    <TextView
        android:id="@+id/end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="end"
        android:text="TWO" />
</LinearLayout>

And then in your main activity do like this:

 for(i in 0..2) {
        val view: View?
        val inflater =
            this.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        view = inflater.inflate(R.layout.horizontal, null)

        val textOne = view.findViewById<TextView>(R.id.start)
        textOne.text = "TEST $i"

        val textTwo = view.findViewById<TextView>(R.id.start)
        textTwo.text = "TEST $i"

        (mainL as LinearLayout).addView(view)
    }

Where mainL is main vertical layout, to which you can add padding, or you can modify your horizontal one, it depends on what you want to achive.

In this example i used a for loop just to show you that 3 lines are created, in every cicle if you have a list of text to put in you could use this syntax for loop

for ((index, value) in names.withIndex()) {
    println("$index: $value")
}

reference: https://kotlinlang.org/docs/tutorials/kotlin-for-py/loops.html

For your specific case i suggest to have the main layout with padding start and end, and in horizontal layout margin top and bottom to create space between elements.

Upvotes: 1

Related Questions