Hướng dẫn tạo Horizontal RecyclerView giống như trên app Play Store.
Đầu tiên mở file Build gradle lên thêm các phụ thuộc sau:
compile 'com.android.support:recyclerview-v7:25.1.1' compile 'com.android.support:cardview-v7:25.1.1'
1.Tạo Model SingleItemModel.java
Model này có tác dụng lưu trữ dữ liệu của các đối tượng con.
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; } }
2. Tạo đối tượng SectionDataModel.jva
Đối tượng này dùng để lưu dữ liệu của một section. Nghĩa là 1 section sẽ gồm có một Tiêu đề và nhiều đối tượng con bên trong.
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. Tạo file list_item.xml
File này là giao diện của 1 section.
<?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="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="more" android:background="@color/colorPrimary" 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>
4. Tạo tiếp file list_single_card.xml
File này dùng hiện thị một đối tượng con trong section.
<?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>
5. Ở activity_main.xml thêm một recyclerview như sau:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.lynkdev.horizontalrecyclerview.MainActivity"> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/my_recycler_view"/> </RelativeLayout>
6. Tạo SectionListDataAdapter.java như sau
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()); } @Override public int getItemCount() { return (null != itemsList ? itemsList.size() : 0); } public class SingleItemRowHolder extends RecyclerView.ViewHolder { private TextView tvTitle; private ImageView itemImage; private 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(); } }); } } }
7. Tạo MyDataAdapter.java như sau:
public class MyDataAdapter extends RecyclerView.Adapter<MyDataAdapter.ItemRowHolder> { private ArrayList<SectionDataModel> dataList; private Context mContext; public MyDataAdapter(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); return new ItemRowHolder(v); } @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.recycler_view_list.setNestedScrollingEnabled(false); 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(); } }); } @Override public int getItemCount() { return (null != dataList ? dataList.size() : 0); } public class ItemRowHolder extends RecyclerView.ViewHolder { private TextView itemTitle; private RecyclerView recycler_view_list; private Button btnMore; private 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); } } }
8. Quay lại MainActivity.java để thiết lập các Adapter
public class MainActivity extends AppCompatActivity { ArrayList<SectionDataModel> allSampleData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); allSampleData = new ArrayList<SectionDataModel>(); createDummyData(); RecyclerView myRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); myRecyclerView.setHasFixedSize(true); MyDataAdapter adapter = new MyDataAdapter(this, allSampleData); myRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); myRecyclerView.setAdapter(adapter); } //Tạo dữ liệu 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); } } }
Done tiến hành chạy app kiểm tra.
Link GitHub
Bài viết được Edit từ android-pratap.blogspot.com