Skip to content

Instantly share code, notes, and snippets.

@mrleolink
Last active August 29, 2015 14:09
Show Gist options
  • Save mrleolink/67af78464ecf6084acf3 to your computer and use it in GitHub Desktop.
Save mrleolink/67af78464ecf6084acf3 to your computer and use it in GitHub Desktop.
A simple implementation for AutoWrapLayout for TextView
/**
* This f**king code was created by Leo on 11/12/14.
*/
public class AutoWrapLayout extends RelativeLayout {
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
private static final int DEFAULT_MARGIN = 5; // dp
private int margin;
private LinkedList<String> dataList;
public AutoWrapLayout(Context context) {
this(context, null);
}
public AutoWrapLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoWrapLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
margin = (int) (getResources().getDisplayMetrics().density * DEFAULT_MARGIN);
}
public void setDataList(LinkedList<String> dataList) {
this.dataList = dataList;
for (String string : dataList) {
Button button = (Button) inflate(getContext(), R.layout.my_button, null);
setViewId(button);
button.setText(string);
addView(button);
}
// re-layout
post(new Runnable() {
@Override
public void run() {
reLayout();
}
});
}
/**
* Set margin in DP
* @param margin in DP
*/
public void setMargin(int margin) {
this.margin = (int) (margin * getResources().getDisplayMetrics().density);
// re-layout
post(new Runnable() {
@Override
public void run() {
reLayout();
}
});
}
private void reLayout() {
View topView = null;
int totalWidth = 0;
int maxWidth = getMeasuredWidth();
maxWidth -= getPaddingLeft() + getPaddingRight(); // take paddings in to account
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
int width = v.getMeasuredWidth();
if (i == 0) {
totalWidth = width;
} else {
if (totalWidth + width > maxWidth) {
topView = getChildAt(i - 1);
layoutParams.addRule(BELOW, topView.getId());
layoutParams.topMargin = margin;
totalWidth = width;
} else {
if (topView != null) {
layoutParams.addRule(BELOW, topView.getId());
layoutParams.topMargin = margin;
}
layoutParams.addRule(RIGHT_OF, getChildAt(i - 1).getId());
layoutParams.leftMargin = margin;
totalWidth += width + margin;
}
}
v.setLayoutParams(layoutParams);
}
}
private void setViewId(View v) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
v.setId(generateViewIdManually());
} else {
v.setId(generateViewId());
}
}
/**
* Generate a value suitable for use in {@link #setId(int)}.
* This value will not collide with ID values generated at build time by aapt for R.id.
*
* @return a generated ID value
*/
private int generateViewIdManually() {
for (;;) {
final int result = sNextGeneratedId.get();
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1;
if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
if (sNextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="5dp"/>
<solid
android:color="@android:color/transparent" />
<stroke
android:color="@android:color/holo_green_dark"
android:width="2dp" />
<padding
android:bottom="10dp"
android:top="10dp"
android:left="10dp"
android:right="10dp"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_bg"
android:textSize="25sp"/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment