Android ListView lags with ImageLoader - android

I am using androidimageloader.com and get a good bit of flicker as images load into the list, much unlike the demo and apps that use it. I have the imageLoader in the application class, and don't get why it flickers. The images are Facebook profile pictures for users. What would be causing this? Here is my adapter:
public class FriendAdapter extends BaseAdapter {
private Typeface tf;
LayoutInflater inflater;
private String[] nameEvents;
private String[] urls;
private ArrayList<Friend> friends;
ImageManager imageManager;
ImageTagFactory imageTagFactory;
public FriendAdapter(Activity activity, ArrayList<Friend> friends) {
this.friends = friends;
setData(this.friends);
tf = Typeface.createFromAsset(activity.getAssets(),
"fonts/Roboto-Condensed.ttf");
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageManager = BuzzbabaApplication.getImageLoader();
imageTagFactory = new ImageTagFactory(activity, R.drawable.no_pic_icon);
}
public View getView(int position, View convertView, ViewGroup parent) {
FriendView fView;
if (convertView == null) {
convertView = inflater.inflate(R.layout.friend_layout, null);
fView = new FriendView();
fView.name = (TextView) convertView.findViewById(R.id.friendName);
fView.name.setTypeface(tf);
fView.pic = (ImageView) convertView.findViewById(R.id.profilePic);
convertView.setTag(fView);
} else {
fView = (FriendView) convertView.getTag();
}
fView.name.setText(nameEvents[position]);
// HomeScreen.imageLoader.DisplayImage(urls[position], fView.pic);
((ImageView) fView.pic).setTag(imageTagFactory.build(urls[position]));
imageManager.getLoader().load(fView.pic);
return convertView;
}
public void setData(ArrayList<Friend> friends) {
nameEvents = new String[friends.size()];
urls = new String[friends.size()];
int index = 0;
for (Friend f : friends) {
String pos = f.getName();
int num = f.getNumEvents();
if (num == 1) {
pos = pos + "\n" + num + " event";
} else {
pos = pos + "\n" + num + " events";
}
nameEvents[index] = pos;
urls[index] = f.getPictureURL();
index++;
}
}
static class FriendView {
TextView name;
ImageView pic;
}
public int getCount() {
return friends.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
}

Related

Custom ListView with checkbox changes position while scrolling in android

I am new to android and working on web view demo, I have implemented it. But the problem with me is when I check any check box and scrolling the list view , The checked position changes.
I have tried some links from stack over flow with no luck, SO I request someone can help me to resolve this issue, please
My adapter is as below,
adapter
public class FilterAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private ArrayList<String> mData = new ArrayList<String>();
private LayoutInflater mInflater;
private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();
public FilterAdapter(Context context) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
public void addSeparatorItem(final String item) {
mData.add(item);
// save separator position
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
public int getCount() {
return mData.size();
}
public String getItem(int position) {
return mData.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView + " type = " + type);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.raw_filter, null);
holder.textView = (TextView) convertView.findViewById(R.id.tv_filter);
holder.chk_filter = (CheckBox) convertView.findViewById(R.id.chk_filter);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.raw_headr, null);
holder.textView = (TextView) convertView.findViewById(R.id.tv_hdr);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
}
class ViewHolder {
public TextView textView;
public CheckBox chk_filter;
}
add clickListener in your getView() method, it will fix your set checked box in the entire listView like this:
checkBoxSelected.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
instrumentClickListener.onCheckBoxClick(instrumentDTO, checkBoxSelected.isChecked(), position);
Log.d(TAG, "checked instruments is check: " + checkBoxSelected.isChecked() + " \ninstrument: " + position);
}
});

customlistadapter TextView values get change when scrolled down and set to its initial value

In CustomListAdapter I have a increment button and a textview to show its value,when I click on increment button I increment the value then store it to the sqlite db then I fetch that value and then I set it to the respective textview.
But when I scroll down then its value get change to its intial value i.e "0"
I referred to a similar question before, they suggested to use viewholder I used that also but didnot helped me.
I would appreciate anyone guiding me on how to do this.
Here is CustomListAdapter code:
public class CustomListAdapter2 extends BaseAdapter {
private SQLiteHandler db;
// HashMap<Integer,Integer> quantity = new HashMap<Integer,Integer>();
private Activity activity;
private LayoutInflater inflater;
private List<com.example.malli.myapplication.model.Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
private EventBus bus = EventBus.getDefault();
public CustomListAdapter2(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
Log.d("size",String.valueOf(movieItems.size()));
db = new SQLiteHandler(activity.getApplicationContext());
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolderItem viewHolder = null;
if (inflater == null) {
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row2, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
viewHolder = new ViewHolderItem();
viewHolder.thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
viewHolder.title=(TextView)convertView.findViewById(R.id.title);
viewHolder.rating=(TextView)convertView.findViewById(R.id.rating);
viewHolder.genre=(TextView) convertView.findViewById(R.id.genre);
viewHolder.addbutton=(Button)convertView.findViewById(R.id.addbutton);
viewHolder.qty = (TextView) convertView.findViewById(R.id.qty);
convertView.setTag(viewHolder);
}else
{
viewHolder = (ViewHolderItem) convertView.getTag();
}
final Integer uniqueKey = Integer.valueOf(position);
final Movie m = movieItems.get(position);
// store the holder with the view.
// convertView.setTag(viewHolder);
for(int j =0;j<20;j++){
String val1=db.getUser(j);
if(val1 != null) {
viewHolder.qty.setText(db.getUser(j));
}
else{
viewHolder.qty.setText("0");
}
}
final ViewHolderItem finalViewHolder = viewHolder;
viewHolder.addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = finalViewHolder.qty.getText().toString();
if(val == null)
val= String.valueOf(1);
else {
val = String.valueOf(Integer.valueOf(val) + 1);
Log.d("val",String.valueOf(val));
}
db.add(m.getTitle(), String.valueOf(val),
String.valueOf(m.getRating1(),String.valueOf(m.getRating1()));
String val2 = db.getUser(m.getRating1());
finalViewHolder.qty.setText(db.getUser(m.getRating1()));
db.addtotalcost(String.valueOf(
Integer.valueOf(val)*m.getRating1()));
String totalcost = db.getTotalCost2();
EventBus.getDefault().post(new
ChargingEvent(Integer.valueOf(totalcost)));
}
});
// thumbnail image
viewHolder.thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
viewHolder.title.setText(m.getTitle());
// rating
viewHolder.rating.setText("Cost: " + String.valueOf(m.getRating1()));
// genre
String genreStr = "";
for (String str : m.getGenre()) {
genreStr += str + ", ";
}
genreStr = genreStr.length() > 0 ? genreStr.substring(0,
genreStr.length() - 2) : genreStr;
viewHolder.genre.setText(genreStr);
// release year
//year.setText(String.valueOf(m.getYear()));
return convertView;
}
}
add this line
movieItems.set(position, m);
after
m.setqty(val1);
this will update the value of the property in the data set, so the adapter view the new data when it's rendered by getView()

Accelarate listview scrolling

I'm trying to scroll my simple listview, but unfortunately it's not scrolling smoothly.
I can't figure out what seem to be the problem. I'm not doing anything fancy.
public class ArticleRowAdapter extends BaseAdapter {
private static final int TYPE_MAINARTICLE = 0;
private static final int TYPE_ARTICLE = 1;
private static final int TYPE_MAX_COUNT = TYPE_ARTICLE + 1;
private Context context;
private ArrayList<ArticleRow> mData = new ArrayList<ArticleRow>();
private LayoutInflater mInflater;
public ArticleRowAdapter(Context context,ArrayList<ArticleRow> data) {
this.context = context;
this.mData = data;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
static class ArticleRowHolder
{
TextView tvTitle;
ImageView ivImage;
TextView tvSubTitle;
}
public void addItem(final ArticleRow item) {
mData.add(item);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
return position == 0 ? TYPE_MAINARTICLE : TYPE_ARTICLE;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public ArticleRow getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ArticleRowHolder holder = null;
int type = getItemViewType(position);
if(convertView == null)
{
holder = new ArticleRowHolder();
switch(type)
{
case TYPE_MAINARTICLE:
convertView = mInflater.inflate(R.layout.mainarticle,parent, false);
break;
case TYPE_ARTICLE:
convertView = mInflater.inflate(R.layout.article,parent , false);
break;
}
holder.tvTitle = (TextView)convertView.findViewById(R.id.articleTitle);
holder.ivImage = (ImageView)convertView.findViewById(R.id.articleImage);
holder.tvSubTitle = (TextView)convertView.findViewById(R.id.articleSubTitle);
convertView.setTag(holder);
}
else
{
holder = (ArticleRowHolder)convertView.getTag();
}
ArticleRow articleRow = mData.get(position);
holder.tvTitle.setText((CharSequence)articleRow.title);
holder.tvSubTitle.setText(Html.fromHtml(articleRow.subTitle));
if(articleRow.imageURL == null)
holder.ivImage.setImageDrawable(this.context.getResources().getDrawable(R.drawable.dunk));
else
{
holder.ivImage.setImageDrawable(this.context.getResources().getDrawable(R.drawable.dunk));
}
return convertView;
}
I can say that the reason of lags are imageViews, thats for sure:
holder.ivImage = (ImageView)convertView.findViewById(R.id.articleImage);
try to not to fill imageViews with images and see what happens :). Also check google's BitmapFun and LazyList - both about images in list/grid views

CheckBox Issue in List View With Different Layout For Rows

I tried make list view has TextView and CheckBox. It is worked fine but when select CheckBox in row another CheckBox in another row selected too.
Example: if I checked first row and scroll down I found another row selected too.
This my Adapter Code
public class ReadersrListAdapter extends BaseAdapter{
private static final int TYPE_SEPARATOR = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_MAX_COUNT = 2;
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater mInflater=null;
public ReadersrListAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
mInflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return !data.get(position).get(UtiliShare.KEY_TITLE).startsWith("-");
}
#Override
public int getItemViewType(int position) {
return data.get(position).get(UtiliShare.KEY_TITLE).startsWith("-") ? TYPE_SEPARATOR : TYPE_ITEM;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
ViewHolder2 holder2 = null;
int type = getItemViewType(position);
if (convertView == null) {
//holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.reader_list_item, null);
holder.textView = (TextView)convertView.findViewById(R.id.readerTitle);
holder.textView.setTypeface(UtiliShare.getTf());
convertView.setTag(holder);
break;
case TYPE_SEPARATOR:
holder2 = new ViewHolder2();
convertView = mInflater.inflate(R.layout.reader_list_devider, null);
holder2.textView = (TextView)convertView.findViewById(R.id.readerTitle);
holder2.textView.setTypeface(UtiliShare.getTf());
convertView.setTag(holder2);
break;
}
//convertView.setTag(holder);
} else {
if(type==TYPE_ITEM) holder = (ViewHolder)convertView.getTag();
else holder2 = (ViewHolder2)convertView.getTag();
}
HashMap<String, String> curdata = new HashMap<String, String>();
curdata = data.get(position);
String txt = curdata.get(UtiliShare.KEY_TITLE);
if(type == TYPE_SEPARATOR){
txt = txt.replace("-", "");
holder2.textView.setText(txt);
}else{
//if(position <= 100) System.out.println("getView " + position + " " + convertView + " type = " + type);
holder.star = (CheckBox) convertView.findViewById(R.id.btn_Fav);
holder.star.setOnCheckedChangeListener(((ReadersListActivity) this.activity).mStarCheckedChanceChangeListener);
holder.textView.setText(txt);
}
//holder.textView.setText(txt);
return convertView;
}
private static class ViewHolder {
public CheckBox star;
public TextView textView;
}
private static class ViewHolder2 {
public TextView textView;
}
}
And this OnCheckedChangeListener in activity
public OnCheckedChangeListener mStarCheckedChanceChangeListener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Cyril: Not implemented yet!
final int position = list.getPositionForView(buttonView);
Toast.makeText(ReadersListActivity.this, ""+position, Toast.LENGTH_SHORT).show();
}
};
How Can I fix this???
Thanks.
As you may know the layouts are reused as you scroll, so you need to track whether each row should be checked yourself. Let's add a new member to your Adapter:
private SparseBooleanArray checked = new SparseBooleanArray();
And a new method:
public void toggleCheck(int position) {
boolean state = expanded.get(position, false);
expanded.put(!state);
}
Now call our new method in onCheckedChanged():
final int position = list.getPositionForView(buttonView);
adapter.toggleCheck(position);
Lastly let's tweak getView() to change the checked state (and a few other things):
// Don't create a new HashMap that you'll never use
//HashMap<String, String> curdata = new HashMap<String, String>();
HashMap<String, String> curdata = data.get(position);
String txt = curdata.get(UtiliShare.KEY_TITLE);
if(type == TYPE_SEPARATOR){
txt = txt.replace("-", "");
holder2.textView.setText(txt);
}else{
//if(position <= 100) System.out.println("getView " + position + " " + convertView + " type = " + type);
// These two lines should be in `if(convertView == null)` with the others
holder.star = (CheckBox) convertView.findViewById(R.id.btn_Fav);
holder.star.setOnCheckedChangeListener(((ReadersListActivity) this.activity).mStarCheckedChanceChangeListener);
// Set the appropriate values
holder.textView.setText(txt);
holder.star.setChecked(expanded.get(position, false));
}

ListFragment error

I have a list in a "listview" to scroll the list using this mess,
grouping and the list has a header with icons.
public class MyCustomAdapter extends BaseAdapter {
private static final String ASSETS_DIR = "images/";
private static final int TYPE_HEAD = -1;
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private Context ctx;
private ArrayList<String> mData = new ArrayList<String>();
private LayoutInflater mInflater;
private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();
public MyCustomAdapter(Context context) {
this.ctx = context;
mInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
public void addSeparatorItem(final String item) {
mData.add(item);
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
public void addHeadItem(){
mData.add("");
mSeparatorsSet.add(0);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mData.size();
//return equipos.size();
}
#Override
public String getItem(int position) {
return mData.get(position) ;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public int getItemViewType(int position) {
if (position==0)
return TYPE_HEAD;
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView
+ " type = " + type);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.list_item, null);
holder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.textView2 = (TextView) convertView.findViewById(R.id.textView2);
holder.textView3 = (TextView) convertView.findViewById(R.id.textView3);
holder.imageView1 = (ImageView) convertView.findViewById(R.id.imageView1);
String[] datos = mData.get(position).split("-");
holder.textView1.setText(String.format(" %s - %s", datos[0],datos[1]));
holder.textView2.setText(datos[2]);
holder.textView3.setText(datos[3]);
String sel_bandera = datos[4].trim() ;
String imgFilePath = "";
if (sel_bandera.equals("verde")){
imgFilePath = ASSETS_DIR + "circle_green.png" ;
}else if (sel_bandera.equals("amarilla")){
imgFilePath = ASSETS_DIR + "circle_yellow.png";
}else {
imgFilePath = ASSETS_DIR + "circle_red.png";
}
try {
Bitmap bitmap = BitmapFactory.decodeStream(this.ctx.getResources().getAssets().open(imgFilePath));
holder.imageView1.setImageBitmap(bitmap);
//bandera.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.list_group, null);
holder.textView1 = (TextView) convertView.findViewById(R.id.textSeparator);
holder.textView1.setText(mData.get(position));
break;
case TYPE_HEAD:
convertView = mInflater.inflate(R.layout.list_head, null);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
public static class ViewHolder {
public TextView textView1;
public TextView textView2;
public TextView textView3;
public ImageView imageView1;
public TextView getTextView1() {
return textView1;
}
public void setTextView1(TextView textView1) {
this.textView1 = textView1;
}
public TextView getTextView2() {
return textView2;
}
public void setTextView2(TextView textView2) {
this.textView2 = textView2;
}
public TextView getTextView3() {
return textView3;
}
public void setTextView3(TextView textView3) {
this.textView3 = textView3;
}
public ImageView getImageView1() {
return imageView1;
}
public void setImageView1(ImageView imageView1) {
this.imageView1 = imageView1;
}
}
}
public class EquiposActivity extends ListFragment implements OnTouchListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mAdapter = new MyCustomAdapter(getActivity());
if (lista.length > 0) {
String[] datos = lista[0].split("-");
cabecera_grupo = datos[4];
}
mAdapter.addHeadItem();
for (int i = 0; i < lista.length; i++) {
String[] datos = lista[i].split("-");
String grupo = datos[4];
if (i == 0) {
mAdapter.addSeparatorItem(grupo.replace("_", " "));
}
if (!grupo.equals(cabecera_grupo)) {
mAdapter.addSeparatorItem(grupo.replace("_", " "));
cabecera_grupo = grupo;
}
mAdapter.addItem(String.format("%s - %s - %s - %s - %s",
datos[0], datos[1], datos[2], datos[3], datos[5]));
}
setListAdapter(mAdapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
I suggest you to rewrite your getView() method, because I think that you are wrongly using ViewHolder pattern. Read this: http://www.jmanzano.es/blog/?p=166
Or just get rid of ViewHolder and code getView() without it.

Categories

Resources