Accelarate listview scrolling - android

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

Related

android Listview repeat data while scroll

i have listview with BaseAdapter this is my adapter code
public class MessageAdapter1 extends BaseAdapter {
Context context;
private int auth;
private List<MessageList> mMessages;
private LayoutInflater mInflater;
public MessageAdapter1(Context context, List<MessageList> messages) {
this.mMessages = messages;
this.context = context;
this.session = new SessionManager(context);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
auth = session.getUserId();
}
#Override
public int getItemViewType(int position) {
int type = -1;
String m = mMessages.get(position).getType();
int user_idx = mMessages.get(position).getUser_id();
if(auth != user_idx && m.equals("message")) type = 1;
else if(auth == user_idx && m.equals("message")) type = 0;
else if(auth != user_idx && m.equals("image")) type = 3;
else if(auth == user_idx && m.equals("image")) type = 4;
//other else if and types .....
return type;
}
#Override
public int getViewTypeCount() {
return 19;
}
#Override
public int getCount() {
return mMessages.size();
}
#Override
public Object getItem(int i) {
return mMessages.get(i);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case MessageList.TYPE_MESSAGE_RIGHT:
convertView = mInflater.inflate(R.layout.right_message, null);
holder.groupMessage = (LinearLayout)convertView.findViewById(R.id.messages);
break;
case MessageList.TYPE_MESSAGE_LEFT:
convertView = mInflater.inflate(R.layout.left_message, null);
holder.groupMessage = (LinearLayout)convertView.findViewById(R.id.messages);
break;
case MessageList.TYPE_ACTION:
convertView = mInflater.inflate(R.layout.typing, null);
holder.Indicator = (AVLoadingIndicatorView)convertView.findViewById(R.id.indicator);
break;
//other case break for other types ..
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
setMessage(holder,position);
return convertView;
}
private void setMessage(ViewHolder holder, int position){
MessageList m = mMessages.get(position);
//holder.groupMessage.add ... data
}
public static class ViewHolder {
private LinearLayout groupMessage;
private AVLoadingIndicatorView Indicator;
//more here other
}
}
I search in google and in stackoverflow all solution talk about Override
`getViewTypeCount` and `getItemViewType` and other solution not helped me
i see my code its correct but why its repeat or reorder item when scroll on
ListView
Because your item views appear to change based on the type of items in the list, you cannot cache your viewholder.
Try removing your if (convertView == null) { and accompanying else { statement.

java.lang.NullPointerException: Attempt to read from field 'android.widget.TextView

Hello I realize there are multiple people with a similar issue but the reason for me adding this as a new question is because this is an adapter with two holders. I have a listview that has a header cell and the information cell. the error that I am encountering its
java.lang.NullPointerException: Attempt to read from field 'android.widget.TextView.
Which only happens when I scroll the list down and then go back up. I am assuming the holder is getting destroyed and when I call the line to add text the holder is null but I am not sure. Thank you for your help in advance!
Custom Adapter:
private class MyCustomAdapter extends ArrayAdapter<sources> {
private ArrayList<sources> sources_list = new ArrayList<sources>();
private TreeSet<Integer> sectionHeader = new TreeSet<Integer>();
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private LayoutInflater vi;
public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<sources> sources_list) {
super(context, textViewResourceId, sources_list);
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final sources item) {
sources_list.add(item);
notifyDataSetChanged();
}
public void addSectionHeaderItem(final sources item) {
sources_list.add(item);
sectionHeader.add(sources_list.size() - 1);
notifyDataSetChanged();
}
public int getItemViewType(int position) {
return sectionHeader.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
public int getCount() {
return sources_list.size();
}
public int getViewTypeCount() {
return 2;
}
public sources getItem(int position) {
return sources_list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public class ViewHolder {
TextView code;
CheckBox name;
}
public class ViewHolder2 {
TextView separator;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
ViewHolder2 holder2 = null;
Log.v("ConvertView", String.valueOf(position));
int rowType = getItemViewType(position);
if (convertView == null) {
switch (rowType) {
case TYPE_ITEM:
convertView = vi.inflate(R.layout.source_cell, null);
holder = new ViewHolder();
holder.code = (TextView)
convertView.findViewById(R.id.code);
holder.name = (CheckBox)
convertView.findViewById(R.id.checkBox1);
break;
case TYPE_SEPARATOR:
holder2 = new ViewHolder2();
convertView = vi.inflate(R.layout.source_header, null);
holder2.separator = (TextView)
convertView.findViewById(R.id.separator);
break;
}
convertView.setTag(holder);
} else {
if (rowType == TYPE_ITEM) {
holder = (ViewHolder)
convertView.getTag(R.layout.source_cell);
} else {
holder2 = (ViewHolder2) convertView.getTag(R.layout.source_header);
}
}
if (rowType == TYPE_ITEM) {
sources n_source = sources_list.get(position);
holder.code.setText(n_source.getCode().toUpperCase());
holder.name.setTag(n_source);
} else {
sources n_source = sources_list.get(position);
holder2.separator.setText(n_source.getCode().toUpperCase());
}
return convertView;
}
}
Your setTag/getTag appears to be wrong. You need to use setTag(r.layout.blah, holder) to match your getTag(r.layout.blah).

Navigation Drawer list view with 2 type

I have a Navigation Drawer, With a ListView and with a header. When I scorll the drawer up down the items are mixed, the type of the items. Why?
My DrawerAdapter.java:
public class DrawerAdapter extends BaseAdapter {
private Context context;
private List<DrawerItem> navDrawerItems;
DrawerItemClickListener drawerItemClickListener;
public DrawerAdapter(Context context, ArrayList<DrawerItem> navDrawerItems,DrawerItemClickListener drawerItemClickListener) {
this.context = context;
this.navDrawerItems = navDrawerItems;
this.drawerItemClickListener = drawerItemClickListener;
}
#Override
public int getCount() {
return navDrawerItems.size();
}
#Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public boolean isEnabled(int position) {
return false;
}
static class ViewHolder {
ImageView imvIcon;
TextView textView;
LinearLayout layout;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final DrawerItem mItem = navDrawerItems.get(position);
if(mItem.getType().equals(DrawerItem.TYPE_CLICKABLE))
{
if (convertView == null)
{
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drawer_list_item, parent, false);
holder.imvIcon = (ImageView) convertView.findViewById(R.id.item_icon);
holder.textView = (TextView) convertView.findViewById(R.id.item_text);
holder.layout = (LinearLayout) convertView.findViewById(R.id.drawer_one_layout);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
if(holder.imvIcon != null)
Picasso.with(parent.getContext()).load(mItem.getIcon()).into(holder.imvIcon);
if(holder.textView != null)
holder.textView.setText(mItem.getTitle());
if(holder.layout != null)
holder.layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawerItemClickListener.DrawerItemClicked(mItem);
}
});
}
else
{
if (convertView == null)
{
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drawer_list_item_two, parent, false);
holder.textView = (TextView) convertView.findViewById(R.id.item_text);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(mItem.getTitle());
}
return convertView;
}}
And the Drawer Item :
public class DrawerItem {
public final static String TYPE_CLICKABLE = "clikc";
public final static String TYPE_HEADER = "header";
private String title, type;
private int icon;
public DrawerItem(String title, int icon, String type) {
this.title = title;
this.icon = icon;
this.type = type;
}
public String getTitle() {
return title;
}
public int getIcon() {
return icon;
}
public String getType() {return this.type;}}
Please help me. Thanks.
You are not clearly stating which item type your current view is, so the adapter doesn't know the viewtype and doesn't display correctly the items (e.g. it mixes them).
In your getItemViewType() you should be clear about the viewtype of the current item, and do something like this:
#Override
public int getItemViewType(int position) {
if(navDrawerItems.get(position).getType().equals(DrawerItem.TYPE_CLICKABLE))
return 0;
return 1;
}

ListView Header implementation

I have an Adapter class that implements ListView with headers.
//Adapter Class
private class MyCustomAdapter 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 static final int TYPE_GRAY_SEPARATOR = 2;
private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>();
private ArrayList<ContentWrapper> mData = new ArrayList<ContentWrapper>();
private LayoutInflater mInflater;
private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();
public MyCustomAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
}
public void addItem(ContentWrapper value) {
mData.add(value);
notifyDataSetChanged();
}
public void addSeparatorItem(ContentWrapper value) {
mData.add(value);
// save separator position
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
public ContentWrapper getItem(int position) {
return mData.get(position);
}
#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 long getItemId(int position) {
Log.v("getItemId Position", ""+position);
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.white, null);
holder.textView = (TextView)convertView.findViewById(R.id.text);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.black, null);
holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
} holder.textView.setText(mData.get(position).getItem());
if (type == TYPE_ITEM) {
holder.textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder x = new AlertDialog.Builder(getActivity());
x.setIcon(R.drawable.ic_launcher)
.setTitle(mData.get(position).getItem())
.setMessage(mData.get(position).getItemDescription())
.setCancelable(true)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg,
int arg1) {
}
});
AlertDialog a = x.create();
a.show();
}
return null;
}
});
} else {
holder.textView.setOnClickListener(null);
}
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
In this I truly understand the implementation of getView method (ViewHolder,convertView,etc).
The above code runs smoothy but I do not understand that why we are using the methods
addItem
addSeparatorItem
getItemViewType
getViewTypeCount
getCount
getItemId
Can Anyone explain me the scenario clearly !
Thanks in advance..
These all are the call back methods. You can have the clear definition of these methods in below mentioned link.
http://developer.android.com/reference/android/widget/BaseAdapter.html
Let me give you an example of getItem()
Whenever new listview row is created, adapte willl get item details from this call back method.
Similarly whenever list is created, getCount() is called.
Suppose you have 12 items in listview. But you pass 10 in getCount(). it will show only ten items in list view.

Array List Size Equal Zero When Remove Object From It

I have array list, I used it in adapter class. All things worked good but when I delete specific index from the array list(in my case data) the size of array list equal zero.
Here is my Adapter class
public class MainLocalListAdapter extends BaseAdapter{
public static final int LIMIT_LIST_COUNT = 20;
private Activity activity;
private static ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
private int count = LIMIT_LIST_COUNT;
private int customPosition = 0;
public MainLocalListAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
if(count > data.size()) count = data.size();
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return count;//data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.playlist_local_item, null);
holder.textView = (TextView)convertView.findViewById(R.id.waveTitle2); // title
holder.textView.setTypeface(UtiliShare.getTf());
holder.btnCancel = (ImageView) convertView.findViewById(R.id.btndel);
holder.btnCancel.setOnClickListener(mOnClickListener);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
if(!data.isEmpty()) {
HashMap<String, String> song = data.get(position);
holder.btnCancel.setTag(position);
holder.textView.setText(song.get(UtiliShare.KEY_TITLE));
}
return convertView;
}
private static class ViewHolder{
TextView textView;
ImageView btnCancel;
}
private OnClickListener mOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainLocalListAdapter.this.activity, ""+v.getTag(), Toast.LENGTH_SHORT).show();
data.remove((Integer) v.getTag());
// Here data.size = 0 ????????????
int nval = data.size();
Log.d("list", ""+nval);
notifyDataSetChanged();
}
};
public int getCustomPosition() {
return customPosition;
}
public void setCustomPosition(int cPosition) {
customPosition = cPosition;
int nval = (data.size() - customPosition);
if(nval < LIMIT_LIST_COUNT) this.count = nval;
else count = LIMIT_LIST_COUNT;
}
}
I don't have error because I check data size before get data from it in getView().
How can I fix this??

Categories

Resources