23

How to create a list of buttons one by one in several lines? I made this:

LinearLayout layout = (LinearLayout) findViewById(R.id.linear_layout_tags);
    for (int i = 1; i < 10; i++) {
        Button btnTag = new Button(this);
        btnTag.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        btnTag.setText("Button " + i);
        btnTag.setId(i);
        layout.addView(btnTag);
        ((Button) findViewById(i)).setOnClickListener(this);
    }

and got only one line:

I got this
How to go to the next line programmatically?

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Sviatoslav
  • 1,301
  • 2
  • 17
  • 42
  • 1
    My first idea was to change getView() in custom SimpleCursorAdapter for ListView, but may be it is more simple to put buttons programmatically. So, I ask here. May be somebody decided this question. – Sviatoslav Aug 25 '11 at 18:22
  • I can answer this for you but the question is closed :/ – b_yng Aug 25 '11 at 22:46
  • Too bad android doesn't support this out of the box. I think having something like *CSS inline-block* would be very useful in android. – Saeed Neamati Sep 03 '15 at 07:35

5 Answers5

43

The issue is that your buttons are not going to automatically wrap to the next part of the screen. You have to specifically tell Android how you want your Views to be positioned. You do this using ViewGroups such as LinearLayout or RelativeLayout.

LinearLayout layout = (LinearLayout) findViewById(R.id.linear_layout_tags);
layout.setOrientation(LinearLayout.VERTICAL);  //Can also be done in xml by android:orientation="vertical"

        for (int i = 0; i < 3; i++) {
        LinearLayout row = new LinearLayout(this);
        row.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

        for (int j = 0; j < 4; j++) {
            Button btnTag = new Button(this);
            btnTag.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            btnTag.setText("Button " + (j + 1 + (i * 4)));
            btnTag.setId(j + 1 + (i * 4));
            row.addView(btnTag);
        }

        layout.addView(row);
    }

I'm assuming that R.id.linear_layout_tags is the parent LinearLayout of your XML for this activity.

Basically what you're doing here is you're creating a LinearLayout that will be a row to hold your four buttons. Then the buttons are added and are each assigned a number incrementally as their id. Once all of the buttons are added, the row is added to your activity's layout. Then it repeats. This is just some pseudo code but it will probably work.

Oh and next time be sure to spend more time on your question...

https://stackoverflow.com/questions/how-to-ask

IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
b_yng
  • 14,136
  • 6
  • 32
  • 35
  • 1
    This code is good when we know that 3 buttons always placed in a row. But what to do when the text in the button is taken from `Cursor` (from database)? The width of the button can be so, that only two buttons will fit in a row. So third button must go in the next row. And how can I delete some of the buttons when Click on it. May be I must change `getView()` in the custom `SimpleCursorAdapter` for this. I want smth like this: [link](http://min.us/mrqgNnw5P) – Sviatoslav Aug 26 '11 at 07:02
  • Thanks for the example ! I would recommand to change LayoutParams.FILL_PARENT by LayoutParams.MATCH_PARENT – Dax Feb 14 '15 at 08:24
8

This is like 1 answer, but without the need to make a XML file.

public class mainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);  //Can also be done in xml by android:orientation="vertical"

        for (int i = 0; i < 3; i++) {
            LinearLayout row = new LinearLayout(this);
            row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

            for (int j = 0; j < 4; j++) {
                Button btnTag = new Button(this);
                btnTag.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                btnTag.setText("Button " + (j + 1 + (i * 4 )));
                btnTag.setId(j + 1 + (i * 4));
                row.addView(btnTag);
            }

            layout.addView(row);
        }
        setContentView(layout);
        //setContentView(R.layout.main);
    }
} 
Voidcode
  • 1,229
  • 1
  • 18
  • 22
2

This will help

private void addingParticipantinFrame() {
        TableRow row;
        final int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp);
        add_button_particiapants.setVisibility(View.VISIBLE);
        if (arrrItemSelcted != null && arrrItemSelcted.size() > 0) {

            arrrItemSelcted.remove(0);
            int i = 0;
            int j = 0;
            int width = (screenWidth - (arrrItemSelcted.size())*4)/arrrItemSelcted.size();

            while (i<arrrItemSelcted.size()) {
                j = i + 4;
                row = new TableRow(mParentActivity);
                TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
                row.setLayoutParams(lp);
                row.setWeightSum(4);
                while ((i<j)&&(i<arrrItemSelcted.size())) {
                    Button iBtn = new Button(mParentActivity);
                    iBtn.setGravity(Gravity.CENTER_HORIZONTAL);
                    iBtn.setMinimumWidth(100);//I set 100px for minimunWidth.
                    iBtn.setWidth(width);
                    iBtn.setText(Integer.toString(i + 1));
                    iBtn.setId(i + 1);
                    row.addView(iBtn, 4 + i - j);
                    i++;
                }
                add_button_particiapants.addView(row);
            }



            }
        }
Srishti Roy
  • 576
  • 5
  • 17
2

The best way is to use a FlexboxLayout provide by google.

implementation 'com.google.android:flexbox:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

Then you have to follow several steps.

1) Add a recycler view, it is the best way to map your data with flexbox layout

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="0dp" />

2) Then provide your own adapter

public class LinkedListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{


        private final LayoutInflater mInflater;
        private List<String> mItems = Collections.emptyList();



    LinkedListAdapter(Context context) {
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = mInflater.inflate(R.layout.my_layout_item, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((ViewHolder)holder).updateWithItem(this.mItems.get(position), this.callback);
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    void setItems(List<String> items){
        mItems = items;
        notifyDataSetChanged();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        private final TextView itemText;

        private ViewHolder(View view) {
            super(view);
            itemText = view.findViewById(R.id.item);
        }

        public void updateWithItem(String item){
            itemText.setText(item);
        }

    }

    public List<String> getItems() {
        return mItems;
    }

}

3) As you can see now you should have something to define your layout, my_layout_item.xml should be placed in layout folder

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:padding="15dp"
        android:layout_margin="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

4) Now in your fragment or activity you have to linked all this stuff.

myReclyclerView = view.findViewById(R.id.recycler_view);

FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(getActivity());
flexboxLayoutManager.setFlexDirection(FlexDirection.ROW);
flexboxLayoutManager.setJustifyContent(JustifyContent.CENTER);
flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP);
myReclyclerView .setLayoutManager(flexboxLayoutManager);

List<String> items = new ArrayList<String>();
items.add("test");
myAdapter = new LinkedListAdapter (getContext());
myReclyclerView.setAdapter(myAdapter);
myAdapter.setItems(items);

Here we are, that works the best solution to me.

Source in Kotlin from : https://medium.com/gett-engineering/android-div-like-flexbox-layout-55f0e1286d66

Zhar
  • 3,330
  • 2
  • 24
  • 25
0

I had the problem, that the number of views to be placed on the UI was set during runtime. So I decided that I want only four views in one row and adapted the code above accordingly. Also, I always filled up the last row with invisible edit texts so that the views in the last row also had the same width as the views in the row above:

        // 1.0f is the weight!
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
        layoutParams.setMarginEnd(10);

        for (int i = 0; i < Math.ceil(discipline.getSeries_count() / 4.0); i++) {
            LinearLayout layoutRow = new LinearLayout(MyActivity.this);
            layoutRow.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

            // add only four edit texts to row and move to next line afterwards
            for (int j = 0; j < 4; j++) {
                etSeries = new EditText(MyActivity.this);
                etSeries.setInputType(InputType.TYPE_CLASS_NUMBER);
                int iIndex = (j + 1 + (i * 4));
                etSeries.setText(getResources().getString(R.string.series) + " " + iIndex);
                etSeries.setId(iIndex);
                etSeries.setId(i);
                etSeries.setSelectAllOnFocus(true);
                etSeries.setLayoutParams(layoutParams);
                etSeries.setVisibility(iIndex > discipline.getSeries_count() ? View.INVISIBLE : View.VISIBLE);
                layoutRow.addView(etSeries);
            }
            layoutSeries.addView(layoutRow);
        }
AntonSack
  • 1,021
  • 2
  • 25
  • 47