Android 具有保持架模式的listview中的按钮

Android 具有保持架模式的listview中的按钮,android,listview,android-viewholder,Android,Listview,Android Viewholder,我有一个列表视图,每行包含一个botton 单击该按钮可打开一个对话框以进行单值选择 问题是当我向下移动列表时,按钮中的值正在移动。 第一个值每8行重复一次 以下是我的getView()代码: 公共静态类ViewHolder{ 公共按钮列表Acerada; } 公共视图getView(最终整数位置、视图转换视图、视图组父视图){ 最终持票人; 试一试{ if(convertView==null){ holder=新的ViewHolder(); LayoutInflater vi=(LayoutI

我有一个列表视图,每行包含一个botton

单击该按钮可打开一个对话框以进行单值选择

问题是当我向下移动列表时,按钮中的值正在移动。 第一个值每8行重复一次

以下是我的getView()代码:

公共静态类ViewHolder{
公共按钮列表Acerada;
}
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
最终持票人;
试一试{
if(convertView==null){
holder=新的ViewHolder();
LayoutInflater vi=(LayoutInflater)ctx
.getSystemService(上下文布局\充气机\服务);
convertView=vi.充气(R.layout.row\u lista\u表单,空);
holder.listacerada=(按钮)convertView
.findviewbyd(R.id.listacerada);
}
convertView.setTag(支架);
}否则{
holder=(ViewHolder)convertView.getTag();
}
holder.listacerada.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//获取列表值
字符串datoValido=metrica.getlForms().get(位置)
.getProducto().getDatoValido();
AlertDialog.Builder adb=新建AlertDialog.Builder(ctx);
//干草:干草;不干草:不干草
String[]parts=datoValido.split(“;”);
ArrayList值=新的ArrayList();
用于(字符串s:零件){
字符串[]part2=s.split(“:”);
添加(第2部分[0]);
}
最终字符序列[]项=值
.toArray(新的字符序列[values.size()]);
adb.设置SingleChoiceItems(项目,0,
新建DialogInterface.OnClickListener(){
@凌驾
公共void onClick(对话框接口对话框,
int(其中){
dialog.dismise();
holder.listacerada.setText(项目[其中]);
}
});
adb.setNegativeButton(“取消”,空);
adb.show();
}
});
}捕获(例外e){
e、 printStackTrace();
}
返回视图;
}

由于视图是循环使用的,因此仅在convertView==null时设置OnClickListener。请参阅以下更新的代码:

public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    try {
        if (convertView == null) {
            holder = new ViewHolder();
            LayoutInflater vi = (LayoutInflater) ctx
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.row_lista_form, null);

            holder.listaCerrada = (Button) convertView
                    .findViewById(R.id.listaCerrada);
            }

            holder.listaCerrada.setOnClickListener(new OnClickListener() {

               @Override
               public void onClick(View v) {
                  // Get list Values
                  String datoValido = metrica.getlForms().get(position)
                        .getProducto().getDatoValido();
                  AlertDialog.Builder adb = new AlertDialog.Builder(ctx);
                  // HAY:HAY;NO HAY:NO HAY
                  String[] parts = datoValido.split(";");
                  ArrayList<String> values = new ArrayList<String>();
                  for (String s : parts) {
                     String[] part2 = s.split(":");
                     values.add(part2[0]);
                  }

                  final CharSequence[] items = values
                        .toArray(new CharSequence[values.size()]);

                  adb.setSingleChoiceItems(items, 0,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                  int which) {
                               dialog.dismiss();

                               holder.listaCerrada.setText(items[which]);
                            }

                        });
                  adb.setNegativeButton("Cancelar", null);


                  adb.show();

               }
            });

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

    } catch (Exception e) {
        e.printStackTrace();
    }
    return convertView;
}
public View getView(最终int位置、视图转换视图、视图组父视图){
最终持票人;
试一试{
if(convertView==null){
holder=新的ViewHolder();
LayoutInflater vi=(LayoutInflater)ctx
.getSystemService(上下文布局\充气机\服务);
convertView=vi.充气(R.layout.row\u lista\u表单,空);
holder.listacerada=(按钮)convertView
.findviewbyd(R.id.listacerada);
}
holder.listacerada.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//获取列表值
字符串datoValido=metrica.getlForms().get(位置)
.getProducto().getDatoValido();
AlertDialog.Builder adb=新建AlertDialog.Builder(ctx);
//干草:干草;不干草:不干草
String[]parts=datoValido.split(“;”);
ArrayList值=新的ArrayList();
用于(字符串s:零件){
字符串[]part2=s.split(“:”);
添加(第2部分[0]);
}
最终字符序列[]项=值
.toArray(新的字符序列[values.size()]);
adb.设置SingleChoiceItems(项目,0,
新建DialogInterface.OnClickListener(){
@凌驾
公共void onClick(对话框接口对话框,
int(其中){
dialog.dismise();
holder.listacerada.setText(项目[其中]);
}
});
adb.setNegativeButton(“取消”,空);
adb.show();
}
});
convertView.setTag(支架);
}否则{
holder=(ViewHolder)convertView.getTag();
}
}捕获(例外e){
e、 printStackTrace();
}
返回视图;
}

此页面提供的简易解决方案:


Android会在您滚动以节省内存时回收视图。不要使用convertView,而是创建一个新的视图v=vi。充气(…)。使用convertView是为了获得更好的性能。它应该有一种方法来修复它,而无需在每一行中创建视图。否则,我的列表将不会流畅。您实现了getItemType()吗?下面是一个答案,其中包含了许多关于正确实现自定义ListView适配器的有用信息。对于链接,它是非常有用的,但我知道getItemType适用于每个单元格的不同布局。我错了吗?我想你基本上要做的是在使用customView之前重置它。这样,您就知道以前保存的数据(如果有的话)被清除了。getView()中的position变量包含控件为显示内容而请求的位置信息。当用户与行上的按钮交互时,不会调用getView()。因此,在ViewHolder对象中保存位置值,并设置值
holder.pos=position在if(convertView==null)块之外。在OnClickListener中使用
holder.pos
,而不是
position
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    try {
        if (convertView == null) {
            holder = new ViewHolder();
            LayoutInflater vi = (LayoutInflater) ctx
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.row_lista_form, null);

            holder.listaCerrada = (Button) convertView
                    .findViewById(R.id.listaCerrada);
            }

            holder.listaCerrada.setOnClickListener(new OnClickListener() {

               @Override
               public void onClick(View v) {
                  // Get list Values
                  String datoValido = metrica.getlForms().get(position)
                        .getProducto().getDatoValido();
                  AlertDialog.Builder adb = new AlertDialog.Builder(ctx);
                  // HAY:HAY;NO HAY:NO HAY
                  String[] parts = datoValido.split(";");
                  ArrayList<String> values = new ArrayList<String>();
                  for (String s : parts) {
                     String[] part2 = s.split(":");
                     values.add(part2[0]);
                  }

                  final CharSequence[] items = values
                        .toArray(new CharSequence[values.size()]);

                  adb.setSingleChoiceItems(items, 0,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                  int which) {
                               dialog.dismiss();

                               holder.listaCerrada.setText(items[which]);
                            }

                        });
                  adb.setNegativeButton("Cancelar", null);


                  adb.show();

               }
            });

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

    } catch (Exception e) {
        e.printStackTrace();
    }
    return convertView;
}
if (convertView == null) {
...
}else{
       holder = (ViewHolder) convertView.getTag();
 // ADD THIS
        Formulario f = lForm.get(position);
        String cantidad = f.getCantidad();
        holder.listaCerrada.setText(cantidad);


}