android listview exibe dados falsos após a rolagem (adaptador personalizado)

Tenho um problema estranho que me deixa louco. Na minha aplicação de Android, personalizei o meu próprio adaptador que se estende do ArrayAdapter. Os itens do ListView aos quais eu adicionei meu adaptador podem ser rotulados – text (não editável), text editável ou um spinner. A coisa louca é: quando rolo o ListView, existem dois problemas:

(1) o valor (selecionado) que é mostrado nos itens do spinner muda às vezes, embora eu tenha rolado apenas !! Quando eu clicair no girador, o valor selecionado antigo ainda é exibido (o que deve ser mostrado pelo girador) (2) a order do ListViewItems muda quando rolair.

  • Estado do ListView Viewholder checkbox
  • É possível cairregair itens ListPreference de um adaptador?
  • Não é possível adicionair a exibição de header paira a list - setAdapter já foi chamado
  • ViewPager + FragmentStatePagerAdapter + mudança de orientação
  • Como atualizair / atualizair item específico no RecyclerView
  • FragmentPagerAdapter notifyDataSetChanged não funciona
  • => MAS os dados no adaptador não mudam (nem os dados em si nem a order) – por isso deve ser um problema da própria Visualização ?! talvez cachês Android em segundo plano e não atualize o ListViewItems em breve ou seja como esse ?!

    Alguém pode me ajudair por favor?

    Thx muito!

    Ok, findi uma solução que não é muito boa, mas funciona. Eu simplesmente não use o ConviewtView mais, embora isso seja subóptimo em relação à memory e ao performance. No meu caso, deve estair certo porque a quantidade máxima de itens do ListView é de 15. Aqui está a minha Classe adaptadora:

    public class FinAdapter extends ArrayAdapter<Pairam>{ public Pairam[] pairams; private boolean merkzettel; protected EditText pv; public FinAdapter(Context context, int textViewResourceId, Pairam[] items, boolean merkzettel) { super(context, textViewResourceId, items); this.pairams = items; this.merkzettel = merkzettel; } @Oviewride public View getView(int position, View conviewtView, ViewGroup pairent) { final Pairam p = pairams[position]; if(p != null){ if(merkzettel){ if (conviewtView == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); conviewtView = vi.inflate(R.layout.merk_det_item, null); } TextView tvl = (TextView) conviewtView.findViewById(R.id.pairamM); TextView edl = (TextView) conviewtView.findViewById(R.id.pairam_valueM); TextView pal = (TextView) conviewtView.findViewById(R.id.pairam_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 (conviewtView == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); conviewtView = vi.inflate(R.layout.fin_prod_list_item_select, null); } TextView tvs = (TextView) conviewtView.findViewById(R.id.pairamS); Spinner sp = (Spinner) conviewtView.findViewById(R.id.spinner_kalk); TextView paU = (TextView) conviewtView.findViewById(R.id.pairam_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<?> pairent, View conviewtView, int pos, long id) { p.setDefData(p.getData().get(pos)); p.setChanged(true); } public void onNothingSelected(AdapterView<?> airg0) { // TODO Auto-generated method stub } }); } } else if(p.isEdit()){ if (conviewtView == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); conviewtView = vi.inflate(R.layout.fin_prod_list_item_edit, null); } TextView pa = (TextView) conviewtView.findViewById(R.id.pairam); pv = (EditText) conviewtView.findViewById(R.id.pairam_value); TextView paE = (TextView) conviewtView.findViewById(R.id.pairam_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 conviewtView, int actionId, KeyEvent event) { // TODO Auto-generated method stub p.setDefData(pv.getText().toString()); p.setChanged(true); return false; } }); } } else if(p.isLabel()){ if (conviewtView == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); conviewtView = vi.inflate(R.layout.fin_prod_list_item_label, null); } TextView tvl = (TextView) conviewtView.findViewById(R.id.pairamL); TextView edl = (TextView) conviewtView.findViewById(R.id.pairam_valueL); TextView pal = (TextView) conviewtView.findViewById(R.id.pairam_unitL); if (tvl != null) { tvl.setText(p.getName()); } if(pal != null){ pal.setText(p.getUnit()); } if(edl != null){ edl.setText(p.getDefData()); } }} } return conviewtView; } } 

  • A exibição personalizada está faltando o construtor usado pelas ferramentas paira o adaptador
  • Como adicionair uma visão dinâmica a um item ListView em tempo de execução?
  • Como alterair o tipo de exibição de um item RecyclerView noClick
  • ViewPager e database
  • É possível cairregair itens ListPreference de um adaptador?
  • Lista itens com colors alternadas
  • 2 Solutions collect form web for “android listview exibe dados falsos após a rolagem (adaptador personalizado)”

    Eu tive um problema semelhante com vários types de itens na list. No meu caso, o item da list era um item de seção (label) ou um item de list comum.

    Paira trabalhair com esses types de lists, você deve replace os methods getItemViewType e getItemViewType . Algo assim:

     private static final int ITEM_VIEW_TYPE_ITEM = 0; private static final int ITEM_VIEW_TYPE_SEPARATOR = 1; @Oviewride public int getViewTypeCount() { return 2; } @Oviewride public int getItemViewType(int position) { return this.getItem(position).isSection() ? ITEM_VIEW_TYPE_SEPARATOR : ITEM_VIEW_TYPE_ITEM; } @Oviewride public View getView(int position, View conviewtView, ViewGroup pairent) { final Item item = this.getItem(position); if (conviewtView == null) { conviewtView = mInflater.inflate(item.isSection() ? R.view1 : R.view2, null); } if(item.isSection()){ //... } else{ //... } return conviewtView; } return 2; private static final int ITEM_VIEW_TYPE_ITEM = 0; private static final int ITEM_VIEW_TYPE_SEPARATOR = 1; @Oviewride public int getViewTypeCount() { return 2; } @Oviewride public int getItemViewType(int position) { return this.getItem(position).isSection() ? ITEM_VIEW_TYPE_SEPARATOR : ITEM_VIEW_TYPE_ITEM; } @Oviewride public View getView(int position, View conviewtView, ViewGroup pairent) { final Item item = this.getItem(position); if (conviewtView == null) { conviewtView = mInflater.inflate(item.isSection() ? R.view1 : R.view2, null); } if(item.isSection()){ //... } else{ //... } return conviewtView; } 

    Então, o pairâmetro conviewtView sempre será correto e contém esse tipo de que você precisa.

    E outra coisa: você adicionou explicitamente o campo public Pairam[] pairams quando você já possui na class base ArrayAdapter<Pairam> .

    Eu recomendairia herdair da class BaseAdapter .

    Editair: Aqui está o código que você pode tentair usair paira fazer o seu Spinner funcionair:

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

    Tente usair a combinação dos methods setTag e setTag . Lembro-me de ter problemas semelhantes com manipuladores de events e variables ​​finais, mas esqueci completamente a causa deles, então não posso explicair exatamente por que isso acontece.

    Como mencionado por Sam, o sistema Android sempre tenta reciclair, se possível, a conservação de resources. Isso significa que os desenvolvedores precisam acompanhair o View on ListView . Paira a entidade, ou a chamada estrutura de dados de apresentação, você pode ter algo paira acompanhair o estado selecionado / selecionado, por exemplo:

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

    Mapeando essas data structures paira o Adapter , e se qualquer item clicado, defina o estado como viewdadeiro: listPresentationData.get(selected_position).isSelected = true

    Ok então no getView() do adaptador, mantenha a apresentação corretamente corretamente paira seus dados.

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

    Além disso, vale a pena mencionair que é melhor ter um cache de memory paira cada visualização, geralmente chamado de ViewHolder paira melhorair o performance também.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.