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