quinta-feira, 14 de junho de 2018

Rumo ao Certificado Android: Recycler View

O que é?
Basicamente é uma combinação de uma List View com Scroll View, mas otimizado para economizar memória e facilitar o gerenciamento dos itens.

1. Adicionar a dependência do RecyclerView no Gradle
No arquivo Gradle, colocar o seguinte, por exemplo (o número da versão pode ser alterada):

dependecies{
    compile 'com.android.support:recyclerview-v7:24.1.1'
}

2. Criando um RecyclerView Layout
No arquivo XML do layout que vai receber o RecyclerView, adicionar o dito cujo. por exemplo (estou omitindo as configurações do FrameLayout):

<FrameLayout>
   <android.support.v7.widget.RecyclerView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/rv_nome">

   </android.support.v7.widget.RecyclerView>
</FrameLayout>

3. Criar um Layout para os Itens
Em seguida, precisamos criar um arquivo Layout com a disposição dos elementos que compõem os itens do RecyclerView. Cada item vai gerar um elemento definido neste arquivo (lembrando, super simplificando para fins didático aqui).

<FrameLayout>
    <TextView
      android:id="@+id/tv_textView1" />
</FrameLayout>


4. Criar o View Holder
ViewHolder é a representação lógica dos itens, portanto, geralmente ele possui os mesmos elementos que compõe o layout de itens. Uma classe ViewHolder herda do ViewHolder (jura?):

public class NomeHolder extends RecyclerView.ViewHolder{

    TextView textView1;

    public NomeHolder(View itemView){
        super(itemView);
              
       textView1 = (TextView) itemView.findViewById(R.id.tv_textView1);

    }
        
    public void bind(String value){
       textView1.setText(value);
    }
}

O construtor recebe como parâmetro o layout do item, e dentro do construtor, pegamos a referência do campo para o objeto TextView da classe. Isso pode ser feito para outros campos. Também acho interessante criar um método "bind" para setar os valores dos campos que vão aparecer, embora isso fica a gosto do programador.

Obs: Muita gente geralmente cria a classe ViewHolder como uma classe interna do Adapter, que vamos ver em seguida. Isso pode trazer bastante facilidade, dado que os Adapters são específicos para o ViewHolder

5. Criar o Adpter
Adapter é a classe que gerencia os dados. É nele que colocamos os dados e ele que liga os mesmos nos itens do layout. A classe de um Adapter fica assim (campo R.layout.ItemLayout é o layout que criamos no passo 3):

public class NomeAdapter extends RecyclerView.Adaper<NomeHolder>{
    
  List<String> data;

  public NomeAdapter(List<String> loadedData){
    data = loadedData;
  }

  @Override
  public NomeHolder onCreateViewHolder(ViewGroup vg, int viewType){
    //Aqui nós criamos o Holder
    Context context = vg.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.ItemLayout, 
                                 vg,
                                 false);
    return new NomeHolder(view);
  }

  @Override
  public void onBindViewHolder(NomeHolder holder, int position){
     holder.bind(data[position]);
  }

  @Override
  public int getItemCount(){
    return data.length();
  }
}

Começando com o override do método onCreateViewHolder, que é especificamos como instanciamos o ViewHolder para este RecyclerView.
Já em onBindViewHolder, é especificado o que vai ser preenchido o item, no caso, recebe dois parametros, o holder que vai ser usado e a posição do item que está. Para facilitar, você pode usar uma lista, um array, ou qualquer estrutura de dados semelhante para isso.
Por último, temos o método getItemCount, que deve retornar quantos itens deve estar na lista.

6. Determinar o LayoutManager
Isso é importante porque dependendo do LayoutManager, a forma como os itens vão ser mostrados se modifica. Existem três LayoutManager por padrão no Android:

  • LinearLayoutManager: exibe os itens linearmente;
  • GridLayoutManager: exibe os itens em uma grade com espaços uniformes;
  • StaggeredGridLayoutManager: exibe os itens em uma grade, mas o tamanho sempre se adaptará ao conteúdo.

7. Instanciar  e configurar o Adapter na Activity
Auto-explicatória. Se queremos ver ele rodando, precisamos rodar ele numa Activity.

RecyclerView recycler;
NomeAdapter adapter;
protect void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    setContentView(R.layout.layoutActivity);
    recycler = (RecyclerView) findViewById(R.id.rv_nome); //Passo 2
    

   //Configurar o layout
   LinearLayoutManager layoutManager = new LinearManager(this);
   recycler.setLayoutManager(layoutManager);
   
   List<String> data = loadData();

   adapter = new NomeAdapter(data);
   recycler.setAdapter(adapter);

}

8. Criar os Listener dos eventos que deseja
Por exemplo, se tiver um elemento interativo que queira que algo aconteça quando clica em cima, é agora que deve ser feito:

8.1 Alterar o adapter para criar uma Interface e adicionar um campo para referência de um mesmo

public class NomeAdapter extends RecyclerView.Adaper<NomeHolder>{
   final private ListItemClickListener listener;

   public interface ListItemClickListener{
     void onListItemClick(int clickedIndex);
   }
}

8.2 Modificar o construtor para setar o listener

public class NomeAdapter extends RecyclerView.Adaper<NomeHolder>{
   final private ListItemClickListener listener;

   public interface ListItemClickListener{
     void onListItemClick(int clickedIndex);
   }

   public NomeAdapter(List<String> loadedData, ListItemClickListener itemListener){
    data = loadedData;
    listener = itemListener;
  }
}

8.3 Implementar a interface OnClickListener no ViewHolder

public class NomeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
   @Override
   public void onClick(View view){
      int clickedPosition = getAdapterPosition();
      listener.onListItemClick(clickedPosition);
   }
}

8.4 Setar o Listener no construtor da ViewHolder

public class NomeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

  public NomeHolder(View itemView){
        super(itemView);
              
       textView1 = (TextView) itemView.findViewById(R.id.tv_textView1);
       itemView.setOnClickListener(this);
    }

}

8.5 Implementar a interface criada no passo 1 na Activity e alterar a instanciação

public class Activity extends Activity implements NomeAdapter.ListItemClickListener{

   @Override 
   public void ListItemClickListener(int clickedIndex){

   }
   
   [...]
   adapter = new NomeAdapter(data,this);
   [...]
}

Bem, isso é tudo, lembrando que o que registrei aqui é apenas uma maneira de lidar com RecycleView, mas de forma macro, são estes passos que você deve tomar.

Nenhum comentário:

Postar um comentário