I wanted a very simple solution that was flexible (which is why I use LinearLayouts). This is what I came up with.
https://github.com/ShalakoSnell/Wrapping_Linear_Layout
Note: I have included an example method using textviews (see textViewArrayListForExample())
The XML is just a parent view LinearLayout with id and vertical orientation, nothing else required.
To use: pass in an array of views that are wrapped in LinearLayouts, along with the parent view and the context.
(see viewAdapterArrayList(ArrayList textViews))
Passing in an array of LinearLayouts is what makes this approach so flexible, as it allows you to add different view types. So in the first LinearLayout you could have text and in the second you could have an image then in the third a button and so on...
Portrait example
Landscape example 50dp margins in verticalLinearLayout
(sorry I can't add images yet... see the links.
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new WrappingLinearLayout(
viewAdapterArrayList(textViewArrayListForExample()), // <-- replace this with you own array of LinearLayouts
(LinearLayout) findViewById(R.id.verticalLinearLayout),
this);
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/verticalLinearLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</LinearLayout>
WrappingLinearLayout.Java
package com.example.wrapping_linear_layout;
import android.content.Context;
import android.widget.LinearLayout;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class WrappingLinearLayout {
public WrappingLinearLayout(@NotNull final ArrayList<LinearLayout> views, @NotNull final LinearLayout verticalLinearLayout, @NotNull final Context context) {
verticalLinearLayout.post(new Runnable() {
@Override
public void run() {
execute(views, verticalLinearLayout, context);
}
});
}
private void execute(@NotNull ArrayList<LinearLayout> views, @NotNull final LinearLayout verticalLinearLayout, @NotNull final Context context) {
ArrayList<LinearLayout> horizontalLinearLayouts = new ArrayList<>();
LinearLayout horizontalLinearLayout = new LinearLayout(context);
horizontalLinearLayouts.add(horizontalLinearLayout);
int verticalLinearLayoutWidth = verticalLinearLayout.getMeasuredWidth()
- (verticalLinearLayout.getPaddingLeft()
+ verticalLinearLayout.getPaddingRight());
int totalWidthOfViews = 0;
for (LinearLayout view : views) {
view.measure(0, 0);
int currentViewWidth = view.getMeasuredWidth();
if (totalWidthOfViews + view.getMeasuredWidth() > verticalLinearLayoutWidth) {
horizontalLinearLayout = new LinearLayout(context);
horizontalLinearLayouts.add(horizontalLinearLayout);
totalWidthOfViews = 0;
}
totalWidthOfViews += currentViewWidth;
horizontalLinearLayout.addView(view);
}
for (LinearLayout linearLayout : horizontalLinearLayouts) {
verticalLinearLayout.addView(linearLayout);
}
}
}
Additional code for example use case:
private ArrayList<LinearLayout> viewAdapterArrayList(ArrayList<TextView> textViews) {
ArrayList<LinearLayout> views = new ArrayList<>();
for (TextView textView : textViews) {
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.addView(textView);
views.add(linearLayout);
}
return views;
}
private ArrayList<TextView> textViewArrayListForExample() {
ArrayList<TextView> textViews = new ArrayList<>();
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
for (int i = 0; i < 40; i++) {
TextView textView = new TextView(this);
textView.setText("View " + i + " |");
if (i < 20) {
if (i % 5 == 0) {
textView.setText("View longer view " + i + " |");
} else if (i % 7 == 0) {
textView.setText("View different length view " + i + " |");
} else if (i % 9 == 0) {
textView.setText("View very long view that is so long it's really long " + i + " |");
}
}
textView.setMaxLines(1);
textView.setBackground(new ColorDrawable(Color.BLUE));
textView.setTextColor(Color.WHITE);
textView.setLayoutParams(layoutParams);
textView.setPadding(20, 2, 20, 2);
layoutParams.setMargins(10, 2, 10, 2);
textViews.add(textView);
}
return textViews;
}
}