How to reduce space between columns in recycler view(GridLayoutManager) in android - android

I am using GridLayoutManager of recyclerview to display custom gallery in my app. I have implementated all the features like gallery. But there is a small thing Im stuck with. In one row I have 3 images. But I need to reduce the space between the images. While doing so , I dont want to show more than 3 images in a row, but the image size (if needed) can increase.

You can use custom RecyclerViewItemDecorator:
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;
}
}
}
Then add it to your RecyclerView:
// For example 10 pixels
int spaceInPixels = 10;
mRecyclerView.addItemDecoration(new RecyclerViewItemDecorator(spaceInPixels));
Hope it helps!

Use this for the recycler view,
this.mRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3));
this.mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getContext())
.color(Color.DKGRAY)
.build());
this.mRecyclerView.addItemDecoration(new VerticalDividerItemDecoration.Builder(getContext())
.color(Color.DKGRAY)
.build());
and in your layout file for each item, set the Image in such a way to meet the edges of the container.
eg:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RlayoutGrid"
android:layout_width="220dp"
android:layout_height="170dp"
android:background="#android:color/black">
<ImageView
android:id="#+id/prefence_imageButton"
android:layout_width="match_parent"
android:layout_height="170dp"
android:background="#android:color/black"
android:focusable="false"
android:focusableInTouchMode="false"
android:scaleType="fitXY"
/>
</RelativeLayout>
and add this to your build.gradle
compile 'com.yqritc:recyclerview-flexibledivider:1.2.4'

To remove spacing you can use outRect.setEmpty()
RecyclerView.ItemDecoration divider = new RecyclerView.ItemDecoration(){
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.setEmpty();
}
};
grid.addItemDecoration(divider);

Related

recyclerview is not fit for all screen sizes

I am using recylerview and gridlayout manager with cardviews for each row, my row view(childview) is not responsive at all.
I want to show 15 cardviews in such a way that in portrait mode all my 15 childview should be visible and my recyclerview should not be scrollable whereas in landscape mode it should act vise versa( should be scrollable)
I have tried many soultions suggested on SO but nothing seems to be working.
current behaviour on different screen sizes are as follows
In the above attached screen shot ,the 3rd column, 4th and 5th row are not visible
In the above given screen my ui fits perfectly in portrait mode but in landscape i can't see all the cardviews.
in the screenshot attached above ,5th row is not visible and in the landscape mode there are some responsivness errors.
cardview.xml
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
android:layout_width="127dp"
android:layout_height="118dp"
android:layout_margin="5dp"
cardview:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/mReminder_Image_Id"
android:layout_width="match_parent"
android:layout_height="90dp"
android:scaleType="fitXY"
android:background="#ffffff"/>
<TextView
android:id="#+id/mReminder_Text_Id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#2d2d2d"
android:textSize="13sp"
android:text="Reminder texts"/>
</LinearLayout>
</android.support.v7.widget.CardView>
fragment_reminders.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Fragments.Reminders">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reminders"
android:textSize="20dp"
android:textStyle="bold"
android:textColor="#color/tab_background"
android:layout_gravity="center" />
</android.support.v7.widget.Toolbar>
<android.support.v7.widget.RecyclerView
android:id="#+id/mRecyclerView_id"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Can anyone guide me to solve this .
Thanks .
you can use this:
recyclerView.setLayoutManager(new RecyclerView.GridLayoutManager(this, span_count)
You could have a
res/values/ints.xml file with <integer> elements, giving the integer a name (name attribute) and value (text of the <integer> node). You could also have res/values-w600dp/ints.xml or res/values-land or other variations of the resource, where you provide
different values to use for different screen sizes. Then, at runtime, call
getResources().getInteger() to retrieve the correct value of the resource to use
for the current device, and use that in your GridLayoutManager constructor. Now,
you are in control over how many columns there are, by controlling how many spans
are supplied to the constructor.
https://developer.android.com/training/multiscreen/screensizes
Another approach, suggested by Chiu-Ki Chan, is to create a subclass of
RecyclerView, on which you provide a custom attribute for a desired approximate
column width. Then, in your subclass’ onMeasure() method, you can calculate the
number of spans to use to give you the desired column width.
https://developer.android.com/reference/android/support/v7/widget/GridLayoutManager.html#GridLayoutManager(android.content.Context,%20int)
https://developer.android.com/reference/android/support/v7/widget/RecyclerView#setlayoutmanager
create a class as follows:
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 spacing;
private int displayMode;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int GRID = 2;
public EqualSpacingItemDecoration(int spacing) {
this(spacing, -1);
}
public EqualSpacingItemDecoration(int spacing, int displayMode) {
this.spacing = spacing;
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 = spacing;
outRect.right = position == itemCount - 1 ? spacing : 0;
outRect.top = spacing;
outRect.bottom = spacing;
break;
case VERTICAL:
outRect.left = spacing;
outRect.right = spacing;
outRect.top = spacing;
outRect.bottom = position == itemCount - 1 ? spacing : 0;
break;
case GRID:
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
int cols = gridLayoutManager.getSpanCount();
int rows = itemCount / cols;
outRect.left = spacing;
outRect.right = position % cols == cols - 1 ? spacing : 0;
outRect.top = spacing;
outRect.bottom = position / cols == rows - 1 ? spacing : 0;
}
break;
}
}
private int resolveDisplayMode(RecyclerView.LayoutManager layoutManager) {
if (layoutManager instanceof GridLayoutManager) return GRID;
if (layoutManager.canScrollHorizontally()) return HORIZONTAL;
return VERTICAL;
}
}
and for using it with your recycler view:
1)for grid view:
recyclerView.addItemDecoration(new EqualSpacingItemDecoration(<sizeofpixels>, EqualSpacingItemDecoration.GRID));
2)for vertical view:
recyclerView.addItemDecoration(new EqualSpacingItemDecoration(<sizeofpixels>, EqualSpacingItemDecoration.VERTICAL));
3)for horizontal view:
recyclerView.addItemDecoration(new EqualSpacingItemDecoration(<sizeofpixels>, EqualSpacingItemDecoration.HORIZONTAL));
hope this helps you.

RecyclerView - Layout_weight is ignored when it loads first time

I have an Activity that contains a Fragment. Fragment contains a RecyclerView, displaying CardViews.
CardView is very simple, just a TextView and a CustomView. This is the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="100dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="#+id/card_current_heat_cardview"
android:layout_gravity="center_vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:weightSum="4">
<TextView
android:id="#+id/card_current_heat_textview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textStyle="bold"
android:textColor="#000000"
android:background="#android:color/holo_red_dark"
android:gravity="center_vertical"/>
<com.amige.vm2.CurrentHeatChartView
android:id="#+id/card_current_heat_chart_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
TextView should use 1/4 of the width, and the CustomView 3/4.
Im having trouble understanding why weights are ignored the first time the RecyclerView loads
Image of RecyclerView loaded for the first time
But if I scroll up and down, the layout works as expected for some Cards
Image of RecyclerView scrolled up and down
I also have another Activity (no fragment involved here) that has a RecyclerView and IS using this same CardView Layout and it works perfectly!!
I dont know if it has to do with the Fragment...
What am I missing?
Thanks!
EDIT
This the Adapter code
public class MainAdapter extends RecyclerView.Adapter<MyFragment.MainAdapter.ViewHolder>
{
public MainAdapter()
{
}
#Override
public MyFragment.MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_current_heat, parent, false);
return new MyFragment.MainAdapter.ViewHolder(v);
}
#Override
public void onBindViewHolder(MyFragment.MainAdapter.ViewHolder holder, int position)
{
if (arrayList.size() == 2)
{
if (position == 0)
{
holder.variableNameTextView.setText(“Var Name”);
holder.currentHeatChartView.reloadChartWithSamples(arrayList.get(0));
}
else
{
if ((position - 1) < arrayList.get(1).size())
{
HashMap variableHashMap = (HashMap) arrayList.get(1).get(position - 1);
holder.variableNameTextView.setText(variableHashMap.get("VarName") != null ? (String)variableHashMap.get("VarName") : "");
holder.currentHeatChartView.reloadChartWithVariableValuesAndColors(variableHashMap, colorGradientsArrayList.get((position - 1) % colorGradientsArrayList.size()));
}
}
}
}
#Override
public int getItemCount()
{
if (arrayList.size() == 2)
{
if (arrayList.get(1).size() > 0)
{
return 1 + arrayList.get(1).size();
}
else
{
return 1;
}
}
return 0;
}
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView variableNameTextView;
CurrentHeatChartView currentHeatChartView;
public ViewHolder(View v)
{
super(v);
this.variableNameTextView = (TextView) v.findViewById(R.id.card_current_heat_textview);
this.currentHeatChartView = (CurrentHeatChartView) v.findViewById(R.id.card_current_heat_chart_view);
}
}
}
I found the culprit.
There was a ConstraintLayout on top of the hierarchy of the Activity containing the Fragment. Since I was working with nested layouts, ConstraintLayout was not the right way to go.
I changed it to RelativeLayout and the cards are now rendered properly.
I think your layout inflation is wrong.
View view = View.inflate(mContext, R.layout.your_layout, null);
If you do like that change your code like this.
View view = LayoutInflater.from(mContext).(R.layout.your_layout, parent, false);
Hope it helps:)

How to show images with horizontal scrolling android

I am using a Recyclerview to show the list of items. Now each time can have some photos/multiple photos which I need to show with horizontal scrolling in a single row.
I am currently using Gallery widget to show the photos but as it is now deprecated, so I want some other thing to use to show images horizontally with same features as Gallery have. Can you please help me here.
Thanks a lot in advanced.
Here is the example of horizontal scrollable RecycleView showing bitmap images:
fragment/activity layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
...
<android.support.v7.widget.RecyclerView
android:id="#+id/horizontal_recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:horizontalSpacing="10dp"
android:isScrollContainer="false"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
/>
...
</LinearLayout>
item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/horizontal_item_view_image"
android:layout_marginRight="10dp"
android:layout_width="109dp"
android:layout_height="109dp" />
</LinearLayout>
adapter:
public class HorizontalPhotosAdapter extends RecyclerView.Adapter<HorizontalPhotosAdapter.MyViewHolder> {
private Context context;
private LayoutInflater inflater;
private ArrayList<Bitmap> bitmapList;
public class MyViewHolder extends RecyclerView.ViewHolder {
private ImageView riv;
public MyViewHolder(View view) {
super(view);
riv = (ImageView) view.findViewById(R.id.horizontal_item_view_image);
}
}
public HorizontalPhotosAdapter(Context context, ArrayList<Bitmap> bitmapList, String[] imageUrls) {
this.context = context;
this.bitmapList = bitmapList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_item_view, parent, false);
if (itemView.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT)
itemView.getLayoutParams ().width = RecyclerView.LayoutParams.WRAP_CONTENT;
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.riv.setImageBitmap(bitmapList.get(position));
}
#Override
public int getItemCount() {
return bitmapList.size();
}
}
implementation in fragment/activity:
horizontalAdapter=new HorizontalPhotosAdapter(getContext(), bitmapList);
horizontal_recycler_view.setAdapter(horizontalAdapter);
horizontalAdapter.notifyDataSetChanged();
LinearLayoutManager horizontalLayoutManagaer = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
horizontal_recycler_view.setLayoutManager(horizontalLayoutManagaer);
horizontal_recycler_view.setAdapter(horizontalAdapter);
You can use HorizontalScrollView or ViewPager for your purpose.
Android Viewpager as Image Slide Gallery
You can use viewpager to implement slide show gallery
follow link -
http://codetheory.in/android-image-slideshow-using-viewpager-pageradapter/
A LayoutManager is responsible for measuring and positioning item views within a RecyclerView as well as determining the policy for when to recycle item views that are no longer visible to the user. By changing the LayoutManager a RecyclerView can be used to implement a standard vertically scrolling list, a uniform grid, staggered grids, horizontally scrolling collections and more. Several stock layout managers are provided for general use.
Try the below code to get recycler view with horizontal item
LinearLayoutManager ll_manager= new LinearLayoutManager(getActivity());
ll_manager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(llmRecent);
You can also use the following piece of code:
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 1);
gridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(gridLayoutManager);

Center Columns in RecyclerView

I'm trying to create a dynamic RecyclerView layout. I am using a GridLayoutManager with three columns.
I need to wrap each grid item and center the columns (like attached).
I have tried a StaggeredGridLayout, I have tried a WrapGridLayoutManager but neither of these worked.
Here is my RecyclerView:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/categories_grid"
android:layout_marginTop="#dimen/feed_item_margin"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
and my RecyclerView item:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:background="#drawable/first_time_category_unselected"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="#+id/category_name"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_gravity="center_vertical"
android:textColor="#color/black_colour"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/category_status_icon"
android:layout_gravity="center_vertical"
android:background="#drawable/icon_follow"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
This is the decoration I'm using to implement grid spacing:
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int halfSpace;
public SpacesItemDecoration(int space) {
this.halfSpace = space / 2;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (parent.getPaddingLeft() != halfSpace) {
parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace);
parent.setClipToPadding(false);
}
outRect.top = halfSpace;
outRect.bottom = halfSpace;
outRect.left = halfSpace;
outRect.right = halfSpace;
}
}
This is what I'm trying to achieve:
This is what I am getting:
If anyone can help on this I'd greatly appreciate it
You can use Staggered Grid Layout Manager
as
StagaggeredGridLayoutManager = new StaggeredGridLayoutManager(3, LinearLayoutManager.HORIZONTAL );
recyclerView.setLayoutManager(gaggeredGridLayoutManager);
Here is Link for reference
Use this in recyclerView you could not arrange as you shown
<cuneyt.example.com.tagview.Tag.TagView
android:id="#+id/tag_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" />
Download repo from GIT https://github.com/Cutta/TagView
TagView tagGroup = (TagView)findviewById(R.id.tag_view);
//You can add one tag
tagGroup.addTag(Tag tag);
//You can add multiple tag via ArrayList
tagGroup.addTags(ArrayList tags);
//Via string array
addTags(String[] tags);
//set click listener
tagGroup.setOnTagClickListener(new OnTagClickListener() {
#Override
public void onTagClick(Tag tag, int position) {
}
});
//set delete listener
tagGroup.setOnTagDeleteListener(new OnTagDeleteListener() {
#Override
public void onTagDeleted(final TagView view, final Tag tag, final int position) {
}
});
How do I make WRAP_CONTENT work on a RecyclerView

StaggeredGridLayoutManager without ItemDecoration

StaggeredGridLayoutManager without ItemDecoration needs onScroll to arrange the items in matrix/Grid format. Is there a way to avoid ItemDecoration because I don't want decorator between items.
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL))
//Without addItemDecoration - it requires a scroll to occupy all the columns
recycler.addItemDecoration(new CustomInsetsDecoration(context));
without item decoration --
A
B
C
D
E
F
with item decoration (with min 1px/dp apart)
A B C
D E F
What I want:
ABC
DEF
A,B,C,D,E,F are all are ImageViews (of different sizes)
My item layout - a very simple - relativelayout and an Imageview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/item_browse_cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />
</RelativeLayout>
Any input is appreciated.
Thanks in advance.
Use the following MarginDecorator class with a 0 margin
public class MarginDecorator extends RecyclerView.ItemDecoration {
private int margin;
public MarginDecorator(int margin) {
this.margin = margin;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.top = margin;
outRect.bottom = margin;
outRect.left = margin;
outRect.right = margin;
}
}
Also try using the setGapStrategy()

Categories

Resources