I have got two lists, cart and promos. I want both to be displayed in a single viewholder. Is there any way I can do it? this is how I did, but it is not working.
public class CartAdapter extends BaseAdapter {
ArrayList<Cart> list1;
Context context;
public CartAdapter(Context context, ArrayList<Cart> list) {
this.context = context;
this.list1 = list;
}
#Override
public int getCount() {
return list1.size();
}
#Override
public Object getItem(int position) {
return list1.get(position);
}
#Override
public long getItemId(int position) {
return list1.get(position).getProductId();
}
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
final ViewHolder holder;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.cart_item, parent, false);
holder = new ViewHolder(row);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Cart cart = list.get(position);
final Promos promo = databaseHandler.getPromosForCart(cart);
holder.tvTitle.setText(cart.getProductName());
holder.tvPrice.setText(cart.getPrice());
holder.etQuantity.setText(cart.getQuantity());
holder.tvPromotion.setVisibility(View.GONE);
if(cart.hasPromotion){
final ViewHolder holder2;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.cart_item, parent, false);
holder2 = new ViewHolder(row);
row.setTag(holder);
} else {
holder2 = (ViewHolder) row.getTag();
}
if(promo.type().equals("type1"){
holder2.tvTitle.setText(promo.getProductName());
holder2.tvPrice.setVisibility(View.GONE);
holder2.etQuantity.setVisibility(View.GONE);
holder2.tvPromotion.setText(promo.getPromoDetails());
}else{
holder2.tvTitle.setText(promo.getProductName());
holder2.tvPrice.setVisibility(View.GONE);
holder2.etQuantity.(promo.getQuantity());
holder2.etQuantity.setEnabled(false);
holder2.tvPromotion.setText(promo.getPromoDetails());
}
}
}
Class ViewHolder{
.....
ViewHolder(View v){}
}
}
I searched but all answers I got was about using two layouts, and using only one data list. Please help me.
Related
I want to convert Listview to RecyclerView in my app, I tried to convert code but stucked at getView method, can any one explain how to use this getView code in Recylcer view.
Adapter for ListView CardAdapter.java
public class CardAdapter extends ArrayAdapter<CardDataModel> {
private Context context;
List<CardDataModel> cards;
SharedPreference sharedPreference;
public CardAdapter(Context context, List<CardDataModel> cards) {
super(context, R.layout.card_list_item, cards);
this.context = context;
this.cards = cards;
sharedPreference = new SharedPreference();
}
private class ViewHolder {
TextView CardNameTxt;
TextView CardDescTxt;
TextView CardPriceTxt;
ImageView favoriteImg;
}
#Override
public int getCount() {
return cards.size();
}
#Override
public CardDataModel getItem(int position) {
return cards.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.card_list_item, null);
holder = new ViewHolder();
holder.CardNameTxt = (TextView) convertView
.findViewById(R.id.txt_crd_name);
holder.CardDescTxt = (TextView) convertView
.findViewById(R.id.txt_crd_desc);
holder.CardPriceTxt = (TextView) convertView
.findViewById(R.id.txt_crd_no);
holder.favoriteImg = (ImageView) convertView
.findViewById(R.id.imgbtn_favorite);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
CardDataModel card = (CardDataModel) getItem(position);
holder.CardNameTxt.setText(card.getName());
holder.CardDescTxt.setText(card.getDescription());
holder.CardPriceTxt.setText(card.getPrice() + " ");
/*If a product exists in shared preferences then set heart_red drawable
* and set a tag*/
if (checkFavoriteItem(card)) {
holder.favoriteImg.setImageResource(R.drawable.heart_red);
holder.favoriteImg.setTag("red");
} else {
holder.favoriteImg.setImageResource(R.drawable.heart_grey);
holder.favoriteImg.setTag("grey");
}
return convertView;
}
public boolean checkFavoriteItem(CardDataModel checkCard) {
boolean check = false;
List<CardDataModel> favorites = sharedPreference.getFavorites(context);
if (favorites != null) {
for (CardDataModel card : favorites) {
if (card.equals(checkCard)) {
check = true;
break;
}
}
}
return check;
}
#Override
public void add(CardDataModel card) {
super.add(card);
cards.add(card);
notifyDataSetChanged();
}
#Override
public void remove(CardDataModel card) {
super.remove(card);
cards.remove(card);
notifyDataSetChanged();
}
}
converted somecode like this in RecyclerView Adapter ... CardRvAdapter.java
public class CardRvAdapter extends RecyclerView.Adapter<CardRvAdapter.MyViewHolder> {
private Context context;
List<CardDataModel> cards;
SharedPreference sharedPreference;
public CardRvAdapter(Context context, List<CardDataModel> cards) {
this.context = context;
this.cards = cards;
sharedPreference = new SharedPreference(); }
#Override
public int getItemCount() {
return cards.size();
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
// on create view holder code
View view;
LayoutInflater mInflater = LayoutInflater.from(context);
view = mInflater.inflate(R.layout.card_list_item, viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
//on bind view holder code
myViewHolder.CardPriceTxt.setText(cards.get(i).getPrice());
myViewHolder.CardNameTxt.setText(cards.get(i).getName());
myViewHolder.CardDescTxt.setText(cards.get(i).getDescription());
if (checkFavoriteItem(card)) {
myViewHolder.favoriteImg.setImageResource(R.drawable.heart_red);
myViewHolder.favoriteImg.setTag("red");
} else {
myViewHolder.favoriteImg.setImageResource(R.drawable.heart_grey);
myViewHolder.favoriteImg.setTag("grey");
} }
// checking for favotites in shared preferences
public boolean checkFavoriteItem(CardDataModel checkCard) {
boolean check = false;
List<CardDataModel> favorites = sharedPreference.getFavorites(context);
if (favorites != null) {
for (CardDataModel card : favorites) {
if (card.equals(checkCard)) {
check = true;
break;
}
}
}
return check;
}
#Override
public void add(CardDataModel card) {
super.add(card);
cards.add(card);
notifyDataSetChanged();
}
#Override
public void remove(CardDataModel card) {
super.remove(card);
cards.remove(card);
notifyDataSetChanged();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView CardNameTxt;
TextView CardDescTxt;
TextView CardPriceTxt;
ImageView favoriteImg;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
this.CardDescTxt = (TextView) itemView.findViewById(R.id.txt_crd_desc);
this.CardNameTxt = (TextView) itemView.findViewById(R.id.txt_crd_name);
this.CardPriceTxt = (TextView) itemView.findViewById(R.id.txt_crd_no);
this.favoriteImg = (ImageView) itemView.findViewById(R.id.imgbtn_favorite);
}}}
The problem part..
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.card_list_item, null);
holder = new ViewHolder();
holder.CardNameTxt = (TextView) convertView
.findViewById(R.id.txt_crd_name);
holder.CardDescTxt = (TextView) convertView
.findViewById(R.id.txt_crd_desc);
holder.CardPriceTxt = (TextView) convertView
.findViewById(R.id.txt_crd_no);
holder.favoriteImg = (ImageView) convertView
.findViewById(R.id.imgbtn_favorite);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
CardDataModel card = (CardDataModel) getItem(position);
holder.CardNameTxt.setText(card.getName());
holder.CardDescTxt.setText(card.getDescription());
holder.CardPriceTxt.setText(card.getPrice() + " ");
/*If a product exists in shared preferences then set heart_red drawable
* and set a tag*/
if (checkFavoriteItem(card)) {
holder.favoriteImg.setImageResource(R.drawable.heart_red);
holder.favoriteImg.setTag("red");
} else {
holder.favoriteImg.setImageResource(R.drawable.heart_grey);
holder.favoriteImg.setTag("grey");
}
return convertView;
}
How to modify this code and where to add this checkFavItem, add , and remove methods..suggest me , i am new to android development.
Finishing RecyclerView Code
// specify the row layout file and click for each row
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(listItemLayout, parent, false);
ViewHolder myViewHolder = new ViewHolder(view);
return myViewHolder;
}
// load data in each row element
#Override
public void onBindViewHolder(final ViewHolder holder, final int listPosition) {
TextView item = holder.item;
item.setText(itemList.get(listPosition).getName());
}
I am displaying a listview in which, the row item has two textview. The second textview is for the name of companies and the first textview is for the starting letter of the companies. How this can be achieved ? Need help !!
public class ExampleAdapter extends BaseAdapter {
Context context;
ArrayList<ExamplePojo> items = new ArrayList<>();
public ExampleAdapter(Context context, ArrayList<ExamplePojo> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return items.indexOf(items.get(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null){
convertView = inflater.inflate(R.layout.example_row_item, null);
holder = new ViewHolder();
holder.txtSentence = (TextView) convertView.findViewById(R.id.txtSentence);
holder.txtInitialLetter = (TextView) convertView.findViewById(R.id.txtInitialLetter);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
final ExamplePojo pojo = items.get(position);
holder.txtSentence.setText(pojo.getSentence());
holder.txtInitialLetter.setText(pojo.getSentence().charAt(0));
return convertView;
}
public class ViewHolder{
TextView txtSentence, txtInitialLetter;
}
}
Here is code for showing first character in first textview and complete name in other textview.Also put below lines in if(convertView== null) block
final ExamplePojo pojo = items.get(position);
holder.txtSentence.setText(pojo.getSentence());
holder.txtInitialLetter.setText(pojo.getSentence().substring(0, 1));
I want to use ViewHolder pattern in ListView (I know about RecyclerView but I want it in ListView!!!).
I created it but I noticed that convertView in getView() is always null. Each call getView(). What am I doing wrong?
public class ScheduleListAdapter extends BaseAdapter {
private LayoutInflater lInflater;
private List<ScheduleSubject> scheduleListItems;
public ScheduleListAdapter(Context context, List<ScheduleSubject> scheduleListItems) {
this.scheduleListItems = scheduleListItems;
lInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return scheduleListItems.size();
}
#Override
public Object getItem(int position) {
return scheduleListItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private static class ViewHolder {
TextView name, place;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = lInflater.inflate(R.layout.schedule_item_show, parent, false);
viewHolder = new ViewHolder();
viewHolder.name = (TextView) convertView.findViewById(R.id.schedule_item_name_textView);
viewHolder.place = (TextView) convertView.findViewById(R.id.schedule_item_place_textView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
ScheduleSubject scheduleListItem = getScheduleListItem(position);
viewHolder.number.setText(String.valueOf(scheduleListItem.getLessonNumber()));
viewHolder.name.setText(scheduleListItem.getName());
viewHolder.place.setText(scheduleListItem.getPlace());
return convertView;
}
public ScheduleSubject getScheduleListItem(int position) {
return ((ScheduleSubject) getItem(position));
}
}
try replacing this line
ViewHolder viewHolder;
with this one :
Holder viewHolder;
and this one :
viewHolder = (ViewHolder) convertView.getTag();
with this one :
viewHolder = (Holder) convertView.getTag();
Whats wrong with this adapter, when i scroll down i see repeated rows at the bottom and then when scroll up again i see also repeated rows at the top that were not exist before, and the rest of Data items does not appear
the adapter:
public class ClassesListViewAdapter extends BaseAdapter {
private Context mContext;
ArrayList<String> Data = new ArrayList<>();
public ClassesListViewAdapter(Context context, ArrayList<String> data) {
Data = data;
mContext = context;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getCount() {
return Data.size();
}
private class ViewHolder{
TextView ClassDataTV;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.classes_list_view_item, parent, false);
holder = new ViewHolder();
holder.ClassDataTV = (TextView) convertView.findViewById(R.id.ClassDataTV);
holder.ClassDataTV.setText(Data.get(position));
convertView.setTag(holder);
}else{
holder=(ViewHolder)convertView.getTag();
}
return convertView;
}
}
and here how i use it:
ArrayList<String> v = new ArrayList<>();
v.add("AAAAAAA");
v.add("WWWWWwW");
v.add("VVVVVVV");
v.add("SSSSSSSSS");
v.add("QQQQQQQQQ");
v.add("YYYYYYYY");
v.add("TTTTTTT");
v.add("UUUUUUUUUU");
v.add("zzzzzzzzzzzz");
v.add("CCCCCCCCCC");
v.add("HHHHHHHHHHH");
v.add("IIIIIIIIII");
v.add("PPPPPPPPP");
mListView.setAdapter(new ClassesListViewAdapter(getActivity(), v));
Put following part of your code outside if-block and it will be fixed :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.classes_list_view_item, parent, false);
holder = new ViewHolder();
holder.ClassDataTV = (TextView) convertView.findViewById(R.id.ClassDataTV);
convertView.setTag(holder);
}else{
holder=(ViewHolder)convertView.getTag();
}
// initialize your view here
holder.ClassDataTV.setText(Data.get(position));
return convertView;
}
The logic behind ViewHolder pattern tells that you should do it in this way. when you scroll some of reference will not created again and else block called so this cause your list not updated as you expected.
I have a problem with my custom adapter. the method getView() is not called. I searched on my friends "google" and "stackoverflow" but anything fix my problem.
public class custom_adapter extends BaseAdapter {
private List<Activities> listData;
private LayoutInflater layoutInflater;
public custom_adapter(Context context,
List<Activities> listActivity) {
this.listData = listActivity;
layoutInflater = layoutInflater.from(context);
Log.v("BaseAdapter", "custom_adapter");
}
#Override
public int getCount() {
Log.v("BaseAdapter - getCount", String.valueOf(listData.size()));
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("BaseAdapter", "getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_adapter, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.title);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.averageRatingBarActivitySearch);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Activities newsItem = (Activities) listData.get(position);
holder.name.setText(newsItem.getName());
holder.ratingBar.setRating(newsItem.getAverageMark());
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getPictureActivityString());
}
return convertView;
}
public static class ViewHolder {
TextView name;
RatingBar ratingBar;
ImageView imageView;
}
}
Furthermore, GetCount is not null !
I will be very glade if you can help me
Regards
K.L
For the purpose of handling List of some objects, extending generic ArrayAdapter may be better choice instead of just BaseAdapter. It will handle a lot of things for you. Your whole adapter class could look like.
public class ActivitiesAdapter extends ArrayAdapter<Activities>
{
private LayoutInflater layoutInflater;
public ActivitiesAdapter(Context context, List<Activities> objects)
{
super(context, 0, objects);
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("BaseAdapter", "getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_adapter, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.title);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.averageRatingBarActivitySearch);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Activities newsItem = getItem(position);
holder.name.setText(newsItem.getName());
holder.ratingBar.setRating(newsItem.getAverageMark());
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getPictureActivityString());
}
return convertView;
}
public static class ViewHolder {
TextView name;
RatingBar ratingBar;
ImageView imageView;
}
}
and of course you have to set this adapter to your ListView instance. Like
ActivitiesAdapter adapter = new ActivitiesAdapter(this, yourActivitiesList);
ListView listView = (ListView)findViewById(R.id.my_list_id);
listView.setAdapter(adapter);
or simply setListAdapter(adapter); if you are using ListActivity or ListFragment;
I had the same problem. Maybe, the problem is that you don't notify your adapter that you've changed data in the adapter. Try this code in your adapter:
#Override
public int getCount() {
return data.size();
}
And call notifyDataSetChanged(); when you change the data in Adapter.