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
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
}
}
}
}
I'm trying to implement something like a view pager wizard (two steps in a activity), in which I'm trying to implement a recycler view inside of a view pager. The first view/layout in the pager would consist of a recycler view, in which the user would be allowed to select an area from a list, on selecting the area the pager would call the second view/layout for the user to enter additional information.
Now, no matter what I do, recycler view won't show up inside the view pager. I think I've messed up my layouts. Any help? Thanks
AreaActivity
public class AreaActivity extends AppCompatActivity implements View.OnClickListener {
private ViewPager viewPager;
private ViewPagerAdapter adapter;
private RecyclerView recyclerView;
private TechAreaAdapter tAdapter;
private List<TechAreas> _techAreaList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tech_areas);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewPagerVertical);
adapter = new ViewPagerAdapter();
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
_techAreaList = new ArrayList<>();
tAdapter = new TechAreaAdapter(this, _techAreaList);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 3);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(3, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(tAdapter);
// row click listener
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
TechAreas techAreas = _techAreaList.get(position);
//onclick move to the next view in the pager - viewPager.setCurrentItem(1);
}
#Override
public void onLongClick(View view, int position) {
}
}));
getTechAreaList();
}
#Override
public void onClick(View view) {
switch (view.getId()) {
//Test
}
}
private void getTechAreaList() {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<List<TechAreas>> call = apiService.getTechAreaList();
call.enqueue(new Callback<List<TechAreas>>() {
#Override
public void onResponse(Call<List<TechAreas>> call, Response<List<TechAreas>> response) {
_techAreaList.clear();
_techAreaList.addAll(response.body());
tAdapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<TechAreas>> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Unable to fetch json: " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
/**
* 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()));
}
class ViewPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
public Object instantiateItem(View collection, int position) {
int resId = 0;
switch (position) {
case 0:
resId = R.id.layout_choose_area;
break;
case 1:
resId = R.id.layout_add_info;
break;
}
return findViewById(resId);
}
}}
Main Layout
<android.support.design.widget.CoordinatorLayout
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"
tools:mContext="AreaActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_tech_areas" />
</android.support.design.widget.CoordinatorLayout>
Content Layout
<android.support.constraint.ConstraintLayout
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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_tech_areas">
<CustomViewPager
android:id="#+id/viewPagerVertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/layout_choose_area"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</android.support.constraint.ConstraintLayout>
<LinearLayout
android:id="#+id/layout_add_info"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/colorPrimary"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView/>
<EditText
android:id="#+id/input_interest"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:hint="#string/lbl_enter_interest"
android:padding="10dp" />
</LinearLayout>
</CustomViewPager>
</android.support.constraint.ConstraintLayout>
Custom View Pager
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}}
I am trying to add some space between every list item in the recycler view but it's not working accordingly for some reasons. I've been following a guide to implement this solution but cannot seem to find the answer. It's adding the space but the space is placed over the next list item.
This is what my recyclerview currently looks like:-
My RecyclerView
Here are my classes:-
divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="40dp"
android:height="40dp" />
<solid
android:color="#color/white"/>
</shape>
SimpleDividerItemDecoration class
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
public SimpleDividerItemDecoration(Context context) {
mDivider = ContextCompat.getDrawable(context,R.drawable.divider);
}
#Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
onCreate method in my Fragment class where I get the objects
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_popular_picks, container, false);
recyclerView = (RecyclerView)v.findViewById(R.id.popular_pick_recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getContext()));
getPopularPost();
return v;
}
add following line code, hope it will resolve your issue
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
and here the class GridSpacingItemDecoration
/**
* 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()));
}
If you need just to add space consider adding it to item layout(.xml file for your list item). This can be some padding for each item in RecyclerView.
If you need to add just regular divider consider using default DividerItemDecoration. It available from appcompat library 25.0.0.
You can add it in this way:
mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
mLayoutManager.getOrientation());
recyclerView.addItemDecoration(mDividerItemDecoration);
Why not just add custom view on the bottom of the recyclerview item with the background you've created?
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.