Então, eu tenho esse problema que tinha antes e, naturalmente, pedi ajuda aqui . A resposta de Luksprog foi ótima, porque eu não tinha ideia de como o ListView e o GridView se otimizavam com a reciclagem de Views. Assim, com o conselho dele, pude mudar a maneira como adicionei Views ao meu GridView. O problema agora é que tenho algo que não faz sentido. Este é o meu getView
do meu BaseAdapter
:
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.day_view_item, parent, false);
}
Log.d("DayViewActivity", "Position is: "+position);
((TextView)convertView.findViewById(R.id.day_hour_side)).setText(array[position]);
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.day_event_layout);
//layout.addView(new EventFrame(parent.getContext()));
TextView create = new TextView(DayViewActivity.this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 62, getResources().getDisplayMetrics()), 1.0f);
params.topMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
params.bottomMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
create.setLayoutParams(params);
create.setBackgroundColor(Color.BLUE);
create.setText("Test");
//the following is my original LinearLayout.LayoutParams for correctly setting the TextView Height
//new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()), 1.0f)
if(position == 0) {
Log.d("DayViewActivity", "This should only be running when position is 0. The position is: "+position);
layout.addView(create);
}
return convertView;
}
}
O problema é que quando eu rolar, isso acontece, e não na posição 0 ... Parece a posição 6 e a posição 8, além de colocar duas na posição 8. Agora, ainda estou tentando entender como usar o ListView e o GridView, o que faço não entendo por que isso está acontecendo. Uma das principais razões pelas quais estou fazendo essa pergunta é ajudar outras pessoas que provavelmente não sabem sobre a reciclagem do ListView e do GridView, ou a maneira como este artigo descreve o mecanismo ScrapView.
Mais tarde Editar
Adicionando link a uma conversa no IO do Google, basicamente é tudo o que você precisa para entender como o ListView funciona. Link estava morto em um dos comentários. Portanto, user3427079 foi bom o suficiente para atualizar esse link. Aqui está para fácil acesso.
0
).ListView
necessário exibir uma nova linha (como continuar a rolar para baixo / para cima). O problema é que a visão que acabou de desaparecer e que será usada em futuras posições necessáriasTextView
já foi acrescentada, esse é o problema. Para resolvê-lo, você deve removê-lo nogetView
método se ogetView
método for chamado para qualquer outra posição que não0
.Respostas:
Inicialmente, eu também desconhecia a reciclagem de listview e o mecanismo de uso do convertview, mas depois de um dia inteiro de pesquisa eu entendo os mecanismos da exibição de lista consultando uma imagem do android.amberfog
Sempre que o seu listview é preenchido por um adaptador, ele basicamente mostra o número de linhas que o listview pode mostrar na tela e o número de linhas não aumenta, mesmo quando você percorre a lista. Esse é o truque que o Android usa para que o listview funcione com mais eficiência e rapidez. Agora, a história interna do listview referente à imagem, como você pode ver, inicialmente o listview possui 7 itens visíveis; em seguida, se você rolar até o item 1 não ficar mais visível, getView () passa essa visualização (ou seja, item1) para o reciclador e você pode usar
dentro do seu
Você notará no seu logcat que, inicialmente, o convertview é nulo para todas as linhas visíveis, porque inicialmente não havia visualizações (ou seja, itens) no reciclador; portanto, seu getView () cria uma nova visualização para cada um dos itens visíveis, mas o no momento em que você rolar para cima e o item 1 sair da tela, ele será enviado para o Reciclador com seu estado atual (por exemplo, o 'TextView' do TextView ou no meu caso, se a caixa de seleção estiver marcada, ela será associada à exibição e armazenado em reciclador).
Agora, quando você rolar para cima / para baixo, sua lista não criará uma nova exibição, ela usará a exibição que está no seu reciclador. No seu Logcat, você notará que o 'convertView' não é nulo, porque o seu novo item 8 será desenhado usando o convertview, ou seja, basicamente ele usa a visualização do item 1 do reciclador e infla o item 8 em seu lugar, e você pode observar isso no meu código. Se você tinha uma caixa de seleção e a marca na posição 0 (digamos que o item1 tinha uma caixa de seleção e você a marcou), então, quando você rolar para baixo, verá a caixa de seleção do item 8 já marcada, é por isso que o listview está usando a mesma exibição, não criando um novo para você devido à otimização do desempenho.
Coisas importantes
1 . Nunca definir o
layout_height
elayout_width
do seu listview dewrap_content
comogetView()
irá forçar o seu adaptador para obter alguma criança para medir a altura das vistas a ser desenhado na vista de lista e pode causar algum comportamento inesperado como voltar convertview mesmo a lista não é scrolled.always usarmatch_parent
ou fixo largura altura.2 . Se você quiser usar algum esquema ou vista após a sua exibição de lista e pergunta poderia veio em sua mente, se eu definir o
layout_height
quefill_parent
a visão após visão de lista não vai aparecer como ele vai para baixo da tela, então o seu melhor para colocar o seu listview dentro de um Por exemplo, Linear Layout, defina a altura e a largura desse layout de acordo com os seus requisitos e faça com que o atributo height e width da sua lista seja o do seu layout (como se a largura do seu layout for 320 e a altura for 280), então a sua listview deve ter a mesma altura e largura. Isso informará ao getView () a altura e a largura exatas das visualizações a serem renderizadas, e o getView () não chamará repetidas vezes algumas linhas aleatórias e outros problemas como retornar a exibição de conversão mesmo antes que a rolagem não aconteça. eu mesmo, a menos que meu listview estivesse dentro do lineaLayout, também estava tendo problemas como repetir a chamada de visualização e converter a visualização como, colocar o Listview no LinearLayout funcionava como mágica para mim. (não sabia o porquê)Mas agora está resolvido, eu sei, não sou tão bom em explicar, mas como eu dediquei o dia inteiro para entender, pensei que outros iniciantes como eu pudessem obter ajuda da minha experiência e espero que agora vocês tenham um pouco de compreensão da estrutura do ListView como ele funciona, pois é realmente confuso e complicado, então os iniciantes encontraram muitos problemas para entendê-lo
fonte
if you had a checkbox and if you check it at position 0(let say item1 has also a checkbox and you checked it) so when you scroll down you will see item 8 checkbox is already checked,this is why listview is re using the same view not creating a new for you due to performance optimization.
para eu perceber meu erro. Melhor publicação sobre a reciclagem do Android ListView que me deparei!RecyclerView
também funciona no mesmo mecanismo? Na minha pergunta stackoverflow.com/questions/47897770/… , eu sei que a tarefa é silenciosamente impossívellistView
. Devo tentar comrecyclerView
?Tome cuidado, no padrão Holder, se você definir a posição em seu objeto Holder, você deve defini-la sempre, por exemplo:
este é um exemplo de uma classe abstrata, em que
realiza todas as operações de configuração para o
fonte
parent.setTag(holder);
em vez da maneira correta, que é, #view.setTag(holder);
Usando o padrão Holder, você pode conseguir o que deseja:
Você pode encontrar uma descrição desse padrão aqui:
A reciclagem da exibição em lista acontece quando você rola a tela para baixo e os itens acima estão ocultos. Eles são reutilizados para mostrar novos itens de exibição de lista.
fonte