具有不同布局样式的列表视图回收
listview recycling with difrent layout styles
我有一个包含不同样式项目的列表视图,一个带有日期的 header 样式(黑色)和一个用于该日期项目的项目阶梯。
现在我向下滚动信息不在正确的项目中。有时标题会出现在黑条中,有时日期会出现在项目栏中。
还有就是图片不对。我在我正在构建的应用程序中使用了这样的列表视图适配器,但从未使用过,这是我第一次在单个列表视图中使用不同的布局。
我使用 Aquery 加载图像。
请指出我的错误。
祝贺
活页夹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;
}
}
请覆盖 BaseAdapter 的 getItemViewType()
。
并尝试以下代码。
public int getItemViewType (int position) {
if(TvGids.get(position).get("header").equals("true")){
return 0;
}else{
return 1;
}
}
现在您的 ListView 不知道 header 和普通项目之间的区别。它认为你所有的物品都是一样的。当您实际开始回收视图时,这会导致问题,因为您会得到错误的行布局,如 convertView
.
您需要执行以下任一策略:
使用getItemViewType()
和getViewTypeCount()
。使用这些方法 ListView
现在将知道有不同的项目类型并将正确回收它们,但它需要 getCount()
return 项目数量加上 header 数量(我不确定您当前的实现是否这样做)。我建议您观看名为 The World of ListView 的视频,该视频对此进行了更详细的解释。
将 header 放入常规项目的布局 XML 中,并仅使用此布局。默认情况下使 header 可见性 GONE
。如果该项目应显示 header,请将 header 可见性设置为 VISIBLE
。这对所有列表项使用一种布局,代价是在视图层次结构中有一些额外的视图。
基本上,#1 正确地实现了两种不同类型的列表项,而#2 则相反,使您的列表项实际上是同一个项目。
还有另一种选择:使用 RecyclerView
并使用 ItemDecoration
实现 header。我会让你自己去探索这个。
我有一个包含不同样式项目的列表视图,一个带有日期的 header 样式(黑色)和一个用于该日期项目的项目阶梯。
现在我向下滚动信息不在正确的项目中。有时标题会出现在黑条中,有时日期会出现在项目栏中。
还有就是图片不对。我在我正在构建的应用程序中使用了这样的列表视图适配器,但从未使用过,这是我第一次在单个列表视图中使用不同的布局。
我使用 Aquery 加载图像。
请指出我的错误。
祝贺
活页夹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;
}
}
请覆盖 BaseAdapter 的 getItemViewType()
。
并尝试以下代码。
public int getItemViewType (int position) {
if(TvGids.get(position).get("header").equals("true")){
return 0;
}else{
return 1;
}
}
现在您的 ListView 不知道 header 和普通项目之间的区别。它认为你所有的物品都是一样的。当您实际开始回收视图时,这会导致问题,因为您会得到错误的行布局,如 convertView
.
您需要执行以下任一策略:
使用
getItemViewType()
和getViewTypeCount()
。使用这些方法ListView
现在将知道有不同的项目类型并将正确回收它们,但它需要getCount()
return 项目数量加上 header 数量(我不确定您当前的实现是否这样做)。我建议您观看名为 The World of ListView 的视频,该视频对此进行了更详细的解释。将 header 放入常规项目的布局 XML 中,并仅使用此布局。默认情况下使 header 可见性
GONE
。如果该项目应显示 header,请将 header 可见性设置为VISIBLE
。这对所有列表项使用一种布局,代价是在视图层次结构中有一些额外的视图。
基本上,#1 正确地实现了两种不同类型的列表项,而#2 则相反,使您的列表项实际上是同一个项目。
还有另一种选择:使用 RecyclerView
并使用 ItemDecoration
实现 header。我会让你自己去探索这个。