androidlistviewandroid-listviewaquery

listview recycling with difrent layout styles


i have a listview with difrent style items, a header style (black) with the date and a item stile for the items of that date.

Now wen i scroll down the information is not in the right item. sometimes the title goes in the black bars and sometimes the date goes in the item stile.

Also the image is not the right. I use listview adapters like this in the app i was building but never had this, it is the first time i work with difrent layout's in a single listview.

i use Aquery for the image loading.

Point me on mine mistake please.

Greathings

enter image description here

The binder java

public class BinderData_TvGids extends BaseAdapter {
    LayoutInflater inflater;
    List<HashMap<String,String>> TvGids;
    ViewHolder holder;

    public BinderData_TvGids() {}

    public BinderData_TvGids(Activity act, List<HashMap<String, String>> map) {
        this.TvGids = map;
        inflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {
        return TvGids.size();
    }

    public Object getItem(int arg0) {
        return null;
    }

    public long getItemId(int position) {
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        File ext = Environment.getExternalStorageDirectory();
        File cacheDir = new File(ext, "/android/data/apk/case");
        AQUtility.setCacheDir(cacheDir);
        AQuery aq = new AQuery(convertView);

        ViewHolder holder = null;
        View vi=convertView;
        if(TvGids.get(position).get("header").equals("true")) { //headers worden meegegeven uit array, deze krijgen een apparten layout
            if (convertView == null) {
                vi = inflater.inflate(R.layout.list_row_tvgids_header, null);
                holder = new ViewHolder();
                holder.titel = (TextView) vi.findViewById(R.id.titel); // naam
                vi.setTag(holder);
            } else {
                holder = (ViewHolder) vi.getTag();
            }
            if (holder.titel != null)
                holder.titel.setText(TvGids.get(position).get("datum")); // naam
            return vi;
        } else {
            if (convertView == null) {
                vi = inflater.inflate(R.layout.list_row_tvgids, null);
                holder = new ViewHolder();
                holder.poster =(ImageView)vi.findViewById(R.id.poster); // poster
                holder.zenderlogo =(ImageView)vi.findViewById(R.id.ZenderLogo); // poster
                holder.titel = (TextView) vi.findViewById(R.id.titel); // naam
                holder.starttijd = (TextView) vi.findViewById(R.id.starttijd); // naam
                holder.loader =(ProgressBar)vi.findViewById(R.id.progress); // progressbar
                vi.setTag(holder);
            } else {
                holder = (ViewHolder) vi.getTag();
            }

            if (holder.poster != null & holder.loader != null)
                    if(!TvGids.get(position).get("film_key").contains("TV") && !TvGids.get(position).get("film_key").contains("BS")) {
                        holder.poster.setVisibility(View.INVISIBLE);
                        aq.id(holder.poster).progress(holder.loader).image("http://cdn.be/hosting/movie/" + TvGids.get(position).get("film_key") + "/null/200/poster.jpg", false, true, 0, R.drawable.poster_x, null, AQuery.FADE_IN_NETWORK);
                    } else {
                        holder.loader.setVisibility(View.INVISIBLE);
                    }
            if (holder.zenderlogo != null)
                aq.id(holder.zenderlogo).image("http://cdn.be/hosting/zender/rw.php?zender=" + TvGids.get(position).get("zender") + "&size=166&opacity=50", false, true, 0, 0, null, AQuery.FADE_IN);
            if (holder.starttijd != null)
                holder.starttijd.setText(TvGids.get(position).get("starttijd")); // naam
            if (holder.titel != null)
                holder.titel.setText(TvGids.get(position).get("titel")); // naam
            return vi;
        }
    }

    static class ViewHolder{
        TextView starttijd;
        TextView titel;
        ImageView poster;
        ImageView zenderlogo;
        ProgressBar loader;
    }
}

Solution

  • Right now your ListView doesn't know the difference between a header and a normal item. It thinks all your items are the same. This will cause problems when you actually start recycling views, because you will get the wrong row layout as the convertView.

    You need to do either of the following strategies:

    1. Use getItemViewType() and getViewTypeCount(). With these methods ListView will now know there are different item types and will recycle them correctly, but it requires that getCount() return the number of items PLUS the number of headers (I'm not sure if your current implementation does this or not). I would refer you to a video called The World of ListView that explains this in more detail.

    2. Put the header in the layout XML for a regular item and use only this layout. Make the header visibility GONE by default. If the item should show a header, set the header visibility to VISIBLE. This uses one layout for all list items, at the expense of having some extra views in your view hierarchy.

    Basically, #1 correctly implements two different types of list item, whereas #2 does the opposite by making your list items actually the same item.


    There is another alternative: Use RecyclerView and implement the headers using an ItemDecoration instead. I'll leave you to explore this on your own.