I have a Flow layout that display 4 objects for row, but I need display these 4 objects with a textview below each one of them. But it display 2 images and 2 textview, and junp to another row. I tryed to create a ViewGroup to display them together, but I got the same isue. Maybe if I try to set location of the textView inside of the group It canal work, but I dont know How to do it.
My XML:
<ScrollView
android:id="@+id/svLikes"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="60dp"
android:layout_marginEnd="14dp"
android:layout_marginStart="14dp"
android:layout_marginTop="48dp"
android:background="#3c4052"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/btnAdd"
app:layout_constraintVertical_bias="0.0"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1">
<com.nex3z.flowlayout.FlowLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingRight="5dp"
app:childSpacingForLastRow="align"
android:paddingLeft="5dp"
app:rowSpacing="8dp"
android:id="@+id/likesContainer"
>
</com.nex3z.flowlayout.FlowLayout>
</ScrollView>
My code:
ImageView iconLike = new ImageView(Register30.this);
TextView txtLike = new TextView(Register30.this);
iconLike.setImageDrawable(getDrawable(R.drawable.x));
txtLike.setText("Unable");
countLikesAdd++;
removeMessageOrShow();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(140,130);
lp.setMargins(5,5,5,5);
iconLike.setLayoutParams(lp);
txtLike.setLayoutParams(lp);
txtLike.setTextColor(Color.parseColor("#FFFFFF"));
fieldLike.setText("");
ViewGroup gp = new LinearLayout(Register30.this);
gp.addView(iconLike);
gp.addView(txtLike);
likesContainer.addView(gp);
First Method : Static Way I think what you need is a drawable image on TextView. The drawable image can be inserted in any position except center. Create a suitable image of required sizes form asset studio and use this line on TextView.
android:drawableTop="@drawable/ic_fb_logo_blue_48dp"
A simple implementation is written in below code.
<android.support.v4.widget.NestedScrollView
android:id="@+id/svLikes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp"
android:layout_marginEnd="14dp"
android:layout_marginStart="14dp"
android:layout_marginTop="48dp"
android:orientation="vertical">
<com.nex3z.flowlayout.FlowLayout
android:id="@+id/likesContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp"
app:childSpacingForLastRow="align"
app:rowSpacing="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_fb_logo_blue_48dp"
android:gravity="center"
android:text="@string/facebook"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_fb_logo_blue_48dp"
android:gravity="center"
android:text="@string/facebook"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_fb_logo_blue_48dp"
android:gravity="center"
android:text="@string/facebook"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_fb_logo_blue_48dp"
android:gravity="center"
android:text="@string/facebook"
android:textSize="16sp" />
</com.nex3z.flowlayout.FlowLayout>
</android.support.v4.widget.NestedScrollView>
The output image is below. I have used NestedScrollView Instead of ScrollView.
Second Method : Dynamic Programmatically a number of views can be generated by using grid layout. My implemenation using recylerview is below
Inside Activity class:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerOne = (RecyclerView) findViewById(R.id.recyclerView);
initRecyclerView();
//update whenever necessary
adapterOne.updateItems(myList);
}
private void initRecyclerView(){
//Datum is model class
int spanCount = 4; // 4 columns in grid
int spacing = 8;
boolean includeEdge = true;
GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, spanCount);
recyclerOne.setHasFixedSize(false);
recyclerOne.setLayoutManager(gridLayoutManager);
recyclerOne.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge));
adapterOne = new RecylcerViewAdapter(new ArrayList<Datum>());
recyclerOne.setAdapter(adapterOne);
}
The GridSpacingItemDecoration class is
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view); // item position
int column = position % spanCount; // item column
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount) { // top edge
outRect.top = spacing;
}
outRect.bottom = spacing; // item bottom
} else {
outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position >= spanCount) {
outRect.top = spacing; // item top
}
}
}
}
Inside recycler view adapter class, during binding view use a single textview with drawable image as in first method and update data. For updating whole list you create following function and call it from activity class:
public void updateItems(List<Datum> data) {
list.clear()
list.addAll(data)
notifyDataSetChanged();
}
Other methods There is also one other method I know which is done by inflating an item and adding the inflated view on the already created linearlayout(or any other container layouts).
Use whatever methods you like. Enjoy coding!