I have 2 fragments that will show the gridview with recyclerview
if i use acitivity, my code does not get any problem
but if I use fragment, the view I get is always blank
I have 2 fragments that will show the gridview with recyclerview
if i use acitivity, my code does not get any problem
but if I use fragment, the view I get is always blank
is there anyone who can help me?
This my code
GridAdapter.java
package dev.id.sample.grid;
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.MyViewHolder> {
private Context mContext;
private List<Grid> gridList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, count;
public ImageView thumbnail, overflow;
public MyViewHolder(View view) {
super(view);
thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
}
}
public GridAdapter(Context mContext, List<Grid> gridList) {
this.mContext = mContext;
this.gridList = gridList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.album_card, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Grid grid = gridList.get(position);
// loading grid cover using Glide library
Glide.with(mContext).load(grid.getThumbnail()).into(holder.thumbnail);
holder.thumbnail.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
}
});
}
#Override
public int getItemCount() {
return gridList.size();
}
}
fragment.java
public class xxx extends Fragment {
private RecyclerView recyclerView;
private GridAdapter adapter;
private List<Grid> gridList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_bank, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
gridList = new ArrayList<>();
adapter = new GridAdapter(getActivity(), gridList);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
prepareAlbums();
// Inflate the layout for this fragment
return view;
}
private void prepareAlbums() {
int[] covers = new int[]{
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher
};
Grid
a = new Grid("cccc", 13, covers[0]);
gridList.add(a);
a = new Grid("cccc", 8, covers[1]);
gridList.add(a);
a = new Grid("cccc", 8, covers[2]);
gridList.add(a);
a = new Grid("cccc", 8, covers[3]);
gridList.add(a);
a = new Grid("cccc", 8, covers[4]);
gridList.add(a);
a = new Grid("cccc", 8, covers[5]);
gridList.add(a);
adapter.notifyDataSetChanged();
}
/**
* RecyclerView item decoration - give equal margin around grid item
*/
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
}
}
}
}
/**
* Converting dp to pixel
*/
private int dpToPx(int dp) {
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
}
Related
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
This question already has answers here:
Different (dynamic) items height in GridLayoutManager
(2 answers)
Closed 3 years ago.
I am currently using a GridLayoutManager for a RecyclerView which displays Previews of different Articles, which have different text lengths and therefor different item heights. The question is, how can I use the full height and dont have too much spacing?
Use StaggeredGridLayoutManager!
https://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager
Try to set your layout manager like this for recyclerview.
adapter = new CustomAdapter(R.layout.layout, list, context);
final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(numberOfrows, StaggeredGridLayoutManager.HORIZONTAL);
recyclerView_sk.setHasFixedSize(true);
recyclerView_sk.addItemDecoration(new SpacesItemDecorationNew(0));//For equal distribution of columns.
recyclerView_sk.setLayoutManager(layoutManager);
recyclerView_sk.setAdapter(adapter);
SpacesItemDecorationNew
public class SpacesItemDecorationNew extends RecyclerView.ItemDecoration {
private int mItemOffset;
public SpacesItemDecorationNew(int itemOffset) {
mItemOffset = itemOffset;
}
public SpacesItemDecorationNew(#NonNull Context context, #DimenRes int itemOffsetId) {
this(context.getResources().getDimensionPixelSize(itemOffsetId));
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(mItemOffset, mItemOffset, mItemOffset, mItemOffset);
}
}
Also, you can try with this
mDashboardAdapter = new DashboardAdapter(getActivity(), mDashBoardList, imageId);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 4);
grid.setLayoutManager(mLayoutManager);
grid.addItemDecoration(new GridSpacingItemDecoration(4, 10, true));
grid.setItemAnimator(new DefaultItemAnimator());
grid.setAdapter(mDashboardAdapter);
public static 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
}
}
}
}
This is my code, Where I am displaying 2 items per row.
extends Fragment {
private RecyclerView recyclerView;
private AlbumsAdapter adapter;
private List<Album> albumList;
protected View view;
private FloatingActionButton fab;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_ebooks, container, false);
fab = (FloatingActionButton) view.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), ProductsActivity.class);
startActivity(intent);
}
});
initCollapsingToolbar();
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
albumList = new ArrayList<>();
adapter = new AlbumsAdapter(getActivity(), albumList);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
prepareAlbums();
try {
Glide.with(this).load(R.drawable.cover).into((ImageView) view.findViewById(R.id.backdrop));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
/**
* Initializing collapsing toolbar
* Will show and hide the toolbar title on scroll
*/
private void initCollapsingToolbar() {
final CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) view.findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(" ");
AppBarLayout appBarLayout = (AppBarLayout) view.findViewById(R.id.appbar);
appBarLayout.setExpanded(true);
// hiding & showing the title when toolbar expanded & collapsed
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
collapsingToolbar.setTitle(getString(R.string.app_name));
isShow = true;
} else if (isShow) {
collapsingToolbar.setTitle(" ");
isShow = false;
}
}
});
}
/**
* Adding few albums for testing
*/
private void prepareAlbums() {
int[] covers = new int[]{
R.drawable.album1,
R.drawable.album2,
R.drawable.album3,
R.drawable.album4,
R.drawable.album5,
R.drawable.album6,
R.drawable.album7,
R.drawable.album1,
R.drawable.album2,
R.drawable.album3,
R.drawable.album4};
Album a = new Album("Management..", "Donald", covers[0]);
albumList.add(a);
a = new Album("Officers search", "John.A", covers[1]);
albumList.add(a);
a = new Album("Court Security", "Carter", covers[2]);
albumList.add(a);
a = new Album("Officer DUI", "John", covers[3]);
albumList.add(a);
a = new Album("Criminal Evedence", "Larry", covers[4]);
albumList.add(a);
a = new Album("Criminal Procedure", "Larry", covers[5]);
albumList.add(a);
a = new Album("Officers DUI", "John", covers[6]);
albumList.add(a);
a = new Album("K9 Officers..", "Ken", covers[7]);
albumList.add(a);
a = new Album("Officers search", "John", covers[8]);
albumList.add(a);
a = new Album("Tactical Spanish", "Larry", covers[9]);
albumList.add(a);
adapter.notifyDataSetChanged();
}
/**
* RecyclerView item decoration - give equal margin around grid item
*/
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
}
}
}
}
/**
* Converting dp to pixel
*/
private int dpToPx(int dp) {
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
Using this line of code I am displaying 2 items in a row.
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
I want to make my recycler view responsive so that I can use my app in different screen sizes of android.
I had done this using card view where I had placed card views in a linear layout where the number of cards are fixed I had done that by creating different layouts. Now I want to change it in recycler view where my items can be increased dynamically.
Please help me to make my recycler view responsive dynmically.
Easiest way to solve your problem is to define a resource integer that you access from the code.
So for example if you want to have 2 rows on normal screens you add the following line to integers.xml in the res\values folder in res:
<integer name="number_of_grid_items">2</integer>
And if you want to have 3 items on xxxhdpi screens you add the following line to the integers.xml file in the res\values-xxxhdpi folder:
<integer name="number_of_grid_items">3</integer>
If any of those files don't exist yet, just create them that they look like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="number_of_grid_items">2</integer>
</resources>
To access those resources within you code, just change the line where you create the GridLayoutManager to:
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), getActivity().getResources().getInteger(R.integer.number_of_grid_items));
Hope that helps and please let me know if you have further questions..
Though its late to answer, but you can follow to see if this helps:
How can I make the Android RecyclerView responsive to fit the screen initially?
I use ItemDecoration to set the space between the grid RecyclerView items, and I want the space between each item to be equal.
ItemDecoration
public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpaceItemDecoration(int space) {
this.space = space;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (parent.getLayoutManager() instanceof GridLayoutManager) {
GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams();
GridLayoutManager gridLayoutManager = (GridLayoutManager) parent.getLayoutManager();
int spanSize = layoutParams.getSpanSize();
int spanIndex = layoutParams.getSpanIndex();
int totalSpanSize = gridLayoutManager.getSpanCount();
if (spanIndex == 0) {//left
outRect.left = space;
outRect.right = space / 2;
} else if (spanSize + spanIndex == totalSpanSize) {//right
outRect.right = space;
outRect.left = space / 2;
} else if (spanIndex > 0 && spanSize + spanIndex < totalSpanSize) {
outRect.left = space / 2;
outRect.right = space / 2;
}
outRect.bottom = space;
}
}
RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
item xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="90dp"
android:layout_height="90dp"
android:background="#ff6600"
android:orientation="vertical">
</LinearLayout>
Try this,
int spanCount;
final private Context mContext =YourActivity.this;
int value = activity.getResources().getConfiguration().orientation;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
recycler_view=(RecyclerView)findViewById(R.id.recycler_view);
recycler_view.setLayoutManager(new GridLayoutManager(mContext, 2));
if (value == Configuration.ORIENTATION_PORTRAIT) {
spanCount = 2;
}
else if (value == Configuration.ORIENTATION_LANDSCAPE) {
spanCount = 3;
}
int spacing_left = 50; // 50px
int spacing_top=10;
recycler_view.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing_left, spacing_top));
}
#Override
protected void onResume() {
if (value == Configuration.ORIENTATION_PORTRAIT) {
spanCount = 2;
}
else if (value == Configuration.ORIENTATION_LANDSCAPE) {
spanCount = 3;
}
super.onResume();
}
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; // spacing - column * ((1f / spanCount) * spacing)
outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount)
{ // top edge
outRect.top = spacing_top;
}
outRect.bottom = spacing_top; // 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_top; // item top
}
}
}
}
Use GridItemDecoration:
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.DimenRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class GridItemDecoration extends RecyclerView.ItemDecoration {
private int mItemOffset;
public GridItemDecoration(int itemOffset) {
mItemOffset = itemOffset;
}
public GridItemDecoration(#NonNull Context context, #DimenRes int itemOffsetId) {
this(context.getResources().getDimensionPixelSize(itemOffsetId));
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(mItemOffset, mItemOffset, mItemOffset, mItemOffset);
}
}
From your Activity:
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
................
........................
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mRecyclerView.setHasFixedSize(true);
// Grid layout manager
mLayoutManager = new GridLayoutManager(mContext, 3); // spanCount = 3 for 3 columns
mRecyclerView.setLayoutManager(mLayoutManager);
// Grid item spacing
GridItemDecoration itemDecoration = new GridItemDecoration(mContext, R.dimen.grid_item_spacing); // R.dimen.grid_item_spacing is 2dp
mRecyclerView.addItemDecoration(itemDecoration);
............
......................
}
Why don't you try to remove the code for the custom spacing, and use the grid parameters android:horizontalSpacing and android:verticalSpacing?
Add android:scaleType="fitXY" inside your item xml which will scale the image using FILL so that all items occupy same area.
CODE :
private void configViews(View view) {
int spanCount = 3; // 3 columns
int spacing = 3;
boolean includeEdge = true;
mRecyclerView = (RecyclerView) view.findViewById(R.id.rv_flower_red);
mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity().getApplicationContext(), spanCount));
mFlowerAdapter = new FlowerAdapter_grid(this);
mRecyclerView.setAdapter(mFlowerAdapter);
}
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
}
}
}
}
The core of that CODE is from https://stackoverflow.com/a/30701422/6736285
But when i use that code,
Gridlayout has padding on image's top or bottom.
As you see, there are too much vertical padding.
Question : How do i remove that padding? Please Would you let me know answer?
Here is my FlowerAdapter_grid:
public class FlowerAdapter_grid extends RecyclerView.Adapter<FlowerAdapter_grid.Holder> {
private static final Object TAG = FlowerAdapter_grid.class.getSimpleName();
private final FlowerClickListener mListener;
private List<Flower> mFlowers;
public FlowerAdapter_grid(FlowerClickListener listener) {
mFlowers = new ArrayList<>();
mListener = listener;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_grid, null, false);
return new Holder(row);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
Flower currFlower = mFlowers.get(position);
Glide.with(holder.itemView.getContext())
.load(currFlower.getImage())
.thumbnail(0.5f)
.override(300, 300)
.centerCrop()
.into(holder.mImage);
}
#Override
public int getItemCount() {
return mFlowers.size();
}
public void addFlower(Flower flower) {
mFlowers.add(flower);
notifyDataSetChanged();
}
public void clear(){
mFlowers.clear();
notifyDataSetChanged();
}
public Flower getSelectedFlower(int position) {
return mFlowers.get(position);
}
public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView mImage;
public Holder(View itemView) {
super(itemView);
mImage = (ImageView) itemView.findViewById(R.id.iv_photo);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
mListener.onClick(getLayoutPosition());
}
}
public interface FlowerClickListener {
void onClick(int position);
}
}
and
row_item_grid
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/iv_photo"
/>
</LinearLayout>
and My fragment layout
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipeContainer_red"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_flower_red"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
After trying, it returned this. What was problem?
I too faced this issue when I started working with recycler view.
Issue is the you are setting the grid as vertical scrolling grid and setting the row count to 3.
So it resizes your row_item_grid layout to fit 3 items in a row. So the issue here is you have used match parent for the height parent LinearLayout in the same Layout. but the image is 300dpx300dp which is at the center of the LinearLayout.
So that extra padding is because of your LinearLayout.
Instead you can simple have
row_item_grid.xml
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/iv_photo"
/>
Honestly you dont need parent layouts when your view consists of single layout. I didnt check your itemDecoration code though, for my knowledege, you wont even need it for vertical spacing if you follow these steps