How to Build a Horizontal Listview With Recyclerview

How to build a horizontal ListView with RecyclerView

Is there a better way to implement this now with RecyclerView now?

Yes.

When you use a RecyclerView, you need to specify a LayoutManager that is responsible for laying out each item in the view. The LinearLayoutManager allows you to specify an orientation, just like a normal LinearLayout would.

To create a horizontal list with RecyclerView, you might do something like this:

LinearLayoutManager layoutManager
= new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false);

RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);

Android Horizontal RecyclerView scroll Direction

Assuming you use LinearLayoutManager in your RecyclerView, then you can pass true as third argument in the LinearLayoutManager constructor.

For example:

mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true));

If you are using the StaggeredGridLayoutManager, then you can use the setReverseLayout method it provides.

Howto create horizontal scrolling RecyclerView with Cards

To have horizontal scrolling need to set horizontal layout manager to your recycler view programmatically like below.

 recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
recyclerView.setAdapter(yourAdapter);

Android Horizontal RecyclerView with ListViews as items

Try this:-

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

private static RecyclerViewAdapter adapter;
private LinearLayoutManager layoutManager;
private static RecyclerView recyclerView;
private List<Book> data = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

getNextItems();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new RecyclerViewAdapter(data, this, recyclerView);
recyclerView.setAdapter(adapter);
}

private void getNextItems() {
int itemCount = data.size();
for (int i = itemCount; i <= itemCount + 5; i++) {
Book book = new Book();
book.title = "Title " + i;
book.author = "Author " + i;
book.description = "Description " + i;
data.add(book);
}
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="12dp"
tools:context="com.example.sabari.recyclerviewsample.MainActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</LinearLayout>

RecyclerViewAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
* Created by sabari on 2/8/2016.
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter {
public static final String Name = "Name";
public static final String Author = "Author";
public static final String Description = "Description";
private List<Book> dataSet;
private Context context;

private final int VIEW_ITEM = 1;

// The minimum amount of items to have below your current scroll position before loading more.

public RecyclerViewAdapter(List<Book> data, Context context, RecyclerView recyclerView) {
this.dataSet = data;
this.context = context;
}

public class MyViewHolder extends RecyclerView.ViewHolder {
ListView listView;

public MyViewHolder(View itemView) {
super(itemView);
listView = (ListView) itemView.findViewById(R.id.listview);
}
}

@Override
public int getItemCount() {
return dataSet.size();
}

@Override
public int getItemViewType(int position) {
return position;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.book_layout, parent, false);

vh = new MyViewHolder(v);
return vh;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MyViewHolder) {
// Binding Views...
ArrayList<HashMap> list = new ArrayList<HashMap>();
for (Book book : dataSet) {
HashMap hashMap = new HashMap();
hashMap.put(Name, book.title);
hashMap.put(Author, book.author);
hashMap.put(Description, book.description);
list.add(hashMap);
}

ListViewAdapter adapter = new ListViewAdapter(context, list);
((MyViewHolder) holder).listView.setAdapter(adapter);

}
}
}

ListViewAdapter.java (Ref: http://www.technotalkative.com/android-multi-column-listview)

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;

/**
* Created by sabari on 2/13/2016.
*/
public class ListViewAdapter extends BaseAdapter {
public static final String Name = "Name";
public static final String Author = "Author";
public static final String Description = "Description";
public ArrayList<HashMap> list;
Context context;

public ListViewAdapter(Context context, ArrayList<HashMap> list) {
super();
this.context = context;
this.list = list;
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

private class ViewHolder {
TextView name;
TextView author;
TextView description;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub

// TODO Auto-generated method stub
ViewHolder holder;
LayoutInflater inflater = LayoutInflater.from(context);

if (convertView == null) {
convertView = inflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.author = (TextView) convertView.findViewById(R.id.author);
holder.description = (TextView) convertView.findViewById(R.id.description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}

HashMap map = list.get(position);
holder.name.setText(map.get(Name).toString());
holder.author.setText(map.get(Author).toString());
holder.description.setText(map.get(Description).toString());

return convertView;
}
}

Book.java

   public class Book {
String title;
String author;
String description;
}

book_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_margin="2dp"
android:background="@drawable/border"
android:gravity="center"
android:orientation="vertical"
android:padding="5dp">

<ListView
android:id="@+id/listview"
android:layout_width="250dp"
android:layout_height="match_parent" />

</LinearLayout>

row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
android:weightSum="4">

<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />

<TextView
android:id="@+id/author"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />

<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center" />

</LinearLayout>

Custom drawable - border.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#2B91B4" />
</shape>

horizontal recycler view with horizontal scroll

Step: 1

Create two Model Classes like below.

package-name-here;


public class SingleItemModel {


private String name;
private String url;
private String description;


public SingleItemModel() {
}

public SingleItemModel(String name, String url) {
this.name = name;
this.url = url;
}


public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}


}

  1. Create the other model class SectionDataModel.java

    package-name-here;;

    import java.util.ArrayList;


    public class SectionDataModel {



    private String headerTitle;
    private ArrayList<SingleItemModel> allItemsInSection;


    public SectionDataModel() {

    }
    public SectionDataModel(String headerTitle, ArrayList<SingleItemModel> allItemsInSection) {
    this.headerTitle = headerTitle;
    this.allItemsInSection = allItemsInSection;
    }



    public String getHeaderTitle() {
    return headerTitle;
    }

    public void setHeaderTitle(String headerTitle) {
    this.headerTitle = headerTitle;
    }

    public ArrayList<SingleItemModel> getAllItemsInSection() {
    return allItemsInSection;
    }

    public void setAllItemsInSection(ArrayList<SingleItemModel> allItemsInSection) {
    this.allItemsInSection = allItemsInSection;
    }


    }

3. Step: 2

Create an Activity with RecyclerView to show the list in vertical order.

package-name-here;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;

import com.pratap.gplaystore.adapters.RecyclerViewDataAdapter;
import com.pratap.gplaystore.models.SectionDataModel;
import com.pratap.gplaystore.models.SingleItemModel;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

private Toolbar toolbar;


ArrayList<SectionDataModel> allSampleData;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

toolbar = (Toolbar) findViewById(R.id.toolbar);

allSampleData = new ArrayList<SectionDataModel>();

if (toolbar != null) {
setSupportActionBar(toolbar);
toolbar.setTitle("G PlayStore");

}


createDummyData();


RecyclerView my_recycler_view = (RecyclerView) findViewById(R.id.my_recycler_view);

my_recycler_view.setHasFixedSize(true);

RecyclerViewDataAdapter adapter = new RecyclerViewDataAdapter(this, allSampleData);

my_recycler_view.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

my_recycler_view.setAdapter(adapter);


}

public void createDummyData() {
for (int i = 1; i <= 5; i++) {

SectionDataModel dm = new SectionDataModel();

dm.setHeaderTitle("Section " + i);

ArrayList<SingleItemModel> singleItem = new ArrayList<SingleItemModel>();
for (int j = 0; j <= 5; j++) {
singleItem.add(new SingleItemModel("Item " + j, "URL " + j));
}

dm.setAllItemsInSection(singleItem);

allSampleData.add(dm);

}
}
}
  • Create an XML Layout for the above activity class

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="8dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />


<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />


</LinearLayout>

Step: 3

Now Create an Adapter Class for the recyclerView in the MainActivity.

RecyclerViewDataAdapter.java

package-name-here.adapters;


import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.pratap.gplaystore.R;
import com.pratap.gplaystore.models.SectionDataModel;

import java.util.ArrayList;

public class RecyclerViewDataAdapter extends RecyclerView.Adapter<RecyclerViewDataAdapter.ItemRowHolder> {

private ArrayList<SectionDataModel> dataList;
private Context mContext;

public RecyclerViewDataAdapter(Context context, ArrayList<SectionDataModel> dataList) {
this.dataList = dataList;
this.mContext = context;
}

@Override
public ItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, null);
ItemRowHolder mh = new ItemRowHolder(v);
return mh;
}

@Override
public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {

final String sectionName = dataList.get(i).getHeaderTitle();

ArrayList singleSectionItems = dataList.get(i).getAllItemsInSection();

itemRowHolder.itemTitle.setText(sectionName);

SectionListDataAdapter itemListDataAdapter = new SectionListDataAdapter(mContext, singleSectionItems);

itemRowHolder.recycler_view_list.setHasFixedSize(true);
itemRowHolder.recycler_view_list.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
itemRowHolder.recycler_view_list.setAdapter(itemListDataAdapter);


itemRowHolder.btnMore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


Toast.makeText(v.getContext(), "click event on more, "+sectionName , Toast.LENGTH_SHORT).show();



}
});


/* Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
}

@Override
public int getItemCount() {
return (null != dataList ? dataList.size() : 0);
}

public class ItemRowHolder extends RecyclerView.ViewHolder {

protected TextView itemTitle;

protected RecyclerView recycler_view_list;

protected Button btnMore;



public ItemRowHolder(View view) {
super(view);

this.itemTitle = (TextView) view.findViewById(R.id.itemTitle);
this.recycler_view_list = (RecyclerView) view.findViewById(R.id.recycler_view_list);
this.btnMore= (Button) view.findViewById(R.id.btnMore);


}

}

}
  • Now create an xml Layout file for the above adapter class.

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"

android:background="?android:selectableItemBackground"
android:orientation="vertical"
android:padding="5dp">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp">


<TextView
android:id="@+id/itemTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_toLeftOf="@+id/btnMore"
android:text="Sample title"
android:textColor="@android:color/black"
android:textSize="18sp" />

<Button
android:id="@+id/btnMore"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:theme="@style/MyButton"
android:text="more"
android:textColor="#FFF" />


</RelativeLayout>

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_list"
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_gravity="center_vertical"
android:orientation="horizontal" />


</LinearLayout>

Step: 4

Now , In order to make a horizontal RecyclerView , we need create a layout and Adapter class for each row.

list_single_card.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:cardCornerRadius="5dp"
app:cardUseCompatPadding="true"
>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="0dp"
android:background="?android:selectableItemBackground"
android:orientation="vertical">

<ImageView
android:id="@+id/itemImage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:scaleType="fitCenter"
android:src="@drawable/android" />


<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/itemImage"
android:gravity="center"
android:padding="5dp"
android:text="Sample title"
android:textColor="@android:color/black"
android:textSize="18sp" />


</LinearLayout>

</android.support.v7.widget.CardView>
  • Finally, The Adapter Class for Horizontal RecyclerView

SectionListDataAdapter.java

package-name-here.adapters;


import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.pratap.gplaystore.R;
import com.pratap.gplaystore.models.SingleItemModel;

import java.util.ArrayList;

public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {

private ArrayList<SingleItemModel> itemsList;
private Context mContext;

public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList) {
this.itemsList = itemsList;
this.mContext = context;
}

@Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_single_card, null);
SingleItemRowHolder mh = new SingleItemRowHolder(v);
return mh;
}

@Override
public void onBindViewHolder(SingleItemRowHolder holder, int i) {

SingleItemModel singleItem = itemsList.get(i);

holder.tvTitle.setText(singleItem.getName());


/* Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
}

@Override
public int getItemCount() {
return (null != itemsList ? itemsList.size() : 0);
}

public class SingleItemRowHolder extends RecyclerView.ViewHolder {

protected TextView tvTitle;

protected ImageView itemImage;


public SingleItemRowHolder(View view) {
super(view);

this.tvTitle = (TextView) view.findViewById(R.id.tvTitle);
this.itemImage = (ImageView) view.findViewById(R.id.itemImage);


view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


Toast.makeText(v.getContext(), tvTitle.getText(), Toast.LENGTH_SHORT).show();

}
});


}

}

}

How to achieve recyclerview with horizontal list but vertical scrolling android

You can use recyclerview but if you want to do this in a quick way then use this library:

https://github.com/2dxgujun/AndroidTagGroup

How to use:

Add this on your gradle file:

dependencies {
compile 'me.gujun.android.taggroup:library:1.4@aar'
}

Add this on your xml file:

<me.gujun.android.taggroup.TagGroup
android:id="@+id/tag_group"
style="@style/TagGroup" />

Add this on your java/kotlin file

TagGroup mTagGroup = (TagGroup) findViewById(R.id.tag_group);
mTagGroup.setTags(new String[]{"Tag1", "Tag2", "Tag3"});

RecyclerView Horizontal Scrollview example How to create horizontal recyclerview ? Horizontal scrollview example

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(linearLayoutManager);

Android - How to create Right-to-Left Horizontal-ListView?

RecyclerView helped me out (instead of horizontal-list-view) {thanX to @user2641570}.

accordding to documentation:

public LinearLayoutManager (Context context, int orientation, boolean
reverseLayout)

Parameters context Current context, will be used to access resources.

orientation Layout orientation. Should be HORIZONTAL or VERTICAL.

reverseLayout When set to true, layouts from end to start.

so I just declare LinearLayoutManager as follows:

LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, true);

and everything is OK.



Related Topics



Leave a reply



Submit