Skip to content

Instantly share code, notes, and snippets.

@hzqtc
Last active December 11, 2018 04:36
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save hzqtc/7940858 to your computer and use it in GitHub Desktop.
Save hzqtc/7940858 to your computer and use it in GitHub Desktop.
Android FlowLayout demo.
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="hzqtc.flowlayout"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light.DarkActionBar">
<activity
android:name="hzqtc.flowlayout.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
package hzqtc.flowlayout;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class FlowLayout extends ViewGroup {
private int paddingHorizontal;
private int paddingVertical;
public FlowLayout(Context context) {
super(context);
init();
}
public FlowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
paddingHorizontal = getResources().getDimensionPixelSize(R.dimen.flowlayout_horizontal_padding);
paddingVertical = getResources().getDimensionPixelSize(R.dimen.flowlayout_vertical_padding);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childLeft = getPaddingLeft();
int childTop = getPaddingTop();
int lineHeight = 0;
// 100 is a dummy number, widthMeasureSpec should always be EXACTLY for FlowLayout
int myWidth = resolveSize(100, widthMeasureSpec);
int wantedHeight = 0;
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
}
// let the child measure itself
child.measure(
getChildMeasureSpec(widthMeasureSpec, 0, child.getLayoutParams().width),
getChildMeasureSpec(heightMeasureSpec, 0, child.getLayoutParams().height));
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
// lineheight is the height of current line, should be the height of the heightest view
lineHeight = Math.max(childHeight, lineHeight);
if (childWidth + childLeft + getPaddingRight() > myWidth) {
// wrap this line
childLeft = getPaddingLeft();
childTop += paddingVertical + lineHeight;
lineHeight = childHeight;
}
childLeft += childWidth + paddingHorizontal;
}
wantedHeight += childTop + lineHeight + getPaddingBottom();
setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int childLeft = getPaddingLeft();
int childTop = getPaddingTop();
int lineHeight = 0;
int myWidth = right - left;
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
}
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
lineHeight = Math.max(childHeight, lineHeight);
if (childWidth + childLeft + getPaddingRight() > myWidth) {
childLeft = getPaddingLeft();
childTop += paddingVertical + lineHeight;
lineHeight = childHeight;
}
child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
childLeft += childWidth + paddingHorizontal;
}
}
}
package hzqtc.flowlayout;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
import java.util.Locale;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup flowContainer = (ViewGroup) findViewById(R.id.flow_container);
for (Locale locale : Locale.getAvailableLocales()) {
String countryName = locale.getDisplayCountry();
if (!countryName.isEmpty()) {
flowContainer.addView(createDummyTextView(countryName),
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
}
}
private View createDummyTextView(String text) {
TextView textView = new TextView(this);
textView.setText(text);
return textView;
}
}
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<hzqtc.flowlayout.FlowLayout
android:id="@+id/flow_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"/>
</ScrollView>
</FrameLayout>
<resources>
<dimen name="flowlayout_horizontal_padding">10dp</dimen>
<dimen name="flowlayout_vertical_padding">10dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">FlowLayout</string>
</resources>
@lilised
Copy link

lilised commented Feb 16, 2016

when I set gravity to right all textview that I added shifted to left it goes like this:
Textview1 Textview2 Textview3 Textview4
but it must be like this:
Textview4 Textview3 Textview2 Textview1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment