Android的ListView的滚动后显示虚假的数据(自定义适配器)(android listvi

2019-06-27 02:02发布

我已经得到了我逼疯了一个奇怪的问题。 在我的Android应用程序,我定制我自己的适配器,从ArrayAdapter延伸。 ListView中的项目,我将我的适配器可以被标记文本(不可编辑),可编辑的文本或微调。 疯狂的东西是:当我滚动ListView中,有两个问题:

(1)在所说的纺丝器的项目中示出的(所选择的) 有时会发生变化 ,虽然我只滚动!! 当我点击微调,老选定值仍显示(一,应由微调显示)(2)的ListViewItems 变化顺序 ,当我滚动!

=>但在适配器中的数据不改变 (无论是数据本身也不量级) -因此它必须是视图本身的问题? 在后台,也许安卓缓存和不刷新ListViewItems很快或某事像那?

任何人可以帮助我吗?

多谢!

好吧,我已经找到了解决方案,它是不是很漂亮,但它的工作原理。 我根本就没有用了convertView虽然,关于内存和性能是次优的。 在我的情况下,它应该是OK的,因为我的ListView的最大项目金额15.这是我的适配器级:

 public class FinAdapter extends ArrayAdapter<Param>{
    public Param[] params;
    private boolean merkzettel;
    protected EditText pv;

    public FinAdapter(Context context, int textViewResourceId, Param[] items, boolean merkzettel) {
        super(context, textViewResourceId, items);
        this.params = items;
        this.merkzettel = merkzettel;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final Param p = params[position];
        if(p != null){
            if(merkzettel){
                if (convertView == null) {
                    LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    convertView = vi.inflate(R.layout.merk_det_item, null);
                }
                TextView tvl = (TextView) convertView.findViewById(R.id.paramM);
                TextView edl = (TextView) convertView.findViewById(R.id.param_valueM);
                TextView pal = (TextView) convertView.findViewById(R.id.param_unitM);
                if (tvl != null) {
                    tvl.setText(p.getName());                            
                }
                if(pal != null){
                    pal.setText(p.getUnit());
                }
                if(edl != null){
                    edl.setText(p.getDefData());
                }
            }
            else{
                if(p.isSelect()){

                if (convertView == null) {
                    LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    convertView = vi.inflate(R.layout.fin_prod_list_item_select, null);
                }            
                TextView tvs = (TextView) convertView.findViewById(R.id.paramS);
                Spinner sp = (Spinner) convertView.findViewById(R.id.spinner_kalk);
                TextView paU = (TextView) convertView.findViewById(R.id.param_unitS);


                if (tvs != null) {
                    tvs.setText(p.getName());                            
                }
                if(paU != null){
                    paU.setText(p.getUnit());
                }
                if(sp != null){
                    String[] values = new String[p.getData().size()];
                    for(int i=0; i<values.length; i++){
                        values[i] = p.getData().get(i);
                    }
                    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_spinner_item, values);
                    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    sp.setAdapter(adapter);
                    sp.setSelection(p.getData().indexOf(p.getDefData()));
                    sp.setOnItemSelectedListener(new OnItemSelectedListener(){
                        public void onItemSelected(AdapterView<?> parent,
                                View convertView, int pos, long id) {
                            p.setDefData(p.getData().get(pos));
                            p.setChanged(true);
                        }
                        public void onNothingSelected(AdapterView<?> arg0) {
                            // TODO Auto-generated method stub

                        }

                    });
                }
            }       
            else if(p.isEdit()){
                if (convertView == null) {
                    LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    convertView = vi.inflate(R.layout.fin_prod_list_item_edit, null);
                }
                TextView pa = (TextView) convertView.findViewById(R.id.param);
                pv = (EditText) convertView.findViewById(R.id.param_value);
                TextView paE = (TextView) convertView.findViewById(R.id.param_unit);
                if (pa != null) {
                    pa.setText(p.getName());                            
                }
                if(paE != null){
                    paE.setText(p.getUnit());
                }
                if(pv != null){
                    pv.setText(p.getDefData());
                    pv.setOnEditorActionListener(new OnEditorActionListener(){
                        public boolean onEditorAction(TextView convertView, int actionId,
                                KeyEvent event) {
                            // TODO Auto-generated method stub
                            p.setDefData(pv.getText().toString());
                            p.setChanged(true);
                            return false;
                        }                   
                    }); 
                }

            }
            else if(p.isLabel()){
                if (convertView == null) {
                    LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    convertView = vi.inflate(R.layout.fin_prod_list_item_label, null);
                }
                TextView tvl = (TextView) convertView.findViewById(R.id.paramL);
                TextView edl = (TextView) convertView.findViewById(R.id.param_valueL);
                TextView pal = (TextView) convertView.findViewById(R.id.param_unitL);
                if (tvl != null) {
                    tvl.setText(p.getName());                            
                }
                if(pal != null){
                    pal.setText(p.getUnit());
                }
                if(edl != null){
                    edl.setText(p.getDefData());
                }   
            }}
        }
        return convertView;
    }
}

Answer 1:

我曾与列表中的多个项目类型类似的问题。 在我的情况列表项要么一个部分(标签)项目或一个共同列表项。

为了与这样类型的列表,您应该重写getViewTypeCountgetItemViewType方法。 事情是这样的:

private static final int ITEM_VIEW_TYPE_ITEM = 0;
private static final int ITEM_VIEW_TYPE_SEPARATOR = 1;

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return this.getItem(position).isSection() ? ITEM_VIEW_TYPE_SEPARATOR : ITEM_VIEW_TYPE_ITEM;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final Item item = this.getItem(position);

    if (convertView == null) {
        convertView = mInflater.inflate(item.isSection() ? R.view1 : R.view2, null);
    }

    if(item.isSection()){
        //...
    }
    else{
        //...
    }

    return convertView;
}

然后convertView参数将始终是正确的,并且包含类型,你所需要的。

而另一件事:你明确添加了public Param[] params当你已经拥有它的基类领域ArrayAdapter<Param>

我建议从继承BaseAdapter类。

编辑:这是你可以尝试,以用它让你的代码Spinner工作:

sp.setTag(p);
sp.setOnItemSelectedListener(new OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> parent, View convertView, int pos, long id) {
    Param currentItem = (Param)parent.getTag();
    currentItem.setDefData(currentItem.getData().get(pos));
    currentItem.setChanged(true);
}
//...

尝试使用的组合getTagsetTag方法。 我记得我曾与事件处理程序和最终的变量类似的问题,但我完全忘记了他们的事业,所以我无法解释到底为什么会这样。



Answer 2:

正如萨姆提到,Android系统总是试图可能情况下回收,以节约资源。 这意味着,开发人员需要跟踪的ViewListView自己。 对于实体,或所谓的演示数据结构,你可以有一些跟踪所选/取消选择状态,例如:

class PresentationData {
    // other stuffs..
    boolean isSelected = false;
}

映射这些数据结构的Adapter ,并且如果任何项点击,状态设置为真: listPresentationData.get(selected_position).isSelected = true

好了,所以在getView()适配器,保持正确跟踪演示为您的数据。

if(listPresentationData.get(position).isSelected) 
{ 
    // set background color of the row layout..or something else 
}

此外,值得一提的是更好地对每一个意见,通常被称为内存缓存ViewHolder以提高性能为好。



文章来源: android listview displays false data after scrolling (custom adapter)