Activity doesn't show RecyclerView - Databinding - android

I tried databinding with RecyclerView, but my main_activity doesn't show the RecyclerView Content for my Objects. I dont know where the point of failure is.
Thanks for any advice.
Here my simple Code
class: User
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class: UserAdapter
public class UserAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Activity host;
private ArrayList<User> items;
public UserAdapter(Activity activity, ArrayList<User> items) {
this.host = activity;
this.items = items;
Log.i("UserAdapterName", items.get(0).getName().toString()); //log shows Gordon
}
#Override
public UserAdapter.ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// inflate layout and retrieve binding
ListItemsBinding binding = DataBindingUtil.inflate(host.getLayoutInflater(),
R.layout.list_items, parent, false);;
return new ItemViewHolder(binding);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
User item = items.get(position);
ItemViewHolder itemViewHolder = (ItemViewHolder)holder;
itemViewHolder.bindItem(item);
}
#Override
public int getItemCount() {
return items.size();
}
static class ItemViewHolder extends RecyclerView.ViewHolder {
ListItemsBinding binding;
ItemViewHolder(ListItemsBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void bindItem(User item) {
binding.setUser(item);
binding.executePendingBindings();
}
}
}
class: MainActivity
public class MainActivity extends AppCompatActivity {
private ArrayList<User> userList = new ArrayList<User>();
private ActivityMainBinding binding;
private UserAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
fillData();
adapter = new UserAdapter(MainActivity.this,userList);
binding.recycler.setAdapter(adapter);
}
private void fillData() {
userList.add(new User("Gordon", 26));
userList.add(new User("Dick", 34));
userList.add(new User("Ivan",20));
}
}
layout: activity_main
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Activity Text"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
layout: list_items
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="user"
type="de.bp2go.recgo.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{user.name}"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black"
tools:text="Name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{user.age}"
android:textColor="#android:color/black"
tools:text="Age" />
</LinearLayout>
</layout>

For me it looks like You forgot to set proper LayoutManager for RecyclerView.
Missing line for vertical list:
binding.recycler.setLayoutManager(new LinearLayoutManager(this));

public class MainActivity extends AppCompatActivity {
private ArrayList<User> userList = new ArrayList<User>();
private ActivityMainBinding binding;
private UserAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fillData();
recycler = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
recycler.setLayoutManager(manager);
adapter = new UserAdapter(MainActivity.this,userList);
recycler.setAdapter(adapter);
}
private void fillData() {
userList.add(new User("Gordon", 26));
userList.add(new User("Dick", 34));
userList.add(new User("Ivan",20));
}
}
public class UserAdapter extends RecyclerView.Adapter<ItemViewHolder.ViewHolder> {
private Activity host;
private ArrayList<User> items;
LayoutInflater inflator;
public UserAdapter(Activity activity, ArrayList<User> items) {
this.host = activity;
this.items = items;
Log.i("UserAdapterName", items.get(0).getName().toString()); //log shows Gordon
inflator=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public UserAdapter.ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// inflate layout and retrieve binding
View view =inflator.inflate(R.layout.list_items, parent,false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
User item = items.get(position);
ItemViewHolder itemViewHolder = (ItemViewHolder)holder;
itemViewHolder.bindItem(item);
}
#Override
public int getItemCount() {
return items.size();
}
static class ItemViewHolder extends RecyclerView.ViewHolder {
ListItemsBinding binding;
ItemViewHolder(ListItemsBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void bindItem(User item) {
binding.setUser(item);
binding.executePendingBindings();
}
}
}

Related

Recyler view vertical with nested recycler view and card listener

So, I have a recycler view and the items inside a recyclerview are dynamic. That is there can be one card or two cards. as you can see the recyclerview index 1 has only one item, whereas recyclerview index 0 has two cards. How can I achieve this?
You can do that using nested recylerview means reacyclerview insiderecyclerview.
You can follow the below way.
activity_main.xml
<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">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity implements YourInterface {
RecyclerView recyclerView;
private CategoryAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpRecyclerView();
// add your data to your arraylist and pass it to setInfoToAdapter method like below
ArrayList<CategoryItem> categoryItemList = new ArrayList<>();
categoryItemList.add(new CategoryItem("Item Title"))
categoryList.add(new Category("Section Title", categoryItemList));
setInfoToAdapter(categoryList );
}
//setup recycler view
private void setUpRecyclerView() {
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
private void setInfoToAdapter(List<Category> categoryList) {
adapter = new CategoryAdapter(this, categoryList, this); // here last parameters for your inteface
recyclerView.setAdapter(adapter);
}
#Override
public void doSomething(String title) {
// here you can do whatever you want it tigger when item adapter call this method.
}
}
CategoryAdapter.java
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.CategorySectionHolder> {
private Context context;
private List<Category> categoryList;
private YourInterface interface;
public CategoryAdapter(Context context, List<Category> categoryList,YourInterface interface) {
this.context = context;
this.categoryList = categoryList;
this.interface = interface; //
}
#Override
public CategorySectionHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_section_row, parent, false);
return new CategorySectionHolder(view);
}
#Override
public void onBindViewHolder(CategorySectionHolder holder, int position) {
final Category category = categoryList.get(position);
final String categoryName = category.getName();
holder.tvSectionLabel.setText(categoryName);
// data set for your items
final ArrayList<CategoryItem> itemList =category.getItems(); // here you got your item list for each category
// adapter for your items
final CategoryItemAdapter adapter;
adapter = new CategoryItemAdapter(context, itemList, interface);
//recycler view for items
holder.rvCategoryItems.setHasFixedSize(true);
holder.rvCategoryItems.setNestedScrollingEnabled(false);
holder.rvCategoryItems.setLayoutManager(new LinearLayoutManager(context));
holder.rvCategoryItems.setAdapter(adapter);
}
#Override
public int getItemCount() {
return categoryList.size();
}
public static class CategorySectionHolder extends RecyclerView.ViewHolder {
TextView tvSectionLabel;
RecyclerView rvCategoryItems;
public CategorySectionHolder(View itemView) {
super(itemView);
// initialize your views here
tvSectionLabel = itemView.findViewById(R.id.tvSectionLabel);
rvCategoryItems = itemView.findViewById(R.id.rvCategoryItem);
}
}
}
And category_section_row design for CategoryAdapter which have a recyclerview.
category_section_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="#dimen/_5sdp">
<TextView
android:id="#+id/tvSectionLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Label"
android:layout_alignParentLeft="true"
android:textStyle="bold"
android:textColor="#android:color/darker_gray"
android:textSize="#dimen/_14ssp" />
<!-- recycler view for items -->
<android.support.v7.widget.RecyclerView
android:id="#+id/rvCategoryItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tvSectionLabel"
android:layout_marginTop="#dimen/_5sdp" />
</RelativeLayout>
And Adapter for items
CategoryItemAdapter.java
public class CategoryItemAdapter extends RecyclerView.Adapter<CategoryItemAdapter.CategoryItemsHolder> {
private Context context;
private List<CategoryItem> itemModels;
private YourInterface interface;
public CategoryItemAdapter(Context context, List<CategoryItem> itemModels,YourInterface interface) {
this.context = context;
this.itemModels = itemModels;
this.interface = interface;
}
#Override
public CategoryItemsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_item_row, parent, false);
return new CategoryItemsHolder(view);
}
#Override
public void onBindViewHolder(final CategoryItemsHolder holder, final int position) {
holder.itemName.setText(itemModels.get(position).getTitle());
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// here you can do whatever you want to click of item cardview.
// here you call method of your interface
interface.doSomething("Hello from item adapter")
}
});
}
#Override
public int getItemCount() {
return itemModels.size();
}
public static class CategoryItemsHolder extends RecyclerView.ViewHolder {
TextView itemName;
CardView cardView
public CategoryItemsHolder(View itemView) {
super(itemView);
// initialize your views here.
itemName = itemView.findViewById(R.id.tvItemNameCategory);
cardView = itemView.findViewById(R.id.cardView);
}
}
}
category_item_row.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:id="#+id/cardView"
app:cardBackgroundColor="#color/black"
app:cardCornerRadius="#dimen/_3sdp"
app:cardElevation="#dimen/_3sdp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tvItemNameCategory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:fontFamily="sans-serif"
android:padding="#dimen/_5sdp"
android:text="#string/app_name"
android:textColor="#color/white"
android:textSize="#dimen/_14ssp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--Your other view goes there-->
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
And finally, your Model class should be like the following.
Category.java
public class Category{
private String name;
private ArrayList<CategoryItems> items;
public Category(String name, ArrayList<CategoryItems> items) {
this.name = name;
this.items = items;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
public ArrayList<CategoryItems> getItems() {
return items;
}
public void setItems(ArrayList<CategoryItems> items) {
this.items= items;
}
public class CategoryItems{
private String title;
public Category(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title= title;
}
}
}
Update:
create an interface like that
interface YourInterface{
public void doSomething(String title); //here you can use parameters as you want
}
Now you have to implement this interface in YourActivit in this case in MainActivity.
And pass instance of MainActivity to CategoryAdapter then CategoryItemAdapter. see these classes I have updated.
In Recycler adaptre in onCreateViewHolder add if else or switch case for multiple ui layouts
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == LAYOUT_TYPE_ONE) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type_one, parent, false);
return new FeedViewHolder(layoutView);
} else {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type_two, parent, false);
return new FeedViewHolder(layoutView);
}
}
you can use notifyDataSetChange(); on your adapter to update recycler every

Recycler View Not Showing Items [duplicate]

This question already has answers here:
ReyclerView isn't working
(6 answers)
Closed 4 years ago.
I have been making an app that uses a RecyclerView but its not showing any thing..why contents of the recycler view have not been showing up.my codes are bellow
activity_history.xml
<LinearLayout
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:context=".HistoryActivity"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:id="#+id/layout">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/historyRecyclerView"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.NestedScrollView>
HistoryActivity.java
public class HistoryActivity extends AppCompatActivity {
private RecyclerView mHistoryRecyclerView;
private RecyclerView.Adapter mHistoryAdapter;
private RecyclerView.LayoutManager mHistoryLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
Toast.makeText(this, "dddd", Toast.LENGTH_SHORT).show();
mHistoryRecyclerView = (RecyclerView) findViewById(R.id.historyRecyclerView);
mHistoryRecyclerView.setNestedScrollingEnabled(false);
mHistoryRecyclerView.setHasFixedSize(true);
mHistoryLayoutManager = new LinearLayoutManager(HistoryActivity.this);
mHistoryRecyclerView.setLayoutManager(mHistoryLayoutManager);
mHistoryAdapter = new HistoryAdapter(getDataSetHistory(), HistoryActivity.this);
mHistoryRecyclerView.setAdapter(mHistoryAdapter);
HistoryObject obj=new HistoryObject("12345");
resultsHistory.add(obj);
mHistoryAdapter.notifyDataSetChanged();
}
private ArrayList resultsHistory = new ArrayList<HistoryObject>();
private List<HistoryObject> getDataSetHistory() {
return resultsHistory;
}
}
HistoryAdapter.java
public class HistoryAdapter extends RecyclerView.Adapter<HistoryViewHolders> {
private List<HistoryObject> itemList;
private Context context;
public HistoryAdapter(List<HistoryObject> itemList, Context context) {
this.itemList = itemList;
this.context = context;
Toast.makeText(context,itemList.size()+"" , Toast.LENGTH_SHORT).show();
}
#NonNull
#Override
public HistoryViewHolders onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history, null, false);
HistoryViewHolders rcv = new HistoryViewHolders(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(#NonNull HistoryViewHolders holder, int position) {
holder.rideId.setText(itemList.get(position).getRideId());
Toast.makeText(context, holder.rideId.getText().toString(), Toast.LENGTH_SHORT).show();
}
#Override
public int getItemCount() {
return 0;
}
}
HistoryObject
package com.example.ikramkhan.insta.historyRecyclerView;
public class HistoryObject {
private String rideId;
public HistoryObject(String rideId) {
this.rideId = rideId;
}
public String getRideId() {
return rideId;
}
public void setRideId(String rideId) {
this.rideId = rideId;
}
}
HistoryViewHolders.java
public class HistoryViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView rideId;
public HistoryViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
rideId = (TextView) itemView.findViewById( R.id.rideId);
}
#Override
public void onClick(View v) {
}
}
You're returning zero for the itemCount, therefore your adapter thinks you don't have any items. Try this in your adapter:
#Override
public int getItemCount() {
return itemList.size();
}

Nested Recycler view is laggy while scrolling for the first time

Here, I have two recyclerview that has parentRecyclerViewAdapter and childRecyclerViewAdapter. Parent adapter has LinearLayoutManager.VERTICAL layout manager whereas Clild adapter has GridLayoutManager(mContext, 2) layout manager with itemDecoration.
When scrolling for the first time the RecyclerView scrolling is laggy and once the data is viewed the scrolling is smooth. Until the app instance is not completely removed the scrolling will be smooth and when the app reinitiate the scrolling is laggy again.
Please help me out to figure out this BUG!!
ParentRecyclerViewAdapter
public class RecyclerViewDataAdapter extends RecyclerView.Adapter<RecyclerViewDataAdapter.ItemRowHolder> {
private ArrayList<SectionDataModel> dataList;
private Context mContext;
private RecyclerListItemClick onListClick;
public RecyclerViewDataAdapter(Context context, ArrayList<SectionDataModel> dataList) {
this.dataList = dataList;
this.mContext = context;
onListClick = (RecyclerListItemClick) context;
}
#Override
public ItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
return new ItemRowHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row_template_section, null));
}
#Override
public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {
ArrayList<SingleTemplateModel> templateModelArrayList = dataList.get(i).getTemplateModelArrayList();
String sectionName = dataList.get(i).getHeaderTitle();
itemRowHolder.itemTitle.setText(sectionName);
TemplateChooserAdapter itemListDataAdapter = new TemplateChooserAdapter(mContext, templateModelArrayList , dataList.get(i).getHeaderTitle());
itemRowHolder.recycler_view_list.setAdapter(itemListDataAdapter);
}
#Override
public int getItemCount() {
return (null != dataList ? dataList.size() : 0);
}
public class ItemRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView itemTitle;
private RecyclerView recycler_view_list;
private ItemRowHolder(View view) {
super(view);
this.itemTitle = view.findViewById(R.id.itemTitle);
this.recycler_view_list = view.findViewById(R.id.recycler_view_list);
this.recycler_view_list.setOnClickListener(this);
this.recycler_view_list.setHasFixedSize(true);
this.recycler_view_list.setLayoutManager(new GridLayoutManager(mContext, 2));
this.recycler_view_list.addItemDecoration(new SpacesItemDecoration(2 , 25 , false));
}
#Override
public void onClick(View v) {
onListClick.onRecyclerItemClicked(dataList.get(getAdapterPosition()).getHeaderTitle());
}
}
}
ChildRecyclerAdapter
public class TemplateChooserAdapter extends RecyclerView.Adapter<TemplateChooserAdapter.ViewHolder> {
private static final String TAG = TemplateChooserAdapter.class.getSimpleName();
private Context context;
private ArrayList<SingleTemplateModel> templateModelArrayList;
private OnTemplatesListClicked onListClick;
public TemplateChooserAdapter(Context context, ArrayList<SingleTemplateModel> templateModelArrayList, String sectionName) {
this.context = context;
this.templateModelArrayList = templateModelArrayList;
onListClick = (OnTemplatesListClicked) context;
AppUtils.showLog(TAG, "CorporateUserAdapter");
}
#Override
public TemplateChooserAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.single_row_template_chooser, parent, false)
);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.templateView.setImageResource(templateModelArrayList.get(position).getImage());
}
#Override
public int getItemCount() {
return templateModelArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView templateView;
public ViewHolder(View itemView) {
super(itemView);
templateView = itemView.findViewById(R.id.template_view);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
templateModelArrayList.get(getAdapterPosition()).setShowIndicator(true);
onListClick.onTemplateClick(templateModelArrayList.get(getAdapterPosition())); // TODO send model when item clicked
}
}
}
Activity.java
private void recyclerViewJob() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
RecyclerViewDataAdapter adapter = new RecyclerViewDataAdapter(this, allSampleData);
recyclerView.setAdapter(adapter);
}
SectionDataModel.java
public class SectionDataModel {
private String headerTitle;
private ArrayList<SingleTemplateModel> templateModelArrayList;
public SectionDataModel() {
}
public SectionDataModel(String headerTitle, ArrayList<SingleTemplateModel> templateModelArrayList) {
this.headerTitle = headerTitle;
this.templateModelArrayList = templateModelArrayList;
}
public String getHeaderTitle() {
return headerTitle;
}
public void setHeaderTitle(String headerTitle) {
this.headerTitle = headerTitle;
}
public ArrayList<SingleTemplateModel> getTemplateModelArrayList() {
return templateModelArrayList;
}
public void setTemplateModelArrayList(ArrayList<SingleTemplateModel> templateModelArrayList) {
this.templateModelArrayList = templateModelArrayList;
}
}
SingleTemplateModel.java
public class SingleTemplateModel {
private String title;
private String skuName;
private int image;
private boolean showIndicator;
public SingleTemplateModel(String title, String skuName, int image, boolean showIndicator) {
this.title = title;
this.skuName = skuName;
this.image = image;
this.showIndicator = showIndicator;
}
public String getSkuName() {
return skuName;
}
public void setSkuName(String skuName) {
this.skuName = skuName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public boolean isShowIndicator() {
return showIndicator;
}
public void setShowIndicator(boolean showIndicator) {
this.showIndicator = showIndicator;
}
}
single_row_template_section.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:orientation="vertical"
android:paddingTop="30dp"
android:clickable="true"
android:focusable="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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:text="Sample title"
android:textColor="#color/white"
android:textSize="20sp"
android:textStyle="bold"
android:paddingLeft="5dp"
android:paddingBottom="10dp"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal" />
</LinearLayout>
single_row_template_chooser.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="280dp"
card_view:cardElevation="6dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/template_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#mipmap/model_9" />
</RelativeLayout>
</android.support.v7.widget.CardView>
I think you can try to lazy load your images from resources. There are libraries like Picasso or Glide that will help you with that.
So it may look like this:
Picasso:
import com.squareup.picasso.Picasso;
...
public class TemplateChooserAdapter extends RecyclerView.Adapter<TemplateChooserAdapter.ViewHolder> {
...
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Picasso.with(holder.itemView.getContext()).load(templateModelArrayList.get(position).getImage()).into(holder.templateView);
}
...
}

RecyclerView Item Click Listener with DataBinding

I have implemented recycler view with data binding using a baseadapter which handles all the binding of any layout item.
I have tried to implement per item click listener using method reference and Listener bindings, but I couldn't do that.
Here is my code. Can you give me a sample which is the simple way to detect every single item of the recycler view and I want to add click listener for every single item for different purposes. Thanks.
MyBaseAdapter
public abstract class MyBaseAdapter extends RecyclerView.Adapter<MyBaseAdapter.MyViewHold> {
public class MyViewHold extends RecyclerView.ViewHolder implements View.OnClickListener {
public ViewDataBinding binding;
Context context;
public MyViewHold(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
context = binding.getRoot().getContext();
binding.getRoot().setOnClickListener(this);
}
// Here BR.pojo must be matched to layout variable name
//our layout variable was
/*
<variable
name="pojo"
type="com.durbinlabs.databinding.POJO"
/>
*/
public void bind(Object obj) {
binding.setVariable(BR.pojo, obj);
binding.setVariable(BR.food, obj);
binding.executePendingBindings();
}
#Override
public void onClick(View view) {
// for all view
}
}
#Override
public MyViewHold onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, getLayoutIdForType(viewType)
, parent, false);
return new MyBaseAdapter.MyViewHold(binding);
}
#Override
public void onBindViewHolder(MyViewHold holder, int position) {
holder.bind(getDataAtPosition(position));
Log.d("click", "" + holder.getItemId());
}
public abstract Object getDataAtPosition(int position);
public abstract int getLayoutIdForType(int viewType);}
my pojo class
public class POJO extends BaseObservable {
int img;
String name;
public POJO(int img) {
this.img = img;
}
public void setImg(int img) {
this.img = img;
}
public int getImg() {
return img;
}
public POJO(int img, String name) {
this.img = img;
this.name = name;
}
#Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}}
recycler view row layout (per item)
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="pojo"
type="com.durbinlabs.databinding.POJO" />
</data>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginRight="6dip"
android:contentDescription="TODO"
android:onClick="#{handlers::imgClick}"
android:src="#mipmap/ic_launcher" />
<TextView
android:layout_width="fill_parent"
android:layout_height="26dip"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_toRightOf="#id/icon"
android:ellipsize="marquee"
android:maxLines="1"
android:text="#{pojo.name}"
android:textColor="#android:color/black"
android:textSize="12sp" />
</RelativeLayout>
Adapter
public class Adapter extends MyBaseAdapter {
private List<POJO> itemList;
Context context;
public Adapter(List<POJO> itemList) {
this.itemList = itemList;
}
public Adapter(List<POJO> itemList, Context context) {
this.itemList = itemList;
this.context = context;
}
#Override
public Object getDataAtPosition(int position) {
return itemList.get(position);
}
#Override
public int getLayoutIdForType(int viewType) {
return R.layout.rowlayout;
}
#Override
public int getItemCount() {
return itemList.size();
}}
Try this in your adapter class not base adapter
holder.binding.getRoot().findViewById(R.id.icon).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show();
}
}
);

How save the state of RecyclerView row item?

I have a recyclerview which populates data from SQL database. Now each row in the recyclerview has a seekbar which when moved displays it's progress in a textview inside the same row. The problem is when I scroll the recyclerview up or down then return back to the first changed row, the seekbar is returned to its default position. How can I make it save the new position ? In normal activities/fragments I use lifecycle methods as "onPause" to save/restore the state. Here we have onAttachedToRecyclerView, I think it should solve my problem but I don't know exactly how.
EDIT : here is a full simple app files which I'm working on to test this problem.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private List<Score> scoreList = new ArrayList<>();
private RecyclerView recyclerView;
private MyAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mAdapter = new MyAdapter(scoreList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
prepareScoreData();
}
private void prepareScoreData() {
Score score = new Score("title", 5);
scoreList.add(score);
for(int i= 0; i<1000; i++){
score = new Score("title", 5);
scoreList.add(score);
}
mAdapter.notifyDataSetChanged();
}
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Score> scoresList;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title, scoreView;
SeekBar seekbar;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
scoreView = (TextView) view.findViewById(R.id.score);
seekbar = (SeekBar) view.findViewById(R.id.seekbar);
}
}
public MyAdapter(List<Score> scoresList) {
this.scoresList = scoresList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final Score score = scoresList.get(position);
holder.title.setText(score.getTitle());
if (!score.getProgressed()) {
holder.seekbar.setProgress(0) ;
} else {
holder.seekbar.setProgress(score.getSeekbarProgress());
}
holder.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
holder.scoreView.setText(String.valueOf(i));
score.setSeekbarProgress(i);
score.setProgressed(true);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
#Override
public int getItemCount() {
return scoresList.size();
}
}
Score class
public class Score {
private String title;
int seekbarProgress;
boolean progressed;
public Score() {
}
public Score(String title,int seekbarProgress) {
this.title = title;
this.seekbarProgress = seekbarProgress;
}
public void setProgressed(boolean progressed) {
this.progressed = progressed;
}
public void setTitle(String title) {
this.title = title;
}
public void setSeekbarProgress(int seekbarProgress) {
this.seekbarProgress = seekbarProgress;
}
public String getTitle() {
return title;
}
public int getSeekbarProgress() {
return seekbarProgress;
}
public boolean getProgressed() {
return progressed;
}
}
MainActivity_Layout
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.moaness.tut_recyclerview.MainActivity">
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="60dp"
android:paddingBottom="60dp"
android:layout_marginBottom="10dp"
android:clickable="true"
android:background="#f2f2f2"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:text="title"
android:textColor="#color/title"
android:textSize="16dp"
android:paddingTop="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/score"
android:text="score"
android:layout_below="#+id/title"
android:textSize="16dp"
android:paddingBottom="16dp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/score"
android:id="#+id/seekbar"
/>
</RelativeLayout>
If you are using recyclerview you need to maintain states of each row, means if you are checking using a condition(i.e. if) at any stage of recyclerview item(in recyclerview adapter class) then you need to handle else as well. I can send you a code snippet so you can have a good idea for recyclerview adapter.
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder> {
List<ViewHolder> holders = new ArrayList<ViewHolder>();
private ArrayList<ContactModel> arrayList = new ArrayList<>();
private Context context;
private LayoutInflater inflater;
public void clearAdapter() {
arrayList.clear();
notifyDataSetChanged();
}
public ContactsAdapter(Context context, ArrayList<ContactModel> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
public void setList(ArrayList<ContactModel> listSearch) {
this.arrayList = listSearch;
notifyItemRangeChanged(0, listSearch.size());
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.custom_row_for_contacts, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
holders.add(viewHolder);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final ContactModel current = this.arrayList.get(position);
holder.txtDriverName.setText(current.getName());
holder.txtDriverPhone.setText(current.getPhone());
if (current.getImgUrl().length() > 0) {
String urlLicenceThumb = UrlEndPoints.parentUrl + current.getImgUrl();
Glide.with(context).load(urlLicenceThumb).error(R.mipmap.ic_launcher).into(holder.imgDriver);
} else {
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imgDriver);
}
}
public void delete(int position) {
arrayList.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
return (null != arrayList ? arrayList.size() : 0);
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView txtDriverName, txtDriverPhone;
private CircleImageView imgDriver;
private Button btnInvite;
private CheckBox chkAdd;
public ViewHolder(View itemView) {
super(itemView);
chkAdd = (CheckBox) itemView.findViewById(R.id.chkAdd);
imgDriver = (CircleImageView) itemView.findViewById(R.id.imgDriver);
txtDriverName = (TextView)itemView.findViewById(R.id.txtDriverName);
txtDriverPhone = (TextView) itemView.findViewById(R.id.txtDriverPhone);
btnInvite = (Button) itemView.findViewById(R.id.btnInvite);
}
}
}

Categories

Resources