android - ListView "coming back" when scrolling -


i'm getting strange behavior in listview, , 1 listview, have lot of listviews in app, in happening.

i try explain, when scroll bottom, right, scrolls go , stop in end. when scroll top, it's scroll splash in top , come bottom.

i have this video showing problem.

this xml of listview:

<listview     android:id="@+id/lv_resultado_produtos"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:divider="@color/black"     android:dividerheight="1dip"     android:fastscrollenabled="true"     android:scrollx="0dip"     android:scrolly="0dip"     android:scrollbarsize="22dip"     android:scrollbarstyle="outsideoverlay" /> 

and programmatically set adapter customadapter, nothing more.

i tested in others listviews , didn't behavior.

i glad if me on this.

[edit]

here adapter, it's little complex, sorry, tried keep have limitation in size of characters:

[package]  [imports]  public class customadapter_produto_insercao extends arrayadapter<produto_insercao> {      static view view_aux = null;      static onclicklistener listener_convertview = null;     static onclicklistener listener_btn_editar_produto = null;      static activity ctx;      static dialog_tw ad_estoque;      static list<condicao_preco> list_tabela_preco_condicao;      public static boolean clickable = true;      public static boolean highlight = false;      public static int linha_atual = 0;      public static view view_atual = null;         static boolean id_margem = false;     static boolean id_destaca_ipi = false;     static string ls_id_tipo_regime;     static integer li_cd_cliente;      static string caminho_foto;      static decimalformat decimalformat = null;      static repositorio repositorio;      static condicao_preco c_p_null;      static boolean innotify = false;      private final layoutinflater inflater;      private final int resourceid;      public void setclickable(boolean b){         clickable = b;     }      public customadapter_produto_insercao setid_margem(boolean id_margem){         this.id_margem = id_margem;         return this;     }      public customadapter_produto_insercao sethighlight(boolean highlight){         this.highlight = highlight;         return this;     }      public customadapter_produto_insercao setlistener_convertview(onclicklistener listener){         this.listener_convertview = listener;         return this;     }      public customadapter_produto_insercao setlistener_btn_editar_produto(onclicklistener listener){         this.listener_btn_editar_produto = listener;         return this;     }      public customadapter_produto_insercao(activity context, int resource, list<produto_insercao> objects, list<condicao_preco> list_tabela_preco_condicao, string ls_id_tipo_regime, integer li_cd_cliente) {          super(context, resource, objects);          ctx = context;          this.list_tabela_preco_condicao = list_tabela_preco_condicao;          this.inflater = layoutinflater.from(context);         this.resourceid = resource;         this.ls_id_tipo_regime = ls_id_tipo_regime;         this.li_cd_cliente = li_cd_cliente;          decimalformatsymbols decimalformatsymbols = new decimalformatsymbols();         decimalformatsymbols.setdecimalseparator(',');         decimalformatsymbols.setgroupingseparator('.');              decimalformat = new decimalformat("#,##0.00", decimalformatsymbols);          repositorio = new repositorio(ctx);         string s_id_margem = repositorio.parametro_getvalue("id_margem");         if(s_id_margem != null && s_id_margem.equals("s")){             id_margem = true;         }          string s_id_destaca_ipi = repositorio.parametro_getvalue("id_destaca_ipi");         if(s_id_destaca_ipi != null && s_id_destaca_ipi.equals("s")){             id_destaca_ipi = true;         }          for(produto_insercao p_i : objects){             if(p_i.getqt_pedida() == null || p_i.getqt_pedida() == 0d){                 p_i.setid_selecionado(false);                 p_i.setid_tabela_condicao_preco(-1);                 p_i.setcd_tabela_preco_condicao(-1);             } else {                 p_i.setid_selecionado(true);             }         }          caminho_foto = repositorio.parametro_getvalue("caminho_foto");          c_p_null = new condicao_preco();         c_p_null.setcd_condicao_preco(0);         c_p_null.setcd_tabela_preco_condicao(0);         c_p_null.setds_condicao_preco("selecione");         c_p_null.setid_promocao("n");         c_p_null.setid_fake(true);     }      private static class viewholder {         public int     position;          public textview            cd_produto;         public textview            ds_produto;         public textview            ds_unidade;         public button              btn_vl_saldo;         public spinner             spn_tabela_condicao_preco;         public textview            vl_unidade_unitario;         public textview            vl_unitario;         public button              qt_produto_menos;         public button              qt_produto_mais;         public edittext_decimal_tw qt_produto;         public textview            vl_total;         public button              btn_editar_produto;         public textview            vl_custo;         public textview            pr_ipi;         public imagebutton         foto_produto;          public button              mais_opcoes;     }      @override     public void notifydatasetchanged() {         innotify = true;          boolean b = false;         if(view_aux != null && view_aux.ispressed()){             b = true;         }           super.notifydatasetchanged();          if(b){             view_aux.requestfocus();             view_aux.setpressed(true);             view_aux.setselected(true);         }          innotify = false;     }      public view getview(final int position, view convertview, viewgroup parent) {         final viewholder viewholder;          final produto_insercao p = getitem(position);          if(p.getcd_tabela_preco_condicao() == -1){             p.setid_selecionado(false);         } else {             p.setid_selecionado(true);         }          if (convertview == null) {             convertview = inflater.inflate(resourceid, parent, false);              viewholder = new viewholder();              viewholder.cd_produto                = (textview)            convertview.findviewbyid(r.id.cd_produto);             viewholder.ds_produto                = (textview)            convertview.findviewbyid(r.id.ds_produto);             viewholder.ds_unidade                = (textview)            convertview.findviewbyid(r.id.ds_unidade);             viewholder.btn_vl_saldo              = (button)              convertview.findviewbyid(r.id.btn_vl_saldo);             viewholder.spn_tabela_condicao_preco = (spinner)             convertview.findviewbyid(r.id.spn_tabela_condicao_preco);             viewholder.vl_unidade_unitario       = (textview)            convertview.findviewbyid(r.id.vl_unidade_unitario);             viewholder.vl_unitario               = (textview)            convertview.findviewbyid(r.id.vl_unitario);             viewholder.qt_produto_menos          = (button)              convertview.findviewbyid(r.id.qt_produto_menos);             viewholder.qt_produto_mais           = (button)              convertview.findviewbyid(r.id.qt_produto_mais);             viewholder.qt_produto                = (edittext_decimal_tw) convertview.findviewbyid(r.id.qt_produto);             viewholder.vl_total                  = (textview)            convertview.findviewbyid(r.id.vl_total);             viewholder.btn_editar_produto        = (button)              convertview.findviewbyid(r.id.btn_editar_produto);             viewholder.vl_custo                  = (textview)            convertview.findviewbyid(r.id.vl_custo);             viewholder.pr_ipi                    = (textview)            convertview.findviewbyid(r.id.pr_ipi);             viewholder.foto_produto              = (imagebutton)         convertview.findviewbyid(r.id.foto_produto);              viewholder.mais_opcoes               = (button)              convertview.findviewbyid(r.id.mais_opcoes);              boolean id_mobile_utiliza_valor_unitario = false;             string s_id_mobile_utiliza_valor_unitario = repositorio.parametro_getvalue("id_mobile_utiliza_valor_unitario");             if(s_id_mobile_utiliza_valor_unitario != null && s_id_mobile_utiliza_valor_unitario.equals("s")){                 id_mobile_utiliza_valor_unitario = true;             }             if(!id_mobile_utiliza_valor_unitario){                 viewholder.vl_unidade_unitario.setlayoutparams(new linearlayout.layoutparams(0, 0));                 linearlayout.layoutparams ll = new linearlayout.layoutparams(0, linearlayout.layoutparams.wrap_content, 13);                 viewholder.mais_opcoes.setlayoutparams(ll);             } else {                 linearlayout.layoutparams ll = new linearlayout.layoutparams(0, linearlayout.layoutparams.wrap_content, 15);                 viewholder.mais_opcoes.setlayoutparams(ll);             }              convertview.settag(viewholder);         } else {             viewholder = (viewholder) convertview.gettag();         }          repeater qt_produto_menos_repeater = new repeater(viewholder.qt_produto_menos);          viewholder.qt_produto_menos.setonlongclicklistener(qt_produto_menos_repeater);          repeater qt_produto_mais_repeater = new repeater(viewholder.qt_produto_mais);          viewholder.qt_produto_mais.setonlongclicklistener(qt_produto_mais_repeater);          if(p.isid_liberado()){             viewholder.mais_opcoes              .setvisibility(view.gone);              viewholder.qt_produto_menos         .setvisibility(view.visible);             viewholder.qt_produto_mais          .setvisibility(view.visible);             viewholder.qt_produto               .setvisibility(view.visible);             viewholder.spn_tabela_condicao_preco.setvisibility(view.visible);             viewholder.vl_unidade_unitario      .setvisibility(view.visible);             viewholder.vl_unitario              .setvisibility(view.visible);             viewholder.vl_total                 .setvisibility(view.visible);             viewholder.btn_editar_produto       .setvisibility(view.visible);         } else {             viewholder.mais_opcoes              .setvisibility(view.visible);              viewholder.qt_produto_menos         .setvisibility(view.gone);             viewholder.qt_produto_mais          .setvisibility(view.gone);             viewholder.qt_produto               .setvisibility(view.gone);             viewholder.spn_tabela_condicao_preco.setvisibility(view.gone);             viewholder.vl_unidade_unitario      .setvisibility(view.gone);             viewholder.vl_unitario              .setvisibility(view.gone);             viewholder.vl_total                 .setvisibility(view.gone);             viewholder.btn_editar_produto       .setvisibility(view.gone);              p.setid_liberado(false);         }          viewholder.mais_opcoes.setonclicklistener(new onclicklistener() {                        @override             public void onclick(view v) {                 p.setid_liberado(true);                  notifydatasetchanged();             }         });          viewholder.position = position;          if(!innotify)             new myasynctask(position, viewholder, convertview, p, this).executeonexecutor(asynctask.thread_pool_executor, null);          if(p.getqt_pedida() != null && p.getqt_pedida() > 0d){             convertview.setbackgroundresource(r.color.duapi_pressed);         } else {             convertview.setbackgroundresource(r.color.whitesmoke);         }          if(p.getvl_saldo() != null && p.getvl_saldo() > 0d){             viewholder.cd_produto                .settextcolor(color.black);             viewholder.ds_produto                .settextcolor(color.black);             viewholder.ds_unidade                .settextcolor(color.black);             viewholder.btn_vl_saldo              .settextcolor(color.black);         } else {             viewholder.cd_produto                .settextcolor(color.red);             viewholder.ds_produto                .settextcolor(color.red);             viewholder.ds_unidade                .settextcolor(color.red);             viewholder.btn_vl_saldo              .settextcolor(color.red);         }          if(highlight && position == linha_atual){             convertview.setbackgroundresource(r.color.duapi);         } else {             convertview.setbackgroundresource(r.drawable.listview_background);         }          return convertview;     }      private static class myasynctask extends asynctask {          private int              position;         private viewholder       viewholder;         private view             convertview;         private produto_insercao p;          private list<condicao_preco>           lista_tabela_preco_condicao;         private customadapter_produto_insercao madapter;         private spinneradapter_condicao_preco  adapter;          public myasynctask(int position, viewholder viewholder, view convertview, produto_insercao p, customadapter_produto_insercao madapter) {             this.position    = position;             this.viewholder  = viewholder;             this.convertview = convertview;             this.p           = p;             this.madapter    = madapter;              lista_tabela_preco_condicao = new arraylist<condicao_preco>();         }          @override         protected object doinbackground(object... params) {             if(p.isid_liberado()){                 viewholder.btn_editar_produto.setonclicklistener(new onclicklistener() {                                 @override                     public void onclick(view v) {                                        linha_atual = position;                         view_atual  = convertview;                          if(listener_btn_editar_produto != null){                             listener_btn_editar_produto.onclick(v);                         }                     }                 });                  viewholder.qt_produto_menos.setonclicklistener(new onclicklistener() {                               @override                     public void onclick(view v) {                         view_aux = viewholder.qt_produto_menos;                          double qt_anterior = viewholder.qt_produto.getvalor_double();                          viewholder.qt_produto.setvalor(viewholder.qt_produto.getvalor_double() - p.getfator_venda());                          //verifica se o produto não está na lista de itens pedido, se tiver não deixa zerar...                         if(pedidotabactivity2.find_produto_em_itens(p.getcd_produto())){                             if(viewholder.qt_produto.getvalor_double() <= 0d){                                 viewholder.qt_produto.setvalor(qt_anterior);                                 return;                             }                         }                          if(viewholder.qt_produto.getvalor_double() < 0d){                             viewholder.qt_produto.setvalor(0d);                         }                          p.setqt_pedida(viewholder.qt_produto.getvalor_double());                          calculainformacoes(false);                          if(!atualizaflex(p, 30)){                             viewholder.qt_produto.setvalor(qt_anterior);                             p.setqt_pedida(qt_anterior);                             atualizaflex(p, 10);                             calculainformacoes(false);                             return;                         }                     }                 });                  viewholder.qt_produto_mais.setonclicklistener(new onclicklistener() {                                @override                     public void onclick(view v) {                         view_aux = viewholder.qt_produto_menos;                          double qt_anterior = viewholder.qt_produto.getvalor_double();                          viewholder.qt_produto.setvalor(viewholder.qt_produto.getvalor_double() + p.getfator_venda());                          p.setqt_pedida(viewholder.qt_produto.getvalor_double());                          calculainformacoes(false);                          if(!atualizaflex(p, 30)){                             viewholder.qt_produto.setvalor(qt_anterior);                             p.setqt_pedida(qt_anterior);                             atualizaflex(p, 10);                             calculainformacoes(false);                             return;                         }                     }                 });                  lista_tabela_preco_condicao.add(c_p_null);                  lista_tabela_preco_condicao.addall(list_tabela_preco_condicao);                  if(p.getid_promocao() < 1){                     for(int = 0; < lista_tabela_preco_condicao.size(); i++){                         if(lista_tabela_preco_condicao.get(i).getid_promocao().equals("s")){                             lista_tabela_preco_condicao.remove(i--);                         }                     }                 }                  onitemselectedlistener onitemselectedlistener = new onitemselectedlistener() {                     @override                     public void onitemselected(adapterview<?> arg0, view arg1, int arg2, long arg3) {                                            selection(arg2);                     }                      @override                     public void onnothingselected(adapterview<?> arg0) {                         }                 };                  viewholder.spn_tabela_condicao_preco.setonitemselectedlistener(onitemselectedlistener);                  adapter = new spinneradapter_condicao_preco(ctx, android.r.layout.simple_spinner_item, lista_tabela_preco_condicao, ls_id_tipo_regime, p.getcd_tabela_preco(), p.getcd_produto(), li_cd_cliente);                 adapter.setdropdownviewresource(android.r.layout.simple_spinner_dropdown_item);             }              convertview.setonclicklistener(new onclicklistener() {                 public void onclick(view v) {                     if(!clickable){                         return ;                     }                      linha_atual = position;                     view_atual  = convertview;                      if(listener_convertview != null){                         listener_convertview.onclick(v);                     }                      p.setid_liberado(true);                      madapter.notifydatasetchanged();                 }             });              viewholder.btn_vl_saldo.setonclicklistener(new onclicklistener() {                           @override                 public void onclick(view v) {                     if(ad_estoque != null){                         return ;                     }                      ad_estoque = new dialog_tw(ctx);                      final dialog_tw ad_estoque_temp = ad_estoque;                     ad_estoque.setview(r.layout.layout_pedido_venda_tab_insercao_estoque);                     ad_estoque.settitle("consulta de estoque");                     ad_estoque.setcancelable(false);                      view view_estoque = ad_estoque.getview();                      textview ds_produto   = (textview) view_estoque.findviewbyid(r.id.ds_produto);                     button   btn_ok       = (button)   view_estoque.findviewbyid(r.id.btn_ok);                     listview lv_resultado = (listview) view_estoque.findviewbyid(r.id.lv_resultado);                     textview vl_total     = (textview) view_estoque.findviewbyid(r.id.vl_total);                      ds_produto.settext(p.tostring());                      btn_ok.setonclicklistener(new onclicklistener() {                                            @override                         public void onclick(view v) {                             ad_estoque_temp.getdialog(false, 50d).dismiss();                         }                     });                      ad_estoque.setondismisslistener(new ondismisslistener() {                                                        @override                         public void ondismiss(dialoginterface dialog) {                             ad_estoque = null;                              if(customadapter_pedido_venda_pendente_item_rascunho.editar){                                 customadapter_pedido_venda_pendente_item_rascunho.editar = false;                             }                         }                     });                      repositorio repositorio = new repositorio(ctx);                                                  list<saldo_estoque> lista_saldo_estoque = repositorio.generic_getlist(saldo_estoque.class,                                                                                "cd_produto = '" + p.getcd_produto() + "'",                                                                                 null,                                                                                null,                                                                                null,                                                                                "cd_empresa asc",                                                                                false);                     double total = 0d;                     for(saldo_estoque s_e : lista_saldo_estoque){                         list<empresa> lista_empresa = repositorio.generic_getlist(empresa.class,                                                                                    "cd_empresa = '" + s_e.getcd_empresa() + "'",                                                                                     null,                                                                                    null,                                                                                    null,                                                                                    null,                                                                                    false);                         empresa e = null;                         if(lista_empresa != null && lista_empresa.size() > 0){                             e = lista_empresa.get(0);                             s_e.setnm_reduzido(e.getnm_reduzido());                         }                         total += s_e.getqt_disponivel();                     }                     vl_total.settext(decimalformat.format(total));                      customadapter_estoque adapter_estoque = new customadapter_estoque(ctx, r.layout.layout_pedido_venda_tab_insercao_estoque_lista, lista_saldo_estoque).sethighlight(true);                     lv_resultado.setadapter(adapter_estoque);                      ad_estoque.getdialog(false, 50d).show();                                 }             });             return null;         }                            @override         protected void onpostexecute(object result) {              if(id_margem){                 viewholder.vl_custo.setvisibility(view.visible);                 viewholder.vl_custo.settext(p.getvl_custo_unitario() == null ? "-" : decimalformat.format(p.getvl_custo_unitario()));             }              if(id_destaca_ipi){                 viewholder.pr_ipi.setvisibility(view.visible);                 viewholder.pr_ipi.settext(decimalformat.format(p.getpr_ipi()));             }              if(caminho_foto != null && p.getid_foto() != null && p.getid_foto().equals("s")){                 viewholder.foto_produto.setvisibility(view.visible);                                 viewholder.foto_produto.setonclicklistener(new onclicklistener() {                               @override                     public void onclick(view v) {                         util.carregar_foto_produto(p.getcd_produto(), p.getds_produto(), p.getnm_foto(), ctx);                     }                 });             }              viewholder.cd_produto  .settext(p.getcd_produto());             viewholder.ds_produto  .settext(p.getds_produto());             viewholder.ds_unidade  .settext(p.getds_unidade_unitaria());             viewholder.btn_vl_saldo.settext(decimalformat.format(p.getvl_saldo()));              if(p.isid_liberado()){                 if(p.isid_selecionado()){                                        unidade u = null;                                        list<unidade> lista_unidade = repositorio.generic_getlist(unidade.class,                                "cd_unidade = " + p.getcd_unidade_embalagem(),                                 null,                                null,                                null,                                null,                                false);                     if(lista_unidade != null && lista_unidade.size() > 0){                         u = lista_unidade.get(0);                     }                            double vl_unidade_unitario = util.rounddouble(p.getvl_unitario() / (u != null ? u.getfator_conversao() : 1), 2);                     viewholder.vl_unidade_unitario.settext(decimalformat.format(vl_unidade_unitario));                     viewholder.vl_unitario.settext(decimalformat.format(p.getvl_unitario()));                     viewholder.vl_total   .settext(decimalformat.format(p.getvl_total()));                 } else {                     viewholder.vl_unidade_unitario.settext(" - ");                     viewholder.vl_unitario        .settext(" - ");                     viewholder.vl_total           .settext(" - ");                 }                  viewholder.qt_produto.setvalor(p.getqt_pedida() == null ? 0d : p.getqt_pedida());                  viewholder.spn_tabela_condicao_preco.setadapter(adapter);                  if(lista_tabela_preco_condicao.size() > 1){                     viewholder.spn_tabela_condicao_preco.setenabled(true);                 } else {                     viewholder.spn_tabela_condicao_preco.setenabled(false);                 }                  if(p.isid_selecionado()){                            viewholder.spn_tabela_condicao_preco.setselection(find_condicao_preco_position(lista_tabela_preco_condicao, p.getcd_tabela_preco_condicao()));                 } else {                     viewholder.spn_tabela_condicao_preco.setselection(0);                 }                  if(lista_tabela_preco_condicao == null || lista_tabela_preco_condicao.size() < 2){                     viewholder.btn_editar_produto.setenabled(false);                 } else {                     viewholder.btn_editar_produto.setenabled(true);                 }                  if(!p.isid_selecionado() && lista_tabela_preco_condicao.size() == 3){                     adapter.getdropdownview(2, null, null);                     viewholder.spn_tabela_condicao_preco.setselection(2);                 }             }              convertview.setclickable(true);             convertview.setfocusable(true);         }         private double calculainformacoes_getvl_unitario(){                  [only calculates values]         }                            private void calculainformacoes(boolean calcula_preco){              [only calculates values]         }         private boolean atualizaflex(produto_insercao p_i, int operacao) {             [only calculates values]         }          public condicao_preco find_condicao_preco(list<condicao_preco> lista, integer cd_tabela_preco_condicao){             for(condicao_preco c_p : lista){                 if(c_p.getcd_tabela_preco_condicao().equals(cd_tabela_preco_condicao)){                     return c_p;                 }             }                    return null;         }          public integer find_condicao_preco_position(list<condicao_preco> lista, integer cd_tabela_preco_condicao){             for(int = 0; < lista.size(); i++){                 condicao_preco c_p = lista.get(i);                 if(c_p.getcd_tabela_preco_condicao().equals(cd_tabela_preco_condicao)){                     return i;                 }             }                    return null;         }          public void selection(integer arg2){             if(arg2 > 0){                 condicao_preco c_p = find_condicao_preco(lista_tabela_preco_condicao, p.getcd_tabela_preco_condicao());                 condicao_preco c_p_aux = lista_tabela_preco_condicao.get(arg2);                                                      if(c_p == null || !c_p.getcd_tabela_preco_condicao().equals(c_p_aux.getcd_tabela_preco_condicao())){                     if(p.getid_gera_flex().equals("s") && c_p_aux.getds_condicao_preco().equals("Última venda")){                         if(c_p_aux.getds_condicao_preco().equals("Última venda")){                             util.messagedialog_ok(ctx,                                      ctx.getresources().getstring(r.string.titulo_dialog_padrao),                                      "produto que gera flex não pode ser selecionado 'Última venda'.", util.icone_information);                           }                                    p.setcd_tabela_preco_condicao(p.getcd_tabela_preco_condicao());                                                          madapter.notifydatasetchanged();                         return;                     }                                                            if(c_p_aux.getvl_valor() != null){                         p.setcd_tabela_preco_condicao(c_p_aux.getcd_tabela_preco_condicao());                         p.setid_selecionado(true);                         calculainformacoes(true);                     } else {                         util.messagedialog_ok(ctx,                                  ctx.getresources().getstring(r.string.titulo_dialog_padrao),                                  "não foi possível encontrar última venda deste item para este cliente.", util.icone_information);                         p.setcd_tabela_preco_condicao(p.getcd_tabela_preco_condicao());                                                          madapter.notifydatasetchanged();                     }                 }             } else {                 p.setcd_tabela_preco_condicao(-1);                 p.setid_selecionado(false);                 calculainformacoes(true);             }         }     } } 

kind regards,

william bertan

couple of things:

1) asynctask super buggy. first, it's triggered - static variable never true when you're in getview - main thread can't both in notifydatasetchanged , getview @ same time! more importantly, you're changing views off main thread , bad, bad, bad. it's riddled race conditions, both against own code , against framework. has redone touch views in onpostexecute

2) code in notifydatasetchanged() seems flaky - you're holding reference view if click , scroll before onclick listener gets executed view may no longer on screen. it's rare case, granted, in general avoid @ costs running holding references of listview items or subviews. that's bound cause trouble and/or memory leaks (especially in case reference static!).

i'm not sure exact cause of bug but, if had guess, i'd it's viewaux.setpressed/setselected/requestfocus lines. specifically, requestfocus super suspicious - android scrolls scrolling containers in window put focused view in visible area.

3) remove android:scrollx , scrolly listview - i'm pretty sure don't if do, it's wrong thing.


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -