Como o método getView () funciona ao criar seu próprio adaptador personalizado?

101

Minhas perguntas são:

  1. Qual é exatamente a função do LayoutInflater?
  2. Por que todos os artigos que li verificam se convertview é nulo ou não? O que significa quando é nulo e o que significa quando não é?
  3. Qual é o parâmetro pai que este método aceita?
GrowinMan
fonte

Respostas:

115

1: O LayoutInflaterpega seus arquivos XML de layout e cria diferentes objetos de visualização a partir de seu conteúdo.

2: Os adaptadores são construídos para reutilizar Visualizações, quando uma Visualização é rolada de forma que não seja mais visível, ela pode ser usada para uma das novas Visualizações que aparecem. Esta visualização reutilizada é a convertView. Se for nulo, significa que não há nenhuma visualização reciclada e temos que criar uma nova, caso contrário, devemos usá-la para evitar a criação de uma nova.

3: O parenté fornecido para que você possa aumentar sua visualização para os parâmetros de layout adequados.

Todos estes juntos podem ser usados ​​para criar efetivamente a visualização que aparecerá em sua lista (ou outra visualização que leva um adaptador):

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

Observe o uso de LayoutInflater, que parentpode ser usado como um argumento para ele e como convertViewé reutilizado.

Jave
fonte
5
Convertview == null é útil quando todos os seus itens seguem o mesmo layout. Quando você precisa verificar se há um rádio ou botão marcado, por exemplo, e alterar o layout com base em cada item, você precisa reinflá-lo ou obtém a visualização em cache.
sagits de
Não há necessidade de inflar demais. Apenas você precisa escrever switch ou if-else ladder em getview e aumentar as visualizações de acordo com seu caso, sobrescrever public int getItemViewType (int position) e public int getViewTypeCount (). @sagits
Prashanth Debbadwar
Se as instruções geralmente funcionam, mas ao usar botões de rádio, editar textos e esse tipo de coisa que tive problemas ao usar visualizações em cache, há algumas perguntas a respeito disso no estouro de pilha.
sagits
71

getView()método no adaptador é para a visão de item de geração de um ListView, Gallery...

  1. LayoutInflateré usado para obter a vista objeto que você define em um xml layout (o objeto raiz, normalmente, uma LinearLayout, FrameLayoutou RelativeLayout)

  2. convertViewé para reciclagem. Digamos que você tenha uma visualização de lista que só pode exibir 10 itens por vez e, atualmente, está exibindo o item 1 -> item 10. Quando você rola um item para baixo, o item 1 ficará fora da tela e o item 11 será exibido . Para gerar View para o item 11, o método getView () será chamado, e convertViewaqui está a view do item 1 (que não é mais necessária). Então, em vez de criar um novo objeto de Visualização para o item 11 (que é caro), por que não reutilizá-lo convertView? => apenas verificamos se convertViewé nulo ou não, se for nulo, criamos uma nova visão, caso contrário, reutilizamos convertView.

  3. parentViewé o ListView ou Gallery ... que contém a visão do item que é getView()gerada.

Observação : você não chama este método diretamente, apenas precisa implementá-lo para informar à visualização pai como gerar a visualização do item.

Anh Tuan
fonte
2
EXCELENTE explicação para parentView, não consigo encontrar uma explicação melhor do que esta, +1
Ahmed Adel Ismail
Explicação incrível!
gabi
ótima explicação +1
tpk
8

Você poderia dar uma olhada neste vídeo sobre a exibição de lista. É o Google IO dos últimos anos e ainda é o melhor passo a passo em visualizações de lista na minha mente.

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. Ele aumenta os layouts (os arquivos xml em res / layout / pasta) em objetos java, como LinearLayout e outras visualizações.

  2. Veja o vídeo, vai te deixar atualizado com o que adianta a view convert, basicamente é uma view reciclada esperando para ser reutilizada por você, para evitar a criação de um novo objeto e retardar a rolagem da sua lista.

  3. Permite que você faça referência à visualização de lista a partir do adaptador.

Erbsman
fonte
5

Qual é exatamente a função do LayoutInflater?

Quando você projeta usando XML, todos os seus elementos de IU são apenas tags e parâmetros. Antes de usar esses elementos da IU (por exemplo, TextView ou LinearLayout), você precisa criar os objetos reais correspondentes a esses elementos xml. É para isso que serve o inflador. O inflador usa essas tags e seus parâmetros correspondentes para criar os objetos reais e definir todos os parâmetros. Depois disso, você pode obter uma referência ao elemento da interface do usuário usando findViewById ().

Por que todos os artigos que li verificam se convertview é nulo ou não? O que significa quando é nulo e o que significa quando não é?

Isso é interessante. Veja, getView () é chamado toda vez que um item da lista é desenhado. Agora, antes que o item possa ser desenhado, ele deve ser criado. Agora convertView é basicamente a última visualização usada para desenhar um item. Em getView (), você aumenta o xml primeiro e, em seguida, usa findByViewID () para obter os vários elementos de UI do listitem. Quando verificamos por (convertView == null) o que fazemos é verificar se uma visão é nula (para o primeiro item), então a criamos, senão, se já existir, reutilize-a, não há necessidade de passar pelo processo de inflar novamente . Torna muito mais eficiente.

Você também deve ter encontrado um conceito de ViewHolder em getView (). Isso torna a lista mais eficiente. O que fazemos é criar um viewholder e armazenar a referência a todos os elementos da IU que obtivemos após o aumento. Dessa forma, podemos evitar chamar os diversos findByViewId () e economizar muito tempo. Este ViewHolder é criado na condição (convertView == null) e é armazenado no convertView usando setTag (). No loop else, apenas obtemos de volta usando getView () e o reutilizamos.

Qual é o parâmetro pai que este método aceita?

O pai é um ViewGroup ao qual sua visão criada por getView () é finalmente anexada. Agora, no seu caso, este seria o ListView.

Espero que isto ajude :)

Shubhayu
fonte
4
  1. O inflator de layout aumenta / adiciona XML externo à sua visualização atual.

  2. getView () é chamado várias vezes, incluindo quando rolado. Então, se ele já tem a view inflada, não queremos fazer de novo, pois inflar é um processo caro ... por isso verificamos se é nulo e depois inflamos.

  3. A visualização principal é uma única célula da sua lista.

ngesh
fonte
3
A visão dos pais é explicada incorretamente aqui. Será o ListView, não o ListItem
Varun Jain
2

LayoutInflateré usado para gerar visualizações dinâmicas do XML para o ListViewitem ou no onCreateViewfragmento.

ConvertViewé basicamente usado para reciclar as visualizações que não estão na visualização atualmente. Digamos que você tenha um rolável ListView. Ao rolar para baixo ou para cima, o convertViewdá a visão que foi rolada. Essa reutilização economiza memória.

O parâmetro pai do getView()método fornece uma referência ao layout pai que possui o listView. Digamos que você queira obter o ID de qualquer item no XML pai que possa usar:

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }
user936414
fonte
1

getView()método criar novo Viewou ViewGrouppara cada linha de Listviewou Spinner. Você pode definir isso Viewou ViewGroupem um Layout XMLarquivo na res/layoutpasta e pode dar a referência para a Adapterclasse Object.

se você tiver 4 itens em uma matriz passada para o adaptador. getView()método irá criar 4 View para 4 linhas de Adaper.

A classe LayoutInflater tem um método inflate () que cria View Object a partir do layout de recurso XML.

Ravi1187342
fonte
0

Você também pode encontrar informações úteis sobre getView na interface do adaptador no arquivo Adapter.java. Diz;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
Hamza Polat
fonte