How to give space between gridview in through java - android

How do i get perfect aligning between the gridView items, i have added the gridview using java and it's base adapter is set in which i added the image and textview.
Xml Code:
<android.support.v7.widget.CardView
android:layout_width="180dp"
android:layout_height="200dp"
android:layout_margin="5dp"
android:orientation="vertical"
app:cardCornerRadius="5dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="#+id/ImageWomenItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:scaleType="fitXY"
android:src="#drawable/womenone" />
</LinearLayout>
<TextView
android:id="#+id/itemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Red Top"
android:textColor="#8e8d8d"
android:textSize="15dp" />
</LinearLayout>
</android.support.v7.widget.CardView>
This is Activity code in which i declared the recylerview and set it's adapter
Java code:
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerViewClothes);
recyclerView.setHasFixedSize(true);
mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
mAdapter = new GridAdapter();
recyclerView.setAdapter(mAdapter);

Use Space Decoration Class For That
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
#Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
outRect.bottom = space;
// Add top margin only for the first item to avoid double space between items
if (parent.getChildLayoutPosition(view) == 0) {
outRect.top = space;
} else {
outRect.top = 0;
}
}
}
Your Activity Where You Set Your Adapter
int spacing = getResources().getDimensionPixelSize(R.dimen.spacing);
recyclerview.addItemDecoration(new SpacesItemDecoration(spacing));
Specify in dimen.xml
<dimen name="spacing">5px</dimen>
Xml Code:
<android.support.v7.widget.CardView
android:layout_width="175dp"
android:layout_height="200dp"
android:orientation="vertical"
app:cardCornerRadius="5dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="#+id/ImageWomenItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:scaleType="fitXY"
android:src="#drawable/womenone" />
</LinearLayout>
<TextView
android:id="#+id/itemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Red Top"
android:textColor="#8e8d8d"
android:textSize="15dp" />
</LinearLayout>
</android.support.v7.widget.CardView>

Try this,
recyclerView = (RecyclerView) findViewById(R.id.recyclerView );
recyclerView .setLayoutManager(new GridLayoutManager(getActivity(), 2));
int spanCount = 2;
int spacing_left = 10;
int spacing_top=15;
recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing_left, spacing_top));
GridSpacingItemDecoration:
/* set spacing for grid view */
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
final private int spanCount, spacing, spacing_top;
final private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing_left, int spacing_top) {
this.spanCount = spanCount;
this.spacing = spacing_left;
this.includeEdge = true;
this.spacing_top = spacing_top;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view); // item phases_position
int column = position % spanCount; // item column
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount;
outRect.right = (column + 1) * spacing / spanCount;
if (position < spanCount) { // top edge
outRect.top = spacing_top;
}
outRect.bottom = spacing_top; // item bottom
} else {
outRect.left = column * spacing / spanCount;
outRect.right = spacing - (column + 1) * spacing / spanCount;
if (position >= spanCount) {
outRect.top = spacing_top; // item top
}
}
}
}

Add padding to your root layout of adapter xml.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp">
<android.support.v7.widget.CardView
app:cardCornerRadius="5dp"
app:cardElevation="5dp"
android:layout_width="180dp"
android:layout_height="200dp"
android:layout_margin="5dp"
android:orientation="vertical">.......
</android.support.v7.widget.CardView>
</LinearLayout>

Related

Cardview doesn't have any affect on items

I'm trying to make my RecyclerView prettier, so I added a CardView. However, I don't see any changes when I ran the app, the UI looks like as if there's no CardView at all - there is not separation between the items. Can you please suggest what's wrong with my code here?
This is my list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/link_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="1dp"
android:layout_marginBottom="10dp"
android:layout_marginStart="10dp"
android:text="#string/title_place_holder"/>
<LinearLayout
android:layout_below="#id/link_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<android.support.v7.widget.AppCompatImageView
android:id="#+id/link_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="center"
app:srcCompat="#drawable/ic_launcher_background"/>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/link_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="15sp"
android:padding="1dp"
android:text="#string/summary_place_holder"/>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
This is how I initialize my RecylerView:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
mAdapter = new PostsAdapter(mPostList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
preparePostData();
}
This can be achieved with a 1 line change in xml applied to the CardView element applying a margin.
android:layout_margin"#dimen/default_margin"
With your code:
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp"
android:layout_margin"#dimen/default_margin">
And in the dimens resources file
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<dimen name="default_margin">10dp</dimen>
</resources>
I have made changes in your code, please try below code
in place on
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp"
I've changed to below
app:cardCornerRadius="4dp"
app:cardElevation="6dp"
app:cardUseCompatPadding="true"
Just replace below layout code
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com /apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:cardCornerRadius="4dp"
app:cardElevation="6dp"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/link_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="1dp"
android:layout_marginBottom="10dp"
android:layout_marginStart="10dp"
android:text="#string/title_place_holder"/>
<LinearLayout
android:layout_below="#id/link_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<android.support.v7.widget.AppCompatImageView
android:id="#+id/link_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="center"
app:srcCompat="#drawable/ic_launcher_background"/>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/link_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="15sp"
android:padding="1dp"
android:text="#string/summary_place_holder"/>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
You need item decoration in RecyclerView with equal spacing around item!
Note : make sure yourRecyclerView background is different that item background
EqualSpacingItemDecoration.java
import android.graphics.Canvas;
import android.graphics.Rect;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class EqualSpacingItemDecoration extends RecyclerView.ItemDecoration {
private final int top;
private final int left;
private final int bottom;
private final int right;
private int displayMode;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int GRID = 2;
public EqualSpacingItemDecoration(int top, int left, int bottom, int right) {
this(top, left, bottom, right, -1);
}
public EqualSpacingItemDecoration(int top, int left, int bottom, int right, int displayMode) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
this.displayMode = displayMode;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildViewHolder(view).getAdapterPosition();
int itemCount = state.getItemCount();
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
setSpacingForDirection(outRect, layoutManager, position, itemCount);
}
private void setSpacingForDirection(Rect outRect,
RecyclerView.LayoutManager layoutManager,
int position,
int itemCount) {
// Resolve display mode automatically
if (displayMode == -1) {
displayMode = resolveDisplayMode(layoutManager);
}
switch (displayMode) {
case HORIZONTAL:
outRect.left = left;
outRect.right = position == itemCount - 1 ? right : 0;
outRect.top = top;
outRect.bottom = bottom;
break;
case VERTICAL:
outRect.left = left;
outRect.right = right;
outRect.top = top;
outRect.bottom = position == itemCount - 1 ? bottom : 0;
break;
case GRID:
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
int cols = gridLayoutManager.getSpanCount();
int rows = itemCount / cols;
outRect.left = left;
outRect.right = position % cols == cols - 1 ? right : 0;
outRect.top = top;
outRect.bottom = position / cols == rows - 1 ? bottom : 0;
}
break;
}
}
private int resolveDisplayMode(RecyclerView.LayoutManager layoutManager) {
if (layoutManager instanceof GridLayoutManager) return GRID;
if (layoutManager.canScrollHorizontally()) return HORIZONTAL;
return VERTICAL;
}
#Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
}
}
Use like :
...
mRecyclerView..addItemDecoration(new EqualSpacingItemDecoration(12,12,12,12,1))
...
Just simply use app:cardUseCompatPadding="true" in CardView tag.
Try this in your manifest application tag.
android:hardwareAccelerated="true"

How to remove margin between RecyclerView items

I am trying to make a screen as shown in the picture, as you can see there is no spacing between items in the RecyclerView.
Desired Image:
So far my item_layout for each of the item in recycler view is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
android:layout_width="120dp"
android:layout_margin="0dp"
android:layout_height="190dp"
app:cardCornerRadius="0dp">
<LinearLayout
android:id="#+id/colorBox"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="horizontal">
<TextView
android:id="#+id/colorNameBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:text="asd"
android:textColor="#fff"
android:textSize="16dp"
>
</TextView>
</LinearLayout>
</android.support.v7.widget.CardView>
my ItemDecoration in ColorShadesActivity is given below:
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount; //3
private int spacing; //0
private boolean includeEdge; //false
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 = spacing; // column * ((1f / spanCount) * spacing)
outRect.right = spacing; // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position >= spanCount) {
outRect.top = spacing; // item top
}
}
}
}
But the result I am getting is:
To show GridLayout using RecyclerView You need to make only few steps:
tell RecyclerView that You want to show the elements in GridLayout
declare how many columns You would like to use in GridLayout
set the same height for every element in case You would like to show all elements in equal rows
Here is a working sample code in simplified way to achieve that what You want. I am dynamically change item's height but You can use xml layout for that.
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
private Random random;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
random = new Random(System.currentTimeMillis());
recyclerView = findViewById(R.id.recyclerView);
layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(new RecyclerView.Adapter() {
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View inflate = LayoutInflater.from(viewGroup.getContext()).inflate(android.R.layout.simple_list_item_1, viewGroup, false);
ViewGroup.LayoutParams layoutParams = inflate.getLayoutParams();
layoutParams.height = (int) (getResources().getDisplayMetrics().scaledDensity * 56);
inflate.setLayoutParams(layoutParams);
int randomColor = random.nextInt(Colors.COLORS.length);
inflate.setBackgroundColor(Color.parseColor(Colors.COLORS[randomColor]));
return new RecyclerViewViewHolder(inflate);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
((TextView) viewHolder.itemView.findViewById(android.R.id.text1)).setText(Cheeses.CHEESES[i]);
}
#Override
public int getItemCount() {
return Cheeses.CHEESES.length;
}
});
}
private class RecyclerViewViewHolder extends RecyclerView.ViewHolder {
RecyclerViewViewHolder(#NonNull View itemView) {
super(itemView);
}
}
}
Source on Github

View not appearing at bottom of CardView?

Hi I have a simple CardView where I want to show a divider between each Cardview. The issue is, my View that I use as a divider never gets shown on the last CardView in my RecyclerView. Here is my attempt:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:fresco="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
card_view:cardElevation="0dp"
android:id="#+id/cv_news_feed">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
...Content...
</RelativeLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/material_color_grey_300" />
</android.support.v7.widget.CardView>
The divider shows up for every CardView except for the last for whatever reason and I'm not sure why this is occurring. Any help would be appreciated, thanks!
EDIT: Image posted:
Remove following view from your item
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/material_color_grey_300" />
and try to use ItemDecoration as follows
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
Utility.ItemDecorationConst);
recyclerView.addItemDecoration(5);
DividerItemDecoration.java
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public DividerItemDecoration(int space) {
this.space = space;
}
#Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
outRect.top = space;
outRect.bottom = space;
}
}
CardView is an extension of FrameLayout which means that your divider is not in the bottom of your CardView but in the top.
Place your divider in your LinearLayout instead.
Add layout_gravity attribute to the View:
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:background="#color/material_color_grey_300" />
You can try to this code , hope this can help you
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:fresco="http://schemas.android.com/tools"
android:id="#+id/cv_news_feed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
card_view:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
...Content...
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="#+id/cv_news_feed"
android:layout_marginTop="5dp"
android:background="#android:color/holo_red_dark" />
</RelativeLayout>
Create a class DividerItemDecoration:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by Lincoln on 30/10/15.
*/
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}
#Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
Then set the item decoration using addItemDecoration() method before setting the adapter.
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
// set the adapter
recyclerView.setAdapter(mAdapter);
N.B. Remove the view that you are using in cardview layout to show the divider.
Try to put your divider into LinearLayout,i.e.:
You should use like this
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
...Content...
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/material_color_grey_300" />
</LinearLayout>
Because CardView extends FrameLayout so your devider will be behind LinearLayout content.

How to remove spacing between images in recycleview?

Hi would like to ask if anyone know whats' wrong with recycleview having so much spacing between images? The following is how i tried using margin to control the spaces however it seems not the right solution to my problem.
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/galleryRecyclerView"
android:clipToPadding="false"
android:layout_below="#id/displayGalleryView"
android:longClickable="false" />
And the image xml:
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginLeft="-70dp"
android:id="#+id/imageGalleryView"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
I used marginLeft to control the spaces and it worked before i integrate other features, it's so strange.
Image here
mRecyclerView = (RecyclerView) findViewById(R.id.galleryRecyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(layoutManager.HORIZONTAL);
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, 0, 0);
layoutManager.canScrollHorizontally();
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.addItemDecoration(new RecyclerViewItemDecorator(1));
RecyclerView.Adapter imageAdapter = new GalleryImageAdapter(mGalleryFolder);
mRecyclerView.setAdapter(imageAdapter);
you can reduce gap between items in recycler view...
use this as inner class .
public class RecyclerViewItemDecorator extends RecyclerView.ItemDecoration {
private int spaceInPixels;
public RecyclerViewItemDecorator(int spaceInPixels) {
this.spaceInPixels = spaceInPixels;
}
#Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.left = spaceInPixels;
outRect.right = spaceInPixels;
outRect.bottom = spaceInPixels;
if (parent.getChildLayoutPosition(view) == 0) {
outRect.top = spaceInPixels;
} else {
outRect.top = 0;
}
}
}
call
list.addItemDecoration(new RecyclerViewItemDecorator(1));
before setting the adapter

center items horizontally in RecyclerView(using GridLayoutManager)

I'm trying to center all my items horizontally for each row in RecyclerView
I tried many things: RelativeLayout as a parent, then use layout_centerInParent, use the basic android:layout_gravity="center", try to add some space element,using weights and .... in
item_row.xml
but I didn't succeed :(
What i have
What i want
In activity
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
item_row.xml
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true">
<!-- Recycler View Item Row -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imgThumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:background="#android:color/black" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="item name"
android:id="#+id/txtName"
android:layout_margin="5dp"
android:singleLine="false"
android:lines="2"
android:gravity="center" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/txtCategory"
android:textStyle="italic"
android:textColor="#496fa9"
android:text="subtitle"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:layout_gravity="center" />
<ImageButton
android:id="#+id/imageButton"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:padding="8dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
i googled a lot and found this answer but actually i don't know how to create a LinearLayout for each row of items!
is that the best solution?
any other idea?
you can use a SpanSizeLookup to make views/items with different widths for your grid view. So with that you can do some cleverness with empty views to adjust accordingly. Might be more complicate or simpler depending on how variable your layout actually is.
reference: https://developer.android.com/reference/android/support/v7/widget/GridLayoutManager.SpanSizeLookup.html
for this specific case you show on your drawing you would do something like:
GridLayoutManager lm = new GridLayoutManager(context, 6);
lm.setSpanSizeLookup(new MySizeLookup());
public static class MySizeLookup extends SpanSizeLookup {
public int getSpanSize(int position) {
if(position >= 0 && position <= 2) {
return 2;
} else if (position == 3 || position == 6) {
return 1;
} else {
return 2;
}
}
}
and with that you'll have to make on your adapter, the position 3 and 6 to be an empty/invisible element. Something like new View(context); just to occupy that extra space
Use the gridLayoutManager = new GridLayoutManager(context,6) and override setSpanSizeLookup.
Example:
int totalSize=list.size();
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
int span;
span = totalSize % 3;
if (totalSize < 3) {
return 6;
} else if (span == 0 || (position <= ((totalSize - 1) - span))) {
return 2;
} else if (span == 1) {
return 6;
} else {
return 3;
}
}
});
This will work if you want to display 3 items in a row and remaining in the center of the grid.
Change the grid layout manager span counts accordingly your requirement.
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 6);
final int totalSize = customList.size();
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
int extra;
extra = totalSize % 3;
if(extra == 0)
return 2;
if (totalSize - (position + 1) < extra) {
return (int) 6 / extra;
}
return 2;
}
});
recycler.setLayoutManager(layoutManager);
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 6);
final int totalSize = customList.size();
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
int rows = Math.round((totalSize / 3f) + 0.4f);
int itemInRow = Math.round(((position + 1) / 3f) + 0.4f);
if (rows == 1 || rows == itemInRow) {
int span = totalSize % 3;
if (span == 0) {
return 2;
}
return 6 / span;
}
return 2;
}
});

Categories

Resources