This is my adapter class
public class GenreAdapter extends ExpandableRecyclerViewAdapter<GenreViewHolder, ArtistViewHolder> {
Context context ;
LayoutInflater inflater ;
public GenreAdapter(List<? extends ExpandableGroup> groups,Context context) {
super(groups);
this.context = context ;
inflater = LayoutInflater.from(context);
}
#Override
public GenreViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
//LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_item_genre, parent, false);
return new GenreViewHolder(view);
}
#Override
public ArtistViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_item_artist, parent, false);
return new ArtistViewHolder(view);
}
#Override
public void onBindChildViewHolder(ArtistViewHolder holder, int flatPosition, ExpandableGroup group,
int childIndex) {
final Artist artist =(Artist) group.getItems().get(childIndex);
holder.setArtistName(artist.getName());
}
#Override
public void onBindGroupViewHolder(GenreViewHolder holder, int flatPosition,
ExpandableGroup group) {
holder.setGenreTitle(group);
}
}
This is my model class
package com.nmn.expandablerecycler.utils;
import android.os.Parcel;
import android.os.Parcelable;
import com.thoughtbot.expandablerecyclerview.models.ExpandableGroup;
import java.util.List;
public class Artist implements Parcelable {
private String name;
private boolean isFavorite;
public Artist(String name, boolean isFavorite) {
this.name = name;
this.isFavorite = isFavorite;
}
protected Artist(Parcel in) {
name = in.readString();
}
public String getName() {
return name;
}
/* public String getTitle()
{
return title ;
}*/
public boolean isFavorite() {
return isFavorite;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Artist)) return false;
Artist artist = (Artist) o;
if (isFavorite() != artist.isFavorite()) return false;
return getName() != null ? getName().equals(artist.getName()) : artist.getName() == null;
}
#Override
public int hashCode() {
int result = getName() != null ? getName().hashCode() : 0;
result = 31 * result + (isFavorite() ? 1 : 0);
return result;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<Artist> CREATOR = new Creator<Artist>() {
#Override
public Artist createFromParcel(Parcel in) {
return new Artist(in);
}
#Override
public Artist[] newArray(int size) {
return new Artist[size];
}
};
}
public class Genre extends ExpandableGroup<Artist> {
public Genre(String title, List<Artist> items) {
super(title, items);
}
}
>This are my viewholder classes
public class ArtistViewHolder extends ChildViewHolder {
private TextView artistName;
public ArtistViewHolder(View itemView) {
super(itemView);
artistName = (TextView) itemView.findViewById(R.id.artist_name);
}
public void onBind(Artist artist) {
artistName.setText(artist.getName());
}
public void setArtistName (String name )
{
}
}
public class GenreViewHolder extends GroupViewHolder {
private TextView genreTitle;
public GenreViewHolder(View itemView) {
super(itemView);
genreTitle =(TextView) itemView.findViewById(R.id.genre_title);
}
public void setGenreTitle(ExpandableGroup group) {
genreTitle.setText(group.getTitle());
}
}
>this is the main activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<Artist>artists = new ArrayList<>();
for (int i = 0 ; i<6 ;i++)
{
artists.add(new Artist("naman",true));
}
ArrayList<Genre> genres = new ArrayList<>();
for (int i = 0 ; i<6 ;i++)
{
genres.add(new Genre("Sufi",artists));
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//instantiate your adapter with the list of genres
GenreAdapter adapter = new GenreAdapter(genres,this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
}
The text on the artist(child) name is not shown up . Althiugh the parent (genre text ) expands and collapses as well .Let me know how to
show the text of child (artist) item in this expandable recyclerview
Dude this might sound silly, but your setArtistName method is empty. paste this code artistName.setText(artist.getName());
The library documentation has error
public void onBind(Artist artist) {
artistName.setText(artist.getName());
}
public void setArtistName (String name )
{
}
In this snippet just change the name of method from onBind to setArtistName and remove the empty method you created.
I was also implementing com.thoughtbot.expandablerecyclerview. What I did in the same scenario was, in the custom class that is extending ExpandableGroup, I override getItems() and getItemCount() methods and provided the values which I wanted as "child"-expanded state.
Related
How do you use DiffCallback to load a newList in RecyclerView when DiffUtil ItemCallback is being used.
I would like to give the user the option to return different size lists from the database when the user selects a different size I want the RecyclerView to update.
RecyclerViewAdatper
RecyclerViewAdapter extends ListAdapter<WordEntity, RecyclerViewAdapter.ViewHolder> {
private RecyclerViewAdapter() {
super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<WordEntity> DIFF_CALLBACK = new DiffUtil.ItemCallback<WordEntiti>() {
#Override
public boolean areItemsTheSame...
#Override
public boolean areContentsTheSame...
};
#Override
public viewHolder onCreateViewHolder...
#Override
public void onVindViewHolder ...
class ViewHolder extends RecyclerView.ViewHolder ...
public void updateWordList(List<WordEntity> words) {
final WordDiffCallBack diffCallBack = new WordDiffCallBack(list???, words);
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack);
this.list???.clear();
this.addAll(words);
diffResult.dispatcheUpdatesTo(this);
}
WordsDiffCallBack
private final List<WordEntity> mOldList;
private final List<WordEntity> mNewList;
public WordsDiffCallBack(List<WordEntity> oldList, List<WordEntity> newList) {
this.mOldList = oldList;
this.mNewList = newList;
}
#Override
public int getOldListSize() {
return mOldList.size();
}
#Override
public int getNewListSize() {
return mNewList.size();
}
#Override
public boolean areItemsTheSame(int OldItemPostion, int newItemPosition) ...
#Override boolean areContentsTheSame(int oldItemPosition, int newItemPosition)...
#Override getChangePayload(int oldItemPosition, int newItemPosition) ...
}
I want the RecycelView to update automatically when the size of the list gets changed by the user. How do I call the old list from the ListAdapter and will that even update the RecyclerView
You can create a template just like shown in this video in youTube:
https://www.youtube.com/watch?v=y31fzLe2Ajw
Here is an example of adapter.
public class CartFragAdapter extends RecyclerView.Adapter<CartFragAdapter.CartFragViewHolder> {
private static final String TAG = "debinf PurchaseAdap";
private static final DiffUtil.ItemCallback<ProductsObject> DIFF_CALLBACK = new DiffUtil.ItemCallback<ProductsObject>() {
#Override
public boolean areItemsTheSame(#NonNull ProductsObject oldProduct, #NonNull ProductsObject newProduct) {
Log.i(TAG, "areItemsTheSame: old is "+oldProduct.getCode()+" ; new is "+newProduct.getCode());
return oldProduct.getCode().equals(newProduct.getCode());
}
#Override
public boolean areContentsTheSame(#NonNull ProductsObject oldProduct, #NonNull ProductsObject newProduct) {
Log.i(TAG, "areContentsTheSame: old is "+oldProduct.getPrice()+" ; new is "+newProduct.getPrice());
return oldProduct.getPrice() == newProduct.getPrice();
}
};
private AsyncListDiffer<ProductsObject> differ = new AsyncListDiffer<ProductsObject>(this, DIFF_CALLBACK);
#NonNull
#Override
public CartFragViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_purchase, parent, false);
return new CartFragViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CartFragViewHolder holder, int position) {
final ProductsObject purchaseList = differ.getCurrentList().get(position);
holder.mCode.setText(purchaseList.getCode());
holder.mPrice.setText(String.valueOf(purchaseList.getPrice()));
holder.mDescription.setText(purchaseList.getDescription());
}
#Override
public int getItemCount() {
Log.i(TAG, "getItemCount");
return differ.getCurrentList().size();
}
public void submitList(List<ProductsObject> products){
Log.i(TAG, "submitList: products.size is "+products.size());
differ.submitList(products);
}
public class CartFragViewHolder extends RecyclerView.ViewHolder {
public TextView mCode, mPrice, mDescription;
public CartFragViewHolder(#NonNull View itemView) {
super(itemView);
mCode = (TextView) itemView.findViewById(R.id.item_productCode);
mPrice = (TextView) itemView.findViewById(R.id.item_productPrice);
mDescription = (TextView) itemView.findViewById(R.id.item_productDescription);
}
}
}
In MainActivity you call adapter like this:
CartFragAdapter adapter = new CartFragAdapter();
adapter.submitList(inputData);
I hope it helps!
observe this code
here's my diffutil callback
public class MyDiffUtilCallback extends DiffUtil.Callback {
List<String> oldlist;
List<String > newlist;
public MyDiffUtilCallback(List<String> oldlist, List<String> newlist) {
this.oldlist = oldlist;
this.newlist = newlist;
}
#Override
public int getOldListSize() {
return oldlist.size();
}
#Override
public int getNewListSize() {
return newlist.size();
}
#Override
public boolean areItemsTheSame(int olditempostion, int newitemPostion) {
return olditempostion==newitemPostion;
}
#Override
public boolean areContentsTheSame(int olditempostion, int newitemPostion) {
return olditempostion==newitemPostion;
}
#Nullable
#Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
here's the recyclerview adpater which uses diffutilcallback
public class recyclerviewAdapter extends RecyclerView.Adapter<recyclerviewAdapter.Viewholder> {
List<String> datasource;
public recyclerviewAdapter(List<String> datasource) {
this.datasource = datasource;
}
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.demorow,viewGroup,false);
return new Viewholder(itemView);
}
#Override
public void onBindViewHolder(#NonNull Viewholder viewholder, int i) {
viewholder.tv_demo_data_row.setText(datasource.get(i));
}
#Override
public int getItemCount() {
return datasource.size();
}
public static class Viewholder extends RecyclerView.ViewHolder {
TextView tv_demo_data_row;
public Viewholder(#NonNull View itemView) {
super(itemView);
tv_demo_data_row=itemView.findViewById(R.id.tv_demo_data_row);
}
}
//DIFF CALLBACK STATE
public void insertdata(List<String> insertList){
/**
* Insert list insert data to list
*/
MyDiffUtilCallback diffUtilCallback = new MyDiffUtilCallback(datasource,insertList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffUtilCallback);
datasource.addAll(insertList);
diffResult.dispatchUpdatesTo(this);
}
public void updateList(List<String> newList){
/**
* update list clear old data and update new data
*/
MyDiffUtilCallback diffUtilCallback = new MyDiffUtilCallback(datasource,newList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffUtilCallback);
datasource.clear();
datasource.addAll(newList);
diffResult.dispatchUpdatesTo(this);
}}
and here i can update list in activity on button clickevent
insert_data.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//inserting the data
List<String> insertlist = new ArrayList<>(); //asign old list
for(int i=0;i<2;i++){
insertlist.add(UUID.randomUUID().toString()); // insert new list
adapter.insertdata(insertlist);
faster_recyclerview.smoothScrollToPosition(adapter.getItemCount()-1); //auto scroll to last postion
}
}
});
replace List of string with your modelclass
And in addition to the above (using DiffUtils), if you use Clicks to change RecyclerView's content, make
ViewHolder implements View.OnClickListener
and use this to set OnClickListener in onBindViewHolder
.setOnClickListener(holder);
and get your current position by
this.getAdapterPosition()
private class HistoryRecyclerAdapter extends RecyclerView.Adapter<HistoryRecyclerAdapter.ViewHolder> {
private List<HistoryEntry> entries;
HistoryRecyclerAdapter(List<HistoryEntry> entries) {
this.entries = entries;
}
public void updateContainer(List<HistoryEntry> list){
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {
#Override
public int getOldListSize() { return entries.size(); }
#Override
public int getNewListSize() { return list.size(); }
#Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return entries.get(oldItemPosition).getId()==list.get(newItemPosition).getId();
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
HistoryEntry old = entries.get(oldItemPosition);
HistoryEntry neww = list.get(newItemPosition);
return old.getExpression().equals(neww.getExpression())
&& old.getResult().equals(neww.getResult());
}
}, false);//detectMoves=true потом позволит вызвать анимацию если строка просто была перемещена
entries = list;
diffResult.dispatchUpdatesTo(this);
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
//some Views
final Button delBtn;
ViewHolder(View view){
super(view);
//some Views
delBtn = (Button) view.findViewById(R.id.delete_btn);
}
#Override
public void onClick(View v) {
switch (v.getId()){
//some cases
case R.id.delete_btn:
historyManager.delete(entries.get(this.getAdapterPosition()));
break;
}
}
}
#NonNull
#Override
public HistoryRecyclerAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_row, parent, false);
return new HistoryRecyclerAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(HistoryRecyclerAdapter.ViewHolder holder, final int position) {
//some code
holder.delBtn.setOnClickListener(holder);
}
#Override
public int getItemCount() {
return entries.size();
}
}
Early I used final int position in onBindViewHolder and don't understand what's wrong...)))
Here is snapet of my project (How to view list of my providers):
public class ProviderAdapter extends ListAdapter<Provider, RecyclerView.ViewHolder> {
private final GeneralListener<Provider> listener;
public ProviderAdapter(GeneralListener<Provider> listener) {
super(DIFF_CALLBACK);
this.listener = listener;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(ItemProviderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
((ViewHolder) holder).bind(getItem(position));
}
class ViewHolder extends RecyclerView.ViewHolder {
ItemProviderBinding binding;
public ViewHolder(ItemProviderBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void bind(Provider data) {
binding.image.setImageURI(data.img_url);
binding.txtName.setText(data.name);
binding.txtMealTypes.setText(data.meal_types);
binding.txtAddress.setText(data.address);
binding.btnBack.setOnClickListener(view -> {
listener.onClick(Actions.VIEW, data);
});
}
}
private static final DiffUtil.ItemCallback<Provider> DIFF_CALLBACK = new DiffUtil.ItemCallback<Provider>() {
#Override
public boolean areItemsTheSame(#NonNull Provider oldItem, #NonNull Provider newItem) {
return oldItem.id == newItem.id;
}
#Override
public boolean areContentsTheSame(#NonNull Provider oldItem, #NonNull Provider newItem) {
return oldItem.name.equals(newItem.name)
&& oldItem.meal_types.equals(newItem.meal_types)
&& oldItem.address.equals(newItem.address);
}
};
}
To use it:
ProviderAdapter adapter = new ProviderAdapter(new GeneralListener<Provider>() {
#Override
public void onClick(Actions action, Provider provider) {
if (action == Actions.VIEW) {
// TODO: View provider details
}
}
});
recyclerView.setAdapter(adapter);
adapter.submitList(providerList);
I have one recycler View as a parent and a recycler view inside it. I want to update all of my parent recycler view's rows, when I am selecting a row from child recycler view.
In parent recycler view It have two textviews and one recycler view. The increase class and adapter class for parent recycler view is shown below.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv = (RecyclerView)findViewById(R.id.reviews);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(mLinearLayoutManager);
Data();
adapter = new Adapterclass(countryList,MainActivity.this);
rv.setAdapter(adapter);
rv.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(),rv,new ClickListener(){
#Override
public void onClick(View view, int position) {
Log.e("position child",""+position);
adapter = new Adapterclass(position);
}
#Override
public void onLongClick(View view, int position) {
}
}));
}
Adapter class :
public class Adapterclass extends RecyclerView.Adapter<Adapterclass.MyViewHolder> {
private List<ModelMain> flist;
private List<Modelclass>carList;
Context c;
boolean set = false;
int positn;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView text,currency;
RecyclerView recycler;
public MyViewHolder(View view) {
super(view);
text = (TextView)view.findViewById(R.id.gggg);
currency= (TextView)view.findViewById(R.id.hhh);
recycler = (RecyclerView)view.findViewById(R.id.rview2);
}
}
public Adapterclass(List<ModelMain> slist, Context c){
this.flist = slist;
this.c = c;
}
#Override
public Adapterclass.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell,parent,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(Adapterclass.MyViewHolder holder, final int position) {
ModelMain fm = flist.get(position);
holder.text.setText(fm.getName());
holder.currency.setText(fm.getCurrency());
carList = new ArrayList<>();
carList = fm.getArrays();
Log.d("list",""+carList.toString());
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(c);
holder.recycler.setLayoutManager(mLinearLayoutManager);
final Adapter_Inside adapter = new Adapter_Inside(carList,c);
holder.recycler.setAdapter(adapter);
holder.recycler.addOnItemTouchListener(new RecyclerTouchListener(c,holder.recycler,new ClickListener(){
#Override
public void onClick(View view, int pos) {
ModelMain mm = flist.get(positn);
carList = new ArrayList<>();
carList = mm.getArrays();
Modelclass mv = carList.get(pos);
Log.e("valll", "" + carList.get(pos).getVal());
Boolean bool = carList.get(pos).getVal();
if(bool){
}else{
for(int i =0; i<carList.size();i++){
Modelclass cls = new Modelclass();
Boolean v = carList.get(i).getVal();
String text = carList.get(i).getText();
if(v){
cls.setVal(false);
cls.setText(text);
carList.set(i,cls);
}
}
mv.setVal(true);
set = true;
}
adapter.notifyDataSetChanged();
}
#Override
public void onLongClick(View view, int position) {
}
}));
}
public Adapterclass(int pos){
this.positn = pos;
}
private void SetAdapr() {
notifyDataSetChanged();
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context applicationContext, final RecyclerView rv, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(applicationContext, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, rv.getChildPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
#Override
public int getItemCount() {
return flist.size();
}
Model class for parent recycler view :
public class ModelMain {
String name;
String currency;
List<Modelclass> arrays ;
public ModelMain(String name, String currency, List<Modelclass> arrays) {
this.name = name;
this.currency = currency;
this.arrays = arrays;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public List<Modelclass> getArrays() {
return arrays;
}
public void setArrays(List<Modelclass> arrays) {
this.arrays = arrays;
}
}
And my child recycler view adapter class is :
public class Adapter_Inside extends RecyclerView.Adapter<Adapter_Inside.MyViewHolder> {
private List<Modelclass>carList;
Context c;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView text;
ImageView iv;
public MyViewHolder(View view) {
super(view);
text = (TextView)view.findViewById(R.id.textView);
iv = (ImageView)view.findViewById(R.id.iview);
}
}
public Adapter_Inside(List<Modelclass> slist, Context c){
this.carList = slist;
this.c = c;
}
#Override
public Adapter_Inside.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.secondcell,parent,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(Adapter_Inside.MyViewHolder holder, int position) {
Modelclass fm = carList.get(position);
holder.text.setText(fm.getText());
if(fm.getVal()){
holder.iv.setImageResource(R.drawable.ic_clear_black_18dp);
}
else{
holder.iv.setImageResource(R.drawable.ic_done_black_16dp_2x);
}
}
#Override
public int getItemCount() {
return carList.size();
}
}
And model class for child is :
public class Modelclass {
Boolean val;
String text;
public Boolean getVal() {
return val;
}
public void setVal(Boolean val) {
this.val = val;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
I couldn't retrieve parent recycler view's position when clicking any row in the child view.please help.
You can get reference to your parent RecyclerView by passing it in the Adapter contructor.
public Adapterclass(RecyclerView parent, List<ModelMain> slist, Context c){
this.flist = slist;
this.c = c;
this.recyclerView = parent;
}
Then you can use recycler parent reference and his methods to retrieve all you need
I am implementing sticky header with RecyclerView. I have three sections (i.e 3 sticky headers) and they are working fine.Now I have taken three arraylists inside each section, I have initialized these list in my adapter and I am trying to get data of these lists on basis of header id inside onBindViewHolder. But it is not giving me the full list,just one string from each list (i.e under first section--data on first position of mylist,,,under second section-- data on second position of mylist1 ---under third section-- data on third position of mylist2)
Please Help !!
Code in Context:
StickyTestAdapter
public class StickyTestAdapter extends RecyclerView.Adapter<StickyTestAdapter.ViewHolder> implements
StickyHeaderAdapter<StickyTestAdapter.HeaderHolder> {
private Context mContext;
private ArrayList<String> mylist;
private ArrayList<String> mylist1;
private ArrayList<String> mylist2;
private static int countposition;
private String HEADER_FIRIST="HEADER_FIRIST";
private String HEADER_SECOND="HEADER_SECOND";
private String HEADER_THIRD="HEADER_THIRD";
public StickyTestAdapter(Context context) {
prepareData();
prepareData1();
prepareData2();
this.mContext=context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.item_test, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
long rowType= getHeaderId(position);
Log.e("getHeaderId----",""+rowType);
if (rowType==0){
if(!mylist.equals(""))
{
Log.e("list_data----", "" + mylist.get(position));
viewHolder.item.setText(mylist.get(position));
}
else
{
Log.e("Error--0--", "" + "error");
}
} else if (rowType==1){
if(!mylist1.equals(""))
{
Log.e("list_data1----", "" + mylist1.get(position));
viewHolder.item.setText(mylist1.get(position));
}
else
{
Log.e("Error---1-", "" + "error");
}
} else if (rowType==2){
if(!mylist2.equals(""))
{
Log.e("list_data2----", "" + mylist2.get(position));
viewHolder.item.setText(mylist2.get(position));
}
else
{
Log.e("Error----2", "" + "error");
}
}
}
#Override
public int getItemCount() {
if (getHeaderId(countposition)==0){
Log.e("mylist",""+mylist.size());
return mylist.size();
}else if (getHeaderId(countposition)==1){
Log.e("mylist1",""+mylist1.size());
return mylist1.size();
}else if (getHeaderId(countposition)==2){
Log.e("mylist2",""+mylist2.size());
return mylist2.size();
}
return 0;
}
#Override
public long getHeaderId(int pos) {
return pos;
}
#Override
public HeaderHolder onCreateHeaderViewHolder(ViewGroup parent) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.header_test, parent, false);
return new HeaderHolder(view);
}
#Override
public void onBindHeaderViewHolder(HeaderHolder viewholder, int count) {
countposition=count;
if (getItemViewType(count)==0){
viewholder.headertext.setText(HEADER_FIRIST);
}else if (getItemViewType(count)==1){
viewholder.headertext.setText(HEADER_SECOND);
}else if (getItemViewType(count)==2){
viewholder.headertext.setText(HEADER_THIRD);
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
public TextView item;
public ViewHolder(View itemView) {
super(itemView);
item = (TextView)itemView.findViewById(R.id.text_item);
}
}
static class HeaderHolder extends RecyclerView.ViewHolder {
public TextView headertext;
public HeaderHolder(View itemView) {
super(itemView);
headertext = (TextView)itemView.findViewById(R.id.header_text);
}
}
#Override
public int getItemViewType(int position) {
return position;
}
public void prepareData()
{
mylist=new ArrayList<>();
mylist.add("rajendra");
mylist.add("rani");
mylist.add("rahul");
}
public void prepareData1()
{
mylist1=new ArrayList<>();
mylist1.add("ravi");
mylist1.add("vikram");
mylist1.add("rakesh");
}
public void prepareData2()
{
mylist2=new ArrayList<>();
mylist2.add("apple");
mylist2.add("ashok");
mylist2.add("vikash");
}
}
Question is quite old. But that code looks complicated to read, personally I try to not reinvent what others did quite well by creating libraries.
GitHub is full of source that you can import. Some examples: FlexibleAdapter, FastAdapter, Epoxy and others.
I have build the first one, but you can try the others as well.
With mine, having multiple views and headers with sections is quite easy, I point here the wiki page where I define the section and how to initialize it.
Along with this feature, you have a lot more functionalities that makes your life easier.
I divide arraylist into 3 section based on alphabet like contactlist.
For that i use SectionedRecyclerViewAdapter
MainActivity.java
public class MainActivity extends AppCompactActivity {
private SectionedRecyclerViewAdapter sectionAdapter;
#Override
public View onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
sectionAdapter = new SectionedRecyclerViewAdapter();
for(char alphabet = 'a'; alphabet <= 'z';alphabet++) {
List<String> contacts = getContactsWithLetter(alphabet);
if (contacts.size() > 0) {
sectionAdapter.addSection(new ContactsSection(String.valueOf(alphabet), contacts));
}
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);
return view;
}
#Override
public void onResume() {
super.onResume();
if (getActivity() instanceof AppCompatActivity) {
AppCompatActivity activity = ((AppCompatActivity) getActivity());
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setTitle(R.string.nav_example1);
}
}
private List<String> getContactsWithLetter(char letter) {
List<String> contacts = new ArrayList<>();
for (String contact : getResources().getStringArray(R.array.names_)) {
if (contact.charAt(0) == letter) {
contacts.add(contact);
}
}
return contacts;
}
private class ContactsSection extends StatelessSection {
String title;
List<String> list;
ContactsSection(String title, List<String> list) {
super(new SectionParameters.Builder(R.layout.section_ex1_item)
.headerResourceId(R.layout.section_ex1_header)
.build());
this.title = title;
this.list = list;
}
#Override
public int getContentItemsTotal() {
return list.size();
}
#Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
return new ItemViewHolder(view);
}
#Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
final ItemViewHolder itemHolder = (ItemViewHolder) holder;
String name = list.get(position);
itemHolder.tvItem.setText(name);
itemHolder.imgItem.setImageResource(name.hashCode() % 2 == 0 ? R.drawable.ic_face_black_48dp : R.drawable.ic_tag_faces_black_48dp);
itemHolder.rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), String.format("Clicked on position #%s of Section %s", sectionAdapter.getPositionInSection(itemHolder.getAdapterPosition()), title), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new HeaderViewHolder(view);
}
#Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
headerHolder.tvTitle.setText(title);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
private final TextView tvTitle;
HeaderViewHolder(View view) {
super(view);
tvTitle = (TextView) view.findViewById(R.id.tvTitle);
}
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
private final View rootView;
private final ImageView imgItem;
private final TextView tvItem;
ItemViewHolder(View view) {
super(view);
rootView = view;
imgItem = (ImageView) view.findViewById(R.id.imgItem);
tvItem = (TextView) view.findViewById(R.id.tvItem);
}
}
}
use structure similar to
public class MultiArray<T> {
List<ItemGroup> lists = new ArrayList<>();
public void addList(String headerText, List<T> list) {
lists.add(new ItemGroup(headerText, list));
}
public int itemCount() {
int count = 0;
for (ItemGroup group : lists) {
count += group.count();
}
return count;
}
public T getItem(int position) {
int count = 0;
for (ItemGroup group : lists) {
if (count + group.count() >= position) {
return group.item(position - count);
}
count += group.count();
}
return null;
}
public int getGroupIndex(int position) {
int count = 0;
int groupIndex = 0;
for (ItemGroup group : lists) {
if (count + group.count() >= position) {
return groupIndex;
}
count += group.count();
groupIndex++;
}
return -1;
}
public String getHeaderText(int position){
int count = 0;
for (ItemGroup group : lists) {
if (count + group.count() >= position) {
return group.headerText;
}
count += group.count();
}
return "";
}
class ItemGroup {
public final String headerText;
public final List<T> list;
public ItemGroup(String headerText, List<T> list) {
this.headerText = headerText;
this.list = list;
}
public int count() {
return list.size();
}
public T item(int position) {
return list.get(position);
}
}
}
you can optimize it for faster performance
I have the 2 errors , can you help me to fix them ?
this error in main activity
This is the code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
//first recycler
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(
new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
OkHttpHandler handler = new OkHttpHandler( this, new OkHttpHandler.MyInterface() {
#Override
public void myMethod(ArrayList result) {
mAdapter = new MyAdapter(result,this);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
// GridViewAdapter adapter = new GridViewAdapter(getApplicationContext(), R.layout.grid_item_layout, result);
// adapter.notifyDataSetChanged();
// mGridView.setAdapter(adapter);
}
});
and second error here in my adapter
// viewHolder.txtHeader.setText(...)
final Listitem item;
// final String name = mDataset.get(position);
item = mDataset.get(position);
viewHolder.txtHeader.setText(mDataset.get(position));
this is the full code
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<Listitem> mDataset;
Context mContext;
public class ImageViewHolder extends RecyclerView.ViewHolder {
//ImageView mImage;
public TextView txtHeader;
public TextView txtFooter;
public ImageViewHolder(View itemView) {
super (itemView);
txtHeader = (TextView) itemView.findViewById(R.id.firstLine);
txtFooter = (TextView) itemView.findViewById(R.id.secondLine);
}
}
public void add(int position, Listitem item) { //changed from string to listitem
mDataset.add(position, item);
notifyItemInserted(position);
}
public void remove(String item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<Listitem> myDataset, Context context) {
mDataset = myDataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
// set the view's size, margins, paddings and layout parameters
ImageViewHolder vh = new ImageViewHolder(v);
return vh;
}
private static final int TYPE_IMAGE = 1;
private static final int TYPE_GROUP = 2;
#Override
public int getItemViewType(int position) {
// here your custom logic to choose the view type
return position;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(RecyclerView.ViewHolder TextViewHolder, int position) {
ImageViewHolder viewHolder = (ImageViewHolder) TextViewHolder;
// viewHolder.txtHeader.setText(...)
final Listitem item;
// final String name = mDataset.get(position);
item = mDataset.get(position);
viewHolder.txtHeader.setText(mDataset.get(position));
/* viewHolder.txtFooter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
remove(item);
}
});*/
// viewHolder.txtFooter.setText("Footer: " + mDataset.get(position));
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
listitem
public class Listitem implements Parcelable {
String id;
//String name;
String url;
Listitem (Parcel in){
this.id = in.readString();
// this.name = in.readString();
this.url = in.readString();
}
Listitem( String name,String url) {
this.id = id;
this.url = url;
}
#Override
public int describeContents() {
return 0;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.id);
// dest.writeString(this.name);
dest.writeString(this.url);
}
public static final Parcelable.Creator<Listitem> CREATOR = new Parcelable.Creator<Listitem>() {
public Listitem createFromParcel(Parcel in) {
return new Listitem(in);
}
public Listitem[] newArray(int size) {
return new Listitem[size];
}
};
}
For the first error:
You need to pass a Context in the adapter constructor.
Actually this inside myMethod(ArrayList result) refers to OkHttpHandler.MyInterface not a Context.
To solve this, change mAdapter = new MyAdapter(result,this);
to mAdapter = new MyAdapter(result,YourActivityName.this);
For the second error:
mDataset.get(position) is returning a Listitem object, while you need a CharSequence (or String) object as parameter with setText() method.
You should do
viewHolder.txtHeader.setText(mDataset.get(position).getUrl());
or
viewHolder.txtHeader.setText(mDataset.get(position).getId());
i'm working baseadapter.i have custom baseadapter.i use my adapter in spinner.i have one problem.mybaseadapter's OnItemClickedListener returned all my custom class
carbon.widget.Spinner$CustomClass#535ca050s
this is a result
this is a my code
public static class CustomClass {
private String Name;
public void setName(String name)
{
this.Name=name;
}
public String getName()
{
return Name;
}
public CustomClass(String name)
{
this.Name=name;
}
}
public static class Adapter extends RecyclerView.Adapter<ViewHolder, CustomClass> {
private ArrayList<CustomClass>items=new ArrayList<>();
#Override
public CustomClass getItem(int position) {
return items.get(position);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.carbon_popup_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
super.onBindViewHolder(holder, position);
holder.tv.setText(items.get(position).getName());
Log.e("position String", items.get(position).getName() + "s");
}
#Override
public int getItemCount() {
return items.size();
}
public void setItems(ArrayList<CustomClass> items) {
this.items = items;
notifyDataSetChanged();
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public ViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.carbon_itemText);
}
}
i inserted some values in my baseadapter like this
for (int i = 0; i < 40; i++) {
CustomClass customClass = new CustomClass("item" + i);
// customClass.setName("beka" + i);
list.add(customClass);
}
Spinner day = (Spinner) findViewById(R.id.day);
day.setItems(list);
this is a my setItem method
public void setItems(ArrayList<CustomClass> items) {
popupMenu.setAdapter(defaultAdapter);
defaultAdapter.setOnItemClickedListener(onItemClickedListener);
defaultAdapter.setItems(items);
}
RecyclerView.OnItemClickedListener onItemClickedListener = new RecyclerView.OnItemClickedListener() {
#Override
public void onItemClicked(int position) {
setText(popupMenu.getAdapter().getItem(position).toString());
Log.e("position String",popupMenu.getAdapter().getItem(position).toString()+"s");
popupMenu.dismiss();
}
};
as i said i can't return my custom class's getName. how i can solve my problem? if anyone knows solution please help me
p.s
i try to rewrite this example
https://github.com/ZieIony/Carbon
in this example autor used String arrays but i want to use my Custom Array
how i can solve my problem?
popupMenu.getAdapter().getItem(position) is returning CustomClass in your, and since you didn't override toString() in it, you are seeing the default implementation of Object.toString(). For the sake oh showing the name you could override it and return name. E.g.
#Override
public String toString() {
return name != null ? name : "no name set";
}
Alternatively you can simply call popupMenu.getAdapter().getItem(position).getName()
E.g.
CustomClass objectAtPos = popupMenu.getAdapter().getItem(position);
if (objectAtPos != null) {
setText(objectAtPos.getName());
Log.e("position String",objectAtPos.getName()+"s");
}
popupMenu.dismiss();