I'm trying to create an activity that presents some data to the user. The data is such that it can be divided into 'words', each being a widget, and sequence of 'words' would form the data ('sentence'?), the ViewGroup widget containing the words. As space required for all 'words' in a 'sentence' would exceed the available horizontal space on the display, I would like to wrap these 'sentences' as you would a normal piece of text.
The following code:
public class WrapTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout l = new LinearLayout(this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams mlp = new LinearLayout.LayoutParams(
new ViewGroup.MarginLayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
mlp.setMargins(0, 0, 2, 0);
for (int i = 0; i < 10; i++) {
TextView t = new TextView(this);
t.setText("Hello");
t.setBackgroundColor(Color.RED);
t.setSingleLine(true);
l.addView(t, mlp);
}
setContentView(l, lp);
}
}
yields something like the left picture, but I would want a layout presenting the same widgets like in the right one.
Is there such a layout or combination of layouts and parameters, or do I have to implement my own ViewGroup for this?
Try setting both of lp's LayoutParams to be
WRAP_CONTENT
.Setting mlp to be
WRAP_CONTENT
,WRAP_CONTENT
ensures that your TextView(s) t are just wide and tall enough enough to hold "Hello" or whatever String you put in them. I think l may not be aware of how wide your t's are. ThesetSingleLine(true)
may be contributing too.There is a problem with the first Answer:
In a ListView, for example, the list items are passed a heightMeasureSpec of 0 (UNSPECIFIED) and so, here, the MeasureSpec of size 0 (AT_MOST) is passed to all of the children. This means that the whole PredicateLayout is invisible (height 0).
As a quick fix, I changed the child height MeasureSpec like this:
and then
which seems to work for me although does not handle EXACT mode which would be much more tricky.
I implemented something very similar to this, but using what I think is a little more standard way to handle spacing and padding. Please let me know what you guys think, and feel free to reuse without attribution:
This also requires an entry under /res/values/attrs.xml, which you can create if it's not already there.
Usage in an xml layout looks like this:
Since May 2016 there is new layout called FlexboxLayout from Google, which is highly configurable for purpose you want.
FlexboxLayout is in Google GitHub repository at https://github.com/google/flexbox-layout at this moment.
You can use it in your project by adding dependency to your
build.gradle
file:More about FlexboxLayout usage and all the attributes you can find in repository readme or in Mark Allison articles here:
https://blog.stylingandroid.com/flexboxlayout-part-1/
https://blog.stylingandroid.com/flexboxlayout-part2/
https://blog.stylingandroid.com/flexboxlayout-part-3/
I have updated this sample to fix a bug, now, each line can have a different height !
I adapted some of the ode above and implemented a flow layout which centers all child views, horizontal and vertical. It fits my needs.