I am trying to create a custom adapter for a shop element in my Android app but every time I scroll down the list the images seem to change their position, I have had a look around on here already but suggestions that I have found and tried have been to no avail.
Each item has a title, an image (being loading via an AsyncTask or retrieved from the LRUCache) and a price of the item below is the code I use to generate the adapter.
public class ShopAdapter extends BaseAdapter {
public Context context;
public ArrayList<ShopItem> shopItemList;
public ImageCache imageCache;
String imageToLoad;
Bitmap shopImage;
public ShopAdapter(Context context, ArrayList<ShopItem> shopItemList) {
this.context = context;
this.shopItemList = shopItemList;
imageCache = new ImageCache(this.context);
}
#Override
public int getCount() {
return shopItemList.size();
}
#Override
public Object getItem(int position) {
return shopItemList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.shop_list, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.textView3);
holder.image =(ImageView) convertView.findViewById(R.id.imageView);
holder.price = (TextView) convertView.findViewById(R.id.textView4);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(shopItemList.get(position).getTitle());
shopImage = imageCache.getBitmapFromMemoryCache(shopItemList.get(position).getImage());
if(shopImage != null) {
holder.image.setImageBitmap(shopImage);
} else {
new LoadImage(context, holder.image).execute(imageToLoad);
}
holder.price.setText(shopItemList.get(position).getPrice());
return convertView;
}
static class ViewHolder {
TextView title;
ImageView image;
TextView price;
}
}
Any help would be very much appreciated!
Related
I am trying to get the total of numbers in an sql table,
i first connected between android and sql but i can't
sum the numbers in the table column and show them
in a textview,like i want to get the total
of numbers in a column then
display them in a text view
,can someone help me with this task?
here is the code i used for
the listview
public class MyAppAdapter extends BaseAdapter //has a class viewholder which holds
{
public class ViewHolder
{
TextView textDate;
TextView textTotal;
TextView textLastTotal;
TextView textCount;
TextView textTaxs;
}
public List<ClassListItems2> parkingList;
public Context context;
ArrayList<ClassListItems2> arraylist;
private MyAppAdapter(List<ClassListItems2> apps, Context context)
{
this.parkingList = apps;
this.context = context;
arraylist = new ArrayList<ClassListItems2>();
arraylist.addAll(parkingList);
}
#Override
public int getCount() {
return parkingList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) // inflating the layout and initializing widgets
{
View rowView = convertView;
ViewHolder viewHolder= null;
if (rowView == null)
{
LayoutInflater inflater = getLayoutInflater();
rowView = inflater.inflate(R.layout.listcontent2, parent, false);
viewHolder = new ViewHolder();
viewHolder.textDate = (TextView) rowView.findViewById(R.id.date);
viewHolder.textLastTotal = (TextView) rowView.findViewById(R.id.lasttotal);
viewHolder.textTaxs = (TextView) rowView.findViewById(R.id.date3);
viewHolder.textCount = (TextView) rowView.findViewById(R.id.InvoicescCount);
viewHolder.textTotal = (TextView) rowView.findViewById(R.id.total);
rowView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
// here setting up names and images
viewHolder.textDate.setText(parkingList.get(position).getDate()+"");
viewHolder.textTotal.setText(parkingList.get(position).getTotal());
viewHolder.textLastTotal.setText(parkingList.get(position).getLasttotal());
viewHolder.textTaxs.setText(parkingList.get(position).getTaxs());
viewHolder.textCount.setText(parkingList.get(position).getInvoicecount());
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//What happens when you click on a place!
}
});
return rowView;
}
This Adapter is feed with a Collection (List) in his constructor.
To know total numbers, in Activity/Fragment that handle that Collection use:
parkingList.size()
To get sum:
float total;
for (ClassListItems2 actualItem : parkingList) {
total += actualItem.getTotal()
}
All of this logic must be executed in Activity/Fragment, never in Adapter because the Adapter only got presentation/visual logic.
in my listView i'm trying to divide (categorize) my data in to different section say i have a list of states and i wanna categorize them according to their Countries but what i have right now is categorizing my data Alphabetically and i have no clue how it is happening and how can i achieve what i want. can anyone guide me here ?
my adapter :
public class MyAdapter extends BaseAdapter implements StickyListHeadersAdapter {
private String[] countries;
private LayoutInflater inflater;
private ArrayList<States> statesArray;
public MyAdapter(Context context , ArrayList<States> states) {
inflater = LayoutInflater.from(context);
satesArray = states;
countries = context.getResources().getStringArray(R.array.all_countries);
}
#Override
public int getCount() {
return statesArray.size();
}
#Override
public Object getItem(int position) {
return statesArray.get(position).getName();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_view_row, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.listViewTextView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(statesArray.get(position).getName());
return convertView;
}
#Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = inflater.inflate(R.layout.sticky_header, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.text1);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
//set header text as first char in name
String headerText = "" + countries[position];
holder.text.setText(headerText);
return convertView;
}
#Override
public long getHeaderId(int position) {
// return the first character of the country as ID because this is what headers are based upon
return satesArray.get(position).getName().subSequence(0, 1).charAt(0);
}
class HeaderViewHolder {
TextView text;
}
class ViewHolder {
TextView text;
}
}
UPDATE :
what i want is right here but instead of Alphabets at Section there would be Country name and at rows there would be states of respective Country :
righ here
in my android application I am displaying the contact list of phone in a list view and a check box in each row for selecting contacts. But when I am selecting a particular row about tenth row is also getting selected automatically. I am giving my code below, if any one knows please help..
public class ContactsAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Contact> contacts;
public ContactsAdapter(Context context, ArrayList<Contact> contacts)
{
this.context = context;
this.contacts = contacts;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
final ViewHolder mHolder;
if (convertView == null)
{
// gridView = new View(context);
// get layout from mobile.xml
//gridView = inflater.inflate(R.layout.contact, null);
convertView = inflater.inflate(R.layout.contact, null);
mHolder = new ViewHolder();
mHolder.textName =(TextView) convertView.findViewById(R.id.name);
mHolder.textMobile =(TextView) convertView.findViewById(R.id.mobile);
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
convertView.setTag(mHolder);
));
}
else
{
mHolder = (ViewHolder) convertView.getTag();
mHolder.textSelector.setOnCheckedChangeListener(null);
}
mHolder.textMobile.setText(contacts.get(position).getMobile());
mHolder.textName.setText(contacts.get(position).getName());
mHolder.textSelector.setFocusable(false);
return convertView;
}
private class ViewHolder {
private TextView textMobile,textName;
private CheckBox textSelector;
}
#Override
public int getCount() {
return contacts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
Well Thats because ViewHolder will recycle the Views everytime you Scroll
i suggest you to Use onCLick on ListItem instead checkbox
To overcome this Declare a SparseBooleanArray
SparseBooleanArray sba=new SparseBooleanArray();//this should be global
Then set the items checked state as soon as you render it
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
mHolder.textSelector.setChecked(sba.get(position));
Then write a onClickListener to you convertView and check it manually
convertView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
mHolder.textSelector.setChecked(isChecked);
sba.put(position,isChecked); //storing the state
}
}
);
**Well Now the sba has list items checked and you can use that for further Actions**
# Jocheved... edit your code like this...
public class ContactsAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Contact> contacts;
SparseBooleanArray sba=new SparseBooleanArray();
public ContactsAdapter(Context context, ArrayList<Contact> contacts)
{
this.context = context;
this.contacts = contacts;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ViewHolder mHolder;
if (convertView == null)
{
convertView = inflater.inflate(R.layout.contact, null);
mHolder = new ViewHolder();
mHolder.textName =(TextView) convertView.findViewById(R.id.name);
mHolder.textMobile =(TextView) convertView.findViewById(R.id.mobile);
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
convertView.setTag(mHolder);
}
else
{
mHolder = (ViewHolder) convertView.getTag();
}
mHolder.textMobile.setText(contacts.get(position).getMobile());
mHolder.textName.setText(contacts.get(position).getName());
mHolder.textName.setSelected(true);
mHolder.textSelector.setChecked(sba.get(position));
mHolder.textSelector.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
if(mHolder.textSelector.isChecked())
{
sba.put(position, true);
}
else
{
sba.put(position, false);
}
}
});
return convertView;
}
private class ViewHolder
{
private TextView textMobile,textName;
private CheckBox textSelector;
}
#Override
public int getCount() {
return contacts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
I understand that many of you are already fed up with the nullpointerexception-related questions, so I thought again and again whether or not to ask this question. I read up the following short code for an hour, and I still cannot figure out why the nullpointerexception is thrown..
Here is the ImageAdapter class..
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
public ImageAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mContext = context;
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = mInflater.inflate(R.layout.dialog_addprofile, null);
convertView.setLayoutParams(new GridView.LayoutParams(90, 90));
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.categoryText);
holder.icon = (ImageView) convertView.findViewById(R.id.categoryimage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setAdjustViewBounds(true);
holder.icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.icon.setPadding(8, 8, 8, 8);
holder.title.setText(categoryContent[position]);
holder.icon.setImageResource(mThumbIds[position]);
return convertView;
}
class ViewHolder {
TextView title;
ImageView icon;
}
private Integer[] mThumbIds = {
android.R.drawable.ic_menu_gallery, android.R.drawable.ic_menu_camera
};
private String[] categoryContent = {
"Gallery", "Camera"
};
}
And here's the part of the logcat.
java.lang.NullPointerException
at com.marshall.thequizshow.ui.adapter.ImageAdapter.getView(ImageAdapter.java:56)
According to the logcat, the end part below the if-else statement in the getView method seems to have the problem. I tried really hard to figure out what should be fixed, but I'm still lost. Somebody please help me?
Add this line in your constructor
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
I'm attempting to create a Gridview of icons with the Imageview set to one of two images like in my example below:
I'm retrieving two values from the sqlite content provider, one for the number of stamps and the other for the max number of stamps.
I use a custom adapter with a view holder pattern so I attempt to set the model onLoadFinished() in the Fragment. The model I've currently tried is an int[] with either value of 0 or 1 in the values to determine if green stamp is used or gray. This isn't working however as nothing is being displayed in the GridView.
Here's the code snippet from onLoadFinished() from the Fragment:
imageSourceModel = new int[data.getInt(data.getColumnIndex(RewardsEntry.COLUMN_REW_MAX_POINTS))];
int i = data.getInt(data.getColumnIndex(RewardsEntry.COLUMN_REW_POINTS));
for (int j = 0; j < imageSourceModel.length; j++, i--) {
if (i > 0) {
imageSourceModel[j] = 1;
} else {
imageSourceModel[j] = 0;
}
}
stampGridAdapter.setModel(imageSourceModel);
and the code from the custom Adapter:
#Override
public View getView(int i, View view, ViewGroup parent) {
ViewHolder viewHolder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item_discover, parent, false);
viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
if (model[i] > 0) {
viewHolder.stampView.setImageResource(R.drawable.ic_approved_stamp);
} else {
viewHolder.stampView.setImageResource(R.drawable.ic_approved_stamp_disabled);
}
return view;
}
And simple ViewHolder:
private class ViewHolder {
public ImageView stampView;
public ViewHolder(View view) {
stampView = (ImageView) view.findViewById(R.id.grid_stamp_image);
}
}
If I had to guess, I would say that it fails because of the creation order such that getView() is completed before onLoadFinished() can pass the model in. I'm just not sure how to work around this or what other methods I could use. Any help is appreciated.
For what you want to achieve, this seems unnecessary complicated to me, especially the double variable loop. To cut it simple I'd just do this:
in onLoadFinished()
int maxPoints = data.getInt(data.getColumnIndex(RewardsEntry.COLUMN_REW_MAX_POINTS));
int currentPoints = data.getInt(data.getColumnIndex(RewardsEntry.COLUMN_REW_POINTS));
mGridView.setAdapter(new RewardPointAdapter(getActivity(), currentPoints, maxPoints);
your adapter could look like this:
public class RewardPointAdapter extends BaseAdapter {
private LayoutInflater mLayoutInflater;
private int mMaxRewardPoints;
private int mCurrentRewardPoints;
public RewardPointAdapter(Context context, int currentRewardPoints, int maxRewardPoints) {
mLayoutInflater = LayoutInflater.from(context);
mMaxRewardPoints = maxRewardPoints;
mCurrentRewardPoints = currentRewardPoints;
}
#Override
public int getCount() {
return mMaxRewardPoints;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.list_item_discover, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (position < mCurrentRewardPoints) {
viewHolder.stampView.setImageResource(R.drawable.ic_approved_stamp);
} else {
viewHolder.stampView.setImageResource(R.drawable.ic_approved_stamp_disabled);
}
return convertView;
}
private class ViewHolder {
public ImageView stampView;
public ViewHolder(View view) {
stampView = (ImageView) view.findViewById(R.id.grid_stamp_image);
}
}
}