Listview duplicates item every 6 times
I see the problem now. And no, there is no duplication here. Carry out these few changes:
In your static class ListViewItem
, add boolean isChecked;
static class ListViewItem{
public String ItemTitle;
public int price;
public String Description;
public TextView title;
public TextView pricetitle;
public TextView Descriptiontitle;
public CheckBox cb;
public Spinner sp;
public boolean isChecked; // <--- added
}
Change the initialization of items
:
items.add(new ListViewItem(){{
ItemTitle = "Starter Title";
Description= "Your description goes here";
price=i;
isChecked = false;
}});
In the getView() method, after holder.Descriptiontitle.setText(item.Description);
, add:
holder.cb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
item.isChecked = true;
} else {
item.isChecked = false;
}
}
});
if (item.isChecked) {
holder.cb.setChecked(true);
} else {
holder.cb.setChecked(false);
}
Add the final
keyword to ListViewItem item = items.get(position);
:
final ListViewItem item = items.get(position);
TextView in listview rows showing repeated values on scroll in Android?
I got the solution for the issue. I have introduced a dialogList()
in which I am working with a ArrayList. Below I have mentioned the code of my Adapter class.
public class AppListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private List<App> mApps = Constants.list;
private Context _activity;
ArrayList<String> months=null;
ArrayAdapter<String> dataAdapter =null;
int spinerposition;
Context contextfordatabase=null;
int temp=0;
private int screenWidth;
/**
* Constructor.
*
* @param context the application context which is needed for the layout inflater
* @param screenWidth
*/
public AppListAdapter(Context context, int screenWidth) {
contextfordatabase=context;
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
this._activity=context;
this.screenWidth = screenWidth;
months = new ArrayList<String>();
months.add("No Item Selected");
months.add("None");
months.add("Entertainment");
months.add("Games");
months.add("News/Books");
months.add("Social Networking");
months.add("Utilities");
months.add("Texting");
months.add("Web Browsers");
}
public int getCount() {
return mApps.size();
}
public Object getItem(int position) {
return mApps.get(position);
}
public long getItemId(int position) {
return position;
}
public class AppViewHolder {
private TextView mTitle = null;
private TextView apptitleTxt = null;
private TextView offTxt = null;
private Spinner spiner=null;
public TextView offtext;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final AppViewHolder holder;
if(convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
// creates a ViewHolder and stores a reference to the children view we want to bind data to
holder = new AppViewHolder();
holder.spiner=(Spinner)convertView.findViewById(R.id.spinner);
holder.offtext=(TextView)convertView.findViewById(R.id.off_txt);
holder.apptitleTxt = (TextView) convertView.findViewById(R.id.apptitle_txt);
Typeface typeface = Typeface.createFromAsset(_activity.getAssets(),"CHICM___.TTF");
holder.apptitleTxt.setTypeface(typeface);
holder.offtext.setTypeface(typeface);
if(screenWidth>480){
holder.offtext.setTextSize(30);
holder.apptitleTxt.setTextSize(30);
}
convertView.setTag(holder);
} else {
holder = (AppViewHolder) convertView.getTag();
}
holder.offtext.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialogList(holder.offtext, position);
}
});
holder.apptitleTxt.setText(mApps.get(position).getTitle());
holder.offtext.setText(mApps.get(position).getVersionName());
return convertView;
}
/**
* Sets the list of apps to be displayed.
*
* @param list the list of apps to be displayed
*/
public void setListItems(List<App> list) {
mApps = list;
}
public void dialogList(final TextView textView, final int clickedPosition){
Builder builder = new AlertDialog.Builder(_activity);
builder.setTitle("Select Category");
builder.setItems(R.array.category_list, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
textView.setText(months.get(which+1));
App app = new App();
app.setTitle(mApps.get(clickedPosition).getTitle());
app.setPackageName(mApps.get(clickedPosition).getPackageName());
app.setVersionName(months.get(which+1));
app.setVersionCode(mApps.get(clickedPosition).getVersionCode());
mApps.set(clickedPosition, app);
System.out.println(clickedPosition+" : "+months.get(which+1));
update_database(mApps.get(clickedPosition).getPackageName(),months.get(which+1));
AppListAdapter.this.notifyDataSetChanged();
}
});
builder.create();
builder.show();
}
public void update_database(String packageName, String string) {
CallBackDatabase callback = new CallBackDatabase(contextfordatabase);
callback.open();
Cursor cursor =callback.getAll(packageName);
int y=cursor.getCount();
int j=0;
if(y!=0)
{
callback.UpdateCategory(packageName, string);
}
else
{
callback.InsertAppInfo(null, packageName, "0", "0", "0", "null", string);
}
cursor.deactivate();
cursor.close();
callback.close();
}
}
Repeating items in ListView?
You are facing that data repeat issue, just because you aren't following the exact standards of implementing View-Holder pattern.
Wrong:
Here you are doing findViewById() and setting data if view is null, so it will be running fine for first set of items, afterword it will show you the same data for the next sets of items.
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
ViewHolder holder;
if (v == null) {
try {
LayoutInflater vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.group_item, null);
holder = new ViewHolder();
holder.tv_group_name = (TextView) v
.findViewById(R.id.tv_group_name);
String group_name = group_details.get(position).getGroup_name();
holder.tv_group_name.setText(group_name);
holder.tv_group_name.setTypeface(face);
holder.tv_group_reg_id = (TextView) v
.findViewById(R.id.tv_group_reg_id);
String groupRegId = group_details.get(position)
.getGroup_reg_id();
holder.tv_group_reg_id.setText(groupRegId);
holder.tv_group_reg_id.setTypeface(face);
holder.tv_subscriber_count = (TextView) v
.findViewById(R.id.tv_subscriber_count);
holder.tv_subscriber_count.setText(group_details.get(position)
.getSubscriber_count());
v.setTag(holder);
} catch (Exception e) {
e.printStackTrace();
}
} else
holder = (ViewHolder) v.getTag();
return v;
}
Correct:
Correct way to implement View Holder pattern is to find views if current view is null (that would happen for the first time) and set data only after doing it. So eventually findViewById()
process will be done for the first time and next time onwards it will get views by using attached tags.
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
ViewHolder holder;
if (v == null) {
LayoutInflater vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.group_item, null);
holder = new ViewHolder();
holder.tv_group_name = (TextView) v
.findViewById(R.id.tv_group_name);
holder.tv_group_reg_id = (TextView) v
.findViewById(R.id.tv_group_reg_id);
holder.tv_subscriber_count = (TextView) v
.findViewById(R.id.tv_subscriber_count);
v.setTag(holder);
} catch (Exception e) {
e.printStackTrace();
}
} else
holder = (ViewHolder) v.getTag();
String group_name = group_details.get(position).getGroup_name();
holder.tv_group_name.setText(group_name);
holder.tv_group_name.setTypeface(face);
String groupRegId = group_details.get(position)
.getGroup_reg_id();
holder.tv_group_reg_id.setText(groupRegId);
holder.tv_group_reg_id.setTypeface(face);
holder.tv_subscriber_count.setText(group_details.get(position)
.getSubscriber_count());
return v;
}
Android Listview Item is Repeating on adding new item with different data
okay i have solved it by myself . the problem was i was passing simple string but i have to pass string array in order to add new data to listviews.
here are the changes i made ..
in activity:
public void setlisto(String one ){
Log.e("setlistoo",one+"");
myrows.add(one);
time1.add(Time);
name1.add(Name);
number1.add(Number);
adi = myrows.toArray(new String[myrows.size()]);
adi1=time1.toArray(new String[time1.size()]);
adi2=name1.toArray(new String[name1.size()]);
adi3=number1.toArray(new String[number1.size()]);
listview.setAdapter(new MyNotiAdapter(noticall.this, adi,adi1,adi2,adi3));
// if(adi!=null)
//adp.notifyDataSetChanged();
x++;
}
in baseadapter class :
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder mHolder;
View vi = convertView;
if (vi == null){
vi = inflater.inflate(R.layout.row2, null);
mHolder = new ViewHolder();
mHolder.text= (TextView) vi.findViewById(R.id.lablel);
mHolder.Nameo = (TextView) vi.findViewById(R.id.person);
mHolder.Numbero = (TextView) vi.findViewById(R.id.edu);
mHolder.Time = (TextView) vi.findViewById(R.id.tym);
vi.setTag(mHolder);
mHolder.text.setText(data[position]);
mHolder.Nameo.setText(Name[position]);
mHolder.Numbero.setText(Number[position]);
mHolder.Time.setText(time[position]);
}else {
mHolder = (ViewHolder) convertView.getTag();
}
return vi;
}
everything goes smooth now ... its working perfect . it might help someone like me . Cheers..
list view repeating values several times and repeating check box selection every after 6th value
Set your check box state on getView
if (checkboxstate[((int) viewHolder.checkBox.getTag())] == null) {
checkboxstate[((int) viewHolder.checkBox.getTag())] = false;
}
viewholder.checkbox.setChecked(checkboxstate[((int)viewHolder.checkBox.getTag())]);
First item of listview shows repeated results
It seems that getView()
in general - and especially getView(0) - will be called more often than there are items in the data list. This is not a bug of ListView
or ArrayAdapter
, it's simply the way things are.
In your implementation of getView()
, you only add child View
s to the LinearLayout
, you never remove them.
So if a row is recycled, the number of child View
s will become too large. This will happen not only for the first row but also when you scroll up and down (if the list is long enough) and so cause more rows to be recycled.
Since each row should have six balls, you can add the six ImageView
s to each LinearLayout
right after the row has been inflated (or even make them part of the layout xml file) and later on loop through the ImageView
s to exchange the Bitmap
depending on the data for the current position.
Android ListView and GridView repeating changed item during scroll
In order to optimize the scrolling experience, ListView
and GridView
will re-use item views to avoid having to inflate/instantiate a view for every list item.
That's why getView
has a parameter of type View
called convertView
. When convertView
is null, you need to inflate a new view for the item. When it is not null, that means you can re-use this view to avoid the overhead of inflation.
The downside is that this "recycled" item view will have garbage in it from the last time it was displayed, and you have to reset everything in the view to match the list item.
So a common mistake that new Android developers make is to not have a model representation of everything in the view. For example, if your list item can show a status of active or inactive, then the model for your list item should probably have a boolean
property called mActive
.
The model for the list has to have the entire current state of the list at any given time, so that it can be recreated whenever the ListView
decides it needs to redisplay its list items.
So what you need to do is basically four things:
Add the property to your list item model:
boolean mActive; // this can be private with getter/setter
Create an adapter method for changing the state. For example:
public void toggleItemActive(int position) {
mListItem.get(position).mActive = ! mListItem.get(position).mActive;
notifyDataSetChanged();
}Calling
notifyDataSetChanged()
here is very important.Use this property in your
getView
override:imageView.setImageResource(item.mActive ? R.drawable.active : R.drawable.inactive); // or however you are doing it
Set the property from your event handler:
listView.setOnItemClickListener(new OnItemClickListener) {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MyAdapter adapter = (MyAdapter) parent.getAdapter();
adapter.toggleItemActive(position);
}
});
Now your ListView
will correctly display your list items.
Related Topics
Disable Android Browser's Input Overlays
How to Close Activity and Go Back to Previous Activity in Android
Shared Preferences Reset Data When App Is Force Closed or Device Is Restarted
Using Multiple Text Colors in Android's Textview [ HTML.Fromhtml() ]
Textview with Background Color and Line Spacing
Clearing Notification After a Few Seconds
Android Browser Textarea Scrolls All Over The Place, Is Unusable
<Select> Not Working in Phonegap App on Android 2.3.3
How to Make a Dialog Slide from Bottom to Middle of Screen in Android
Web App on Android Browser Width Issue
CSS Overflow and Absolute Positioning Issue on Android Browser
How to Set Text Color of a Textview Programmatically
Background-Attachment: Fixed Interfering with Background-Size
What Are The Default Color Values for The Holo Theme on Android 4.0
How to Update Google Play Services for Android Studio 2.2 Emulators