AresProductions AresProductions - 1 year ago 50
Android Question

RecyclerView.Adapter shows 2 item in a single row (how to change that)

So I am working on a project which already has some code in it. I would like to change the way my adapter items are being shown.

Right now there are 2 items in each row. What I want to do is have only 1 item in each row.

Here is an image of how the image layout is right now.


2 items appear in each row while I need only 1 to appear.

Here is the code on the xmls

Item xml

<com.inthessaloniki.cityguide.view.SelectorRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_poi_list_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="@drawable/selector_clickable_item_bg_inverse">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ImageView
android:id="@+id/fragment_poi_list_item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"/>

</RelativeLayout>




List xml

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">

<LinearLayout
android:id="@+id/container_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<android.support.v7.widget.RecyclerView
android:id="@+id/fragment_poi_list_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="vertical"
android:background="@color/global_bg_front" />

<com.google.android.gms.ads.AdView
android:id="@+id/fragment_poi_list_adview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:adUnitId="@string/admob_unit_id_poi_list"
app:adSize="BANNER" />

</LinearLayout>

<include
layout="@layout/placeholder_progress"
android:id="@+id/container_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />

<include
layout="@layout/placeholder_offline"
android:id="@+id/container_offline"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />

<include
layout="@layout/placeholder_empty"
android:id="@+id/container_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />




ListAdapter code

public class SubCategoryListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
public static final int VIEW_TYPE_POI = 1;
public static final int VIEW_TYPE_IMAGE_FOOTER = 2;
public static final int VIEW_TYPE_FOOTER = 3;

private List<CategoryModel> mPoiList;
private List<Object> mFooterList;
private PoiViewHolder.OnItemClickListener mListener;
private int mGridSpanCount;
private Location mLocation;
private boolean mAnimationEnabled = true;
private int mAnimationPosition = -1;
private ImageLoader mImageLoader = ImageLoader.getInstance();
private DisplayImageOptions mDisplayImageOptions;
private ImageLoadingListener mImageLoadingListener;


//Ares
private long mCategory;


public SubCategoryListAdapter(List<CategoryModel> poiList, List<Object> footerList, PoiViewHolder.OnItemClickListener listener, int gridSpanCount, Location location, long category)
{
mPoiList = poiList;
mFooterList = footerList;
mListener = listener;
mGridSpanCount = gridSpanCount;
mLocation = location;

//Ares
mCategory = category;

// image caching options
mDisplayImageOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(android.R.color.transparent)
.showImageForEmptyUri(R.drawable.placeholder_photo)
.showImageOnFail(R.drawable.placeholder_photo)
.cacheInMemory(true)
.cacheOnDisk(true)
.displayer(new SimpleBitmapDisplayer())
.build();
mImageLoadingListener = new AnimateImageLoadingListener();
}


@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());

// inflate view and create view holder
View view;
if(viewType== VIEW_TYPE_POI)
{
if(mCategory == -4) {
view = inflater.inflate(R.layout.fragment_poi_list_item_home, parent, false);
}
else
{
view = inflater.inflate(R.layout.fragment_poi_list_item, parent, false);
}
return new PoiViewHolder(view, mListener, mImageLoader, mDisplayImageOptions, mImageLoadingListener, mCategory);
}
else if(viewType==VIEW_TYPE_IMAGE_FOOTER)
{
view = inflater.inflate(R.layout.footer_image_layout, parent, false);
return new ImageFooterViewHolder(view, mListener);
}
else if(viewType==VIEW_TYPE_FOOTER)
{
view = inflater.inflate(R.layout.fragment_poi_list_footer, parent, false);
return new FooterViewHolder(view);
}
else
{
throw new RuntimeException("There is no view type that matches the type " + viewType);
}
}


@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
{
// bind data
if(viewHolder instanceof PoiViewHolder)
{
// entity
CategoryModel poi = mPoiList.get(getPoiPosition(position));

// render view
if(poi != null)
{
((PoiViewHolder) viewHolder).bindData(poi, mLocation, mCategory);
}
}
else if(viewHolder instanceof FooterViewHolder)
{
// entity
Object object = mFooterList.get(getFooterPosition(position));

// render view
if(object != null)
{
((FooterViewHolder) viewHolder).bindData(object);
}
}

// set item margins
setItemMargins(viewHolder.itemView, position);

// set animation
setAnimation(viewHolder.itemView, position);
}


@Override
public int getItemCount()
{
int size = 0;
if(mPoiList !=null) size += mPoiList.size();
if(mFooterList!=null) size += mFooterList.size();
if(mFooterList!=null) size += 1; //ImageFooter
return size;
}

@Override
public int getItemViewType(int position)
{
int pois = mPoiList.size();
int footers = mFooterList.size();
int imageFooter = 1;

if(position < pois) return VIEW_TYPE_POI;
else if(position < pois+imageFooter) return VIEW_TYPE_IMAGE_FOOTER;
else if(position < pois+imageFooter+footers) return VIEW_TYPE_FOOTER;
else return -1;
}

public int getPoiCount()
{
if(mPoiList !=null) return mPoiList.size();
return 0;
}


public int getFooterCount()
{
if(mFooterList!=null) return mFooterList.size();
return 0;
}


public int getPoiPosition(int recyclerPosition)
{
return recyclerPosition;
}


public int getFooterPosition(int recyclerPosition)
{
return recyclerPosition - getPoiCount();
}


public int getRecyclerPositionByPoi(int poiPosition)
{
return poiPosition;
}


public int getRecyclerPositionByFooter(int footerPosition)
{
return footerPosition + getPoiCount();
}


public void refill(List<CategoryModel> poiList, List<Object> footerList, PoiViewHolder.OnItemClickListener listener, int gridSpanCount, Location location)
{
mPoiList = poiList;
mFooterList = footerList;
mListener = listener;
mGridSpanCount = gridSpanCount;
mLocation = location;
notifyDataSetChanged();
}


public void stop()
{

}


public void setLocation(Location location)
{
mLocation = location;
}


public void setAnimationEnabled(boolean animationEnabled)
{
mAnimationEnabled = animationEnabled;
}


private void setAnimation(final View view, int position)
{
if(mAnimationEnabled && position>mAnimationPosition)
{
view.setScaleX(0f);
view.setScaleY(0f);
view.animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(300)
.setInterpolator(new DecelerateInterpolator());

mAnimationPosition = position;
}
}


private void setItemMargins(View view, int position)
{
int height = 0;
if(mCategory != -4)
height = (int) CityGuideApplication.getContext().getResources().getDimension(R.dimen.fragment_poi_list_recycler_item_size);
int marginTop = 0;

if(position<mGridSpanCount)
{
TypedArray a = CityGuideApplication.getContext().obtainStyledAttributes(null, new int[]{android.R.attr.actionBarSize}, 0, 0);
marginTop = (int) a.getDimension(0, 0);
a.recycle();

if(mCategory != -4)
height += marginTop;
}

ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
marginParams.setMargins(0, marginTop, 0, 0);

ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if(mCategory != -4)
layoutParams.height = height;
}


public static final class PoiViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
private TextView nameTextView;
private TextView distanceTextView;
private ImageView imageView;
private OnItemClickListener mListener;
private ImageLoader mImageLoader;
private DisplayImageOptions mDisplayImageOptions;
private ImageLoadingListener mImageLoadingListener;


public interface OnItemClickListener
{
public void onItemClick(View view, int position, long id, int viewType);
}


public PoiViewHolder(View itemView, OnItemClickListener listener, ImageLoader imageLoader, DisplayImageOptions displayImageOptions, ImageLoadingListener imageLoadingListener, long category)
{
super(itemView);
mListener = listener;
mImageLoader = imageLoader;
mDisplayImageOptions = displayImageOptions;
mImageLoadingListener = imageLoadingListener;

// set listener
itemView.setOnClickListener(this);

// find views
if(category == -4)
{
Log.d("Category Status: ", String.valueOf(category));
}
else
{
nameTextView = (TextView) itemView.findViewById(R.id.fragment_poi_list_item_name);
distanceTextView = (TextView) itemView.findViewById(R.id.fragment_poi_list_item_distance);

distanceTextView.setVisibility(View.GONE);
}
imageView = (ImageView) itemView.findViewById(R.id.fragment_poi_list_item_image);



}


@Override
public void onClick(View view)
{
mListener.onItemClick(view, getPosition(), getItemId(), getItemViewType());
}


public void bindData(CategoryModel subCategory, Location location, long category)
{
if(category == -4)
{

}
else
{
nameTextView.setText(subCategory.getName());
}
mImageLoader.displayImage(subCategory.getImage2(), imageView, mDisplayImageOptions, mImageLoadingListener);
// if(location!=null)
// {
// LatLng myLocation = new LatLng(location.getLatitude(), location.getLongitude());
// LatLng poiLocation = new LatLng(poi.getLatitude(), poi.getLongitude());
// String distance = LocationUtility.getDistanceString(LocationUtility.getDistance(myLocation, poiLocation), LocationUtility.isMetricSystem());
// distanceTextView.setText(distance);
// distanceTextView.setVisibility(View.VISIBLE);
// }
// else
// {
// distanceTextView.setVisibility(View.GONE);
// }
}
}

public static final class ImageFooterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private PoiViewHolder.OnItemClickListener mListener;


public interface OnItemClickListener {
public void onItemClick(View view, int position, long id, int viewType);
}


public ImageFooterViewHolder(View itemView, PoiViewHolder.OnItemClickListener listener) {
super(itemView);
mListener = listener;

// set listener
itemView.setOnClickListener(this);
}


@Override
public void onClick(View view) {
mListener.onItemClick(view, getPosition(), getItemId(), getItemViewType());
}


public void bindData(PoiModel poi, Location location) {

}
}


public static final class FooterViewHolder extends RecyclerView.ViewHolder
{
public FooterViewHolder(View itemView)
{
super(itemView);
}


public void bindData(Object object)
{
// do nothing
}
}
}


GritLayout

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration
{
private int mSpacing;


public GridSpacingItemDecoration(int spacingPixelSize)
{
mSpacing = spacingPixelSize;
}


@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView recyclerView, RecyclerView.State state)
{
super.getItemOffsets(outRect, view, recyclerView, state);

int position = recyclerView.getChildPosition(view);
int spanCount = getSpanCount(recyclerView);
int itemCount = recyclerView.getAdapter().getItemCount();

// top offset
if(position < spanCount)
{
outRect.top = mSpacing;
}
else
{
outRect.top = mSpacing/2;
}

// bottom offset
if(itemCount%spanCount == 0 && position >= itemCount - spanCount)
{
outRect.bottom = mSpacing;
}
else if(itemCount%spanCount != 0 && position >= itemCount - itemCount%spanCount)
{
outRect.bottom = mSpacing;
}
else
{
outRect.bottom = mSpacing/2;
}

// left offset
if(position%spanCount == 0)
{
outRect.left = mSpacing;
}
else
{
outRect.left = mSpacing/2;
}

// right offset
if(position%spanCount == spanCount-1)
{
outRect.right = mSpacing;
}
else
{
outRect.right = mSpacing/2;
}
}


private int getSpanCount(RecyclerView recyclerView)
{
if(recyclerView.getLayoutManager() instanceof GridLayoutManager)
{
GridLayoutManager gridLayoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
return gridLayoutManager.getSpanCount();
}
else
{
throw new IllegalStateException(this.getClass().getSimpleName() + " can only be used with a " + GridLayoutManager.class.getSimpleName());
}
}
}


I don't think that the problem is in the XML files. It must be somewhere in the code. I just can't track it down and modify it... :S

I've been searching for hours.

Thanks in advance!!!

Answer Source

You have not posted the piece of code where you are setting LayoutManager to your RecyclerView.

Is seems you are using GridLayoutManager:

RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(context, 2);
myRecyclerView.setLayoutManager(mLayoutManager);

Try changing it to LinearLayoutManager:

RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);    
myRecyclerView.setLayoutManager(mLayoutManager);