【问题标题】:List item repeating in android customized listview列表项在android自定义列表视图中重复
【发布时间】:2013-10-01 22:07:40
【问题描述】:

在我的自定义列表视图中,项目是重复的。项目的位置对于所有项目都是相同的。 代码如下

ListAdapter.java-

    public class ListAdapter extends BaseAdapter{

    private List<String> mName;
private List<Drawable> mIcon;
private Context mContext;

public ListAdapter(Context mContext, List<String> Name, List<Drawable> Icon) {
    this.mContext=mContext;
    this.mName=Name;
    this.mIcon=Icon;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return mName.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public View getView(final int position, View v, ViewGroup parent) {

    View mLayout;
    TextView mText;
    ImageView mImage;
    CheckBox mCheckBox;

    if(v==null){
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mLayout=new View(mContext);
        mLayout=(LinearLayout) inflater.inflate(R.layout.list_menu, null);

        mText=(TextView) mLayout.findViewById(R.id.Name);
        mImage=(ImageView) mLayout.findViewById(R.id.Icon);
        mCheckBox=(CheckBox) mLayout.findViewById(R.id.mCheckbox);

        mText.setText(mName.get(position));
        mImage.setImageDrawable(mIcon.get(position));

        mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton check, boolean isChecked) {
                if(check.isChecked()){
                    Toast.makeText(mContext, "..."+mName.get(position)+"..."+position, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }   
    else{
        mLayout=(View)v;
    }
    return mLayout;
}

  }

【问题讨论】:

  • 那么问题到底是什么?
  • listview 项目重复。假设 A,B,C,D 是列表项,则显示 A,B,C,D,A,B,C,D

标签: android listview baseadapter


【解决方案1】:

试试这个,每个转换视图都需要setTag()

 @Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder mHolder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_menu, null);
        mHolder = new ViewHolder();

        mHolder.mText=(TextView) convertView.findViewById(R.id.appName);
        mHolder.mImage=(ImageView) convertView.findViewById(R.id.appIcon);
        mHolder.mCheckBox=(CheckBox) convertView.findViewById(R.id.mCheckbox);

        convertView.setTag(mHolder);

    } else {
        mHolder = (ViewHolder) convertView.getTag();
    }

    return convertView;
}

private class ViewHolder {
    private TextView mText;
    private ImageView mImage;
    private CheckBox mCheckBox;

}

【讨论】:

  • developer.android.com/training/improving-layouts/…。它的视图持有者不仅 setTag。并且视图持有者必须是静态的,为什么视图持有者是最终的?
  • @Raghunandan 感谢您的提示
  • 我几乎吃掉了我的牙齿。谢谢,现在我可以睡觉了;p
【解决方案2】:

改变你的getView

 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mLayout=new View(mContext);
    mLayout=(LinearLayout) inflater.inflate(R.layout.list_menu, null);

在您的构造函数中初始化充气机。删除此 mLayout=new View(mContext) 因为您正在使用 mLayout=(LinearLayout) inflater.inflate(R.layout.list_menu, null) 扩展布局

在你的构造函数中

LayoutInflater inflater;
public ListAdapter(Context mContext, List<String> Name, List<Drawable> Icon) {
this.inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mContext=mContext;
this.mName=Name;
this.mIcon=Icon;
}

使用 View holder 来实现平滑滚动和性能。

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    ViewHolder vh;
    if(convertView==null){
        vh = new ViewHolder();
        convertView =(LinearLayout) inflater.inflate(R.layout.list_menu, null);

        vh.mText=(TextView) convertView.findViewById(R.id.Name);
        vh.mImage=(ImageView) convertView.findViewById(R.id.Icon);
        vh.mCheckBox=(CheckBox) convertView.findViewById(R.id.mCheckbox);

        convertView.setTag(vh); 
    } else { 
        vh = (ViewHolder) convertView.getTag(); 
    } 

    vh.mText.setText(mName.get(position));
    vh.mImage.setImageDrawable(mIcon.get(position));
    vh.mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton check, boolean isChecked) {
            if(check.isChecked()){
                Toast.makeText(mContext, "..."+mName.get(position)+"..."+position, Toast.LENGTH_SHORT).show();
            }
        }
    });
    return convertView;
}

static class ViewHolder
{
    TextView mText;
    ImageView mImage;
    CheckBox mCheckBox;
}

【讨论】:

    【解决方案3】:
    // try this
     public class ListAdapter extends BaseAdapter {
    
            private List<String> mName;
            private List<Drawable> mIcon;
            private Context mContext;
    
            public ListAdapter(Context mContext, List<String> Name, List<Drawable> Icon) {
                this.mContext=mContext;
                this.mName=Name;
                this.mIcon=Icon;
            }
    
            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return mName.size();
            }
    
            @Override
            public Object getItem(int position) {
                // TODO Auto-generated method stub
                return position;
            }
    
            @Override
            public long getItemId(int position) {
                // TODO Auto-generated method stub
                return position;
            }
    
            @Override
            public View getView(final int position, View v, ViewGroup parent) {
    
                ViewHolder holder;
    
                if(v==null){
                    holder = new ViewHolder();
                    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v =(LinearLayout) inflater.inflate(R.layout.list_menu, null);
    
                    holder.mText=(TextView) v.findViewById(R.id.Name);
                    holder.mImage=(ImageView) v.findViewById(R.id.Icon);
                    holder.mCheckBox=(CheckBox) v.findViewById(R.id.mCheckbox);
    
                  v.setTag(holder);
                }
                else{
                   holder = (ViewHolder) v.getTag();
                }
                holder.mText.setText(mName.get(position));
                holder.mImage.setImageDrawable(mIcon.get(position));
    
                holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
                    @Override
                    public void onCheckedChanged(CompoundButton check, boolean isChecked) {
                        if(check.isChecked()){
                            Toast.makeText(mContext, "..."+mName.get(position)+"..."+position, Toast.LENGTH_SHORT).show();
                        }
                    }
                });
                v.setTag(holder);
                return v;
            }
    
             class ViewHolder{
                TextView mText;
                ImageView mImage;
                CheckBox mCheckBox;
            }
    
        }
    

    【讨论】:

    • v.setTag(holder); 在您的if(v==null) 语句中将导致NPE。
    • @Shubham,请检查我更新的答案并感谢您强调它。
    【解决方案4】:

    确保 convertView 不为空。因此将所有代码放在 if(convertView == null){ 之后 } 这确保你有一个值不为 null 的 convertView,如果是的话,通过从上下文中膨胀。

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
    
      if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.list_menu, parent, false);
      } 
    
      TextView mText=(TextView) convertView.findViewById(R.id.appName);
      ImageView mImage=(ImageView) convertView.findViewById(R.id.appIcon);
      CheckBox mCheckBox=(CheckBox) convertView.findViewById(R.id.mCheckbox);
    
      mText.setText(mName.get(position));
      mImage.setImageDrawable(mIcon.get(position));
    
      return convertView;
    }
    

    【讨论】:

    • contextView 不应为空。因此在 if(convertView == null){} 之后查找视图将解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多