How to Do Something Like a Flowlayout in Android

wrap a layout with textviews

Try adding the textviews in a loop, adding each one separately in a new OnPreDrawListener. After each one is added, check if it exceeds the space on the row, and if so remove it and add the counter. If it still exceeds the row, remove one more and increase the counter.

The key is to test each in a separate OnPreDrawListener, so it all happens before the view is shown, but after the view has had its layout and size calculated.

Does anyone know how to do flow layout using RecyclerView?

Here is the full example
of using custom Library which acts like List GitHubLibrary TagLayout

  • Sample Code:-

mFlowLayout.setAdapter(new TagAdapter<String>(mVals)
{
@Override
public View getView(FlowLayout parent, int position, String s)
{
TextView tv = (TextView) mInflater.inflate(R.layout.tv,
mFlowLayout, false);
tv.setText(s);
return tv;
}
});

Using below code you can pre set selection you wanted:-

mAdapter.setSelectedList(1,3,5,7,8,9);

Will show result like below:-

Sample Image

Android: Custom FlowLayout

finally I did it with help of this library. I have used only class FlowLayout and attr.xml My main.xml looks like this:

    <com.example.FlowTest.FlowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="@android:color/white"/>

and my item layout looks like this:

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp"/>

And in my Activity's onCreate method:

LayoutInflater mInflater = LayoutInflater.from(this);
mFlowLayout = (FlowLayout) findViewById(R.id.flow);

String [] names = {"goods", "shops", "cars", "washing machine","blablabla","clothes","books"};

for(int i = 0; i<names.length;i++){
Button b = (Button)mInflater.inflate(R.layout.item_flow,mFlowLayout, false);
b.setText(names[i]);
mFlowLayout.addView(b);
}

FlowLayout for Android Widgets

I tried to extend LinearLayout but it appears descendants of the mentioned layouts are not permitted.

Correct.

Perhaps I can programatically rearrange my TextViews using a RelativeLayout?

I don't see how, as you are not the one rendering your UI.

Is there a smarter way to achieve this?

It is unclear what "this" is. If "this" is "a FlowLayout type UI for an app widget", either write your own home screen (so you can have the UI you want without the need for an app widget), or redesign the UI. App widgets have a limited palette of available widgets and containers, as you have noted.

Strategically, you could contribute a FlowLayout to AOSP and home that it becomes available in some future version of Android, and further hope that it will be enabled for use by app widgets.

Why are Widget layouts so very restrictive? Am I missing something important?

App widgets are rendered by the home screen. There are thousands of home screen implementations. They run in their own processes, with their own code, written by their own developers.

As such, you are not actually creating widgets in your app that are displayed by the home screen. Instead, you are creating a data structure, describing the widgets you want the home screen to create on your behalf. As such, RemoteViews does not support app-defined subclasses, simply because your app's classes are not in the home screen's process.

A way to Wrap LinearLayout

You can use GridView instead of LinearLayout.

<GridView
android:id="@+id/tagsLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="auto_fit"
android:horizontalSpacing="5dp"
android:verticalSpacing="5dp"/>

This should automatically put the TextView to next line. If you want something more dynamic then you use FlowLayout library or StaggeredLayout.Check out this SO which claims that it has alternative to FlowLayout.

Can the Android Flow virtual layout handle variable-width Views

Here is a simple example of how it can be achieved (ConstraintLayout:2.0.0-beta2):

<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text1,text2,text3,text4,text5"
app:flow_wrapMode="chain"
app:flow_horizontalStyle="packed"
app:flow_horizontalBias="0"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:background="#FF0000"/>

<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="That is a very long textview that is very, very long"
android:background="#00FF00"/>

<TextView
android:id="@+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text3 which is somewhat long"
android:background="#0099FF"/>

<TextView
android:id="@+id/text4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text4"
android:background="#999999"/>

<TextView
android:id="@+id/text5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text5"
android:background="#9900FF"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Result:

flex with flow

  • app:flow_wrapMode="chain" allows for the chain to wrap to the next line when there's not enough space
  • app:flow_horizontalStyle="packed" is necessary to be able to set the bias
  • app:flow_horizontalBias="0" aligns the Views to the left
  • app:flow_horizontalGap="Xdp" can be used to set a gap between the Views

Other wrap styles (spread and spread_inside) will not take the bias into account as they have a predefined way of laying out the Views



Related Topics



Leave a reply



Submit