Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

estou tentando fazer com que os view holder sejam criados so quando realmente forem necessarios

assim que esta minha ListaAlunosFragment, eu deixei meu codigo assim, mas agora nao esta preenchendo a lista, nao da erro, mas tambem nao popula a lista rs, alguem sabe onde esta o erro?

public class ListaAlunosFragment extends Fragment {

    private Delegate delegate;
    private FloatingActionButton botaovaidenovo;
    private ListaAlunoAdapter adapter;
    private List<Aluno> alunos;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_lista,container,false);
        confiuguraatela(view);
        return  view;
    }

    private void confiuguraatela(View view) {
        configuralista(view);
        configurafloactionbotao(view);
    }

    private void configuralista(View view) {
        final RecyclerView lista = view.findViewById(R.id.lista_deitens);
        final AlunoDAO alunoDAO = carregalista(lista); 

    }

    private AlunoDAO carregalista(RecyclerView lista) {
        GeradordeBancodeDados geradordeBancodeDados = new GeradordeBancodeDados();
        BancoDataBase database = geradordeBancodeDados.gera(getContext());
        final AlunoDAO alunoDAO = database.getAlunoDAO();
        alunos = alunoDAO.busca();
        configuraadapter(lista, alunos);
        return alunoDAO;
    }

    private void configuraadapter(RecyclerView lista, List<Aluno> alunos) {
        adapter = new ListaAlunoAdapter(getContext(), alunos);
        lista.setAdapter(adapter);
    }

    @Override
    public void onResume() {
        alunos.clear();
        alunos.addAll(alunos);
        adapter.notifyDataSetChanged();
        delegate.trocanome("Lista de Nomes");
        super.onResume();
    }
}
7 respostas

meu adapter

public class ListaAlunoAdapter extends RecyclerView.Adapter<ListaAlunoAdapter.AlunoViewHolder> {

    private final List<Aluno> alunos;
    private final Context contexto;
    private int quantidadeviewHolder = 0;

    public ListaAlunoAdapter(Context contexto,List<Aluno>alunos){
        this.contexto = contexto;
        this.alunos = alunos;
    }

    @NonNull
    @Override
    public ListaAlunoAdapter.AlunoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewtype) {
        quantidadeviewHolder++;
        View viewCriada = LayoutInflater.from(contexto).inflate(R.layout.lista_do_adapter, viewGroup, false);
        Log.i("recyclerView Adapter","quantidade view holder "+ quantidadeviewHolder);
        return new AlunoViewHolder(viewCriada);
    }

    @Override
    public void onBindViewHolder(@NonNull ListaAlunoAdapter.AlunoViewHolder viewHolder, int posicao) {
        Aluno aluno = alunos.get(posicao);
        viewHolder.vincula(aluno);

    }

    @Override
    public int getItemCount() {
        return alunos.size();
    }

    class AlunoViewHolder extends RecyclerView.ViewHolder{

        private final TextView nome;
        private final TextView email;

        public AlunoViewHolder(@NonNull final View itemView) {
            super(itemView);
            nome = itemView.findViewById(R.id.xxx_nome);
            email = itemView.findViewById(R.id.xxx_email);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                   // Aluno aluno = (Aluno) alunos.get(itemView);
                  //  delegate.lidacomoalunoclicado(aluno);
                }
            });
        }

        public void vincula (Aluno aluno){
            preencheCampo(aluno);
        }

        private void preencheCampo(Aluno aluno) {
            nome.setText(aluno.getNome());
            email.setText(aluno.getEmail());
        }
    }


}

Oi Rafael, tudo bem?

Com base no seu código era pra aparecer, sendo assim, vamos investigar o que está acontecendo. O primeiro detalhe que preciso saber é se dentro do adapter, está sendo chamado o método onBindViewHolder()?

Se sim, os alunos coletados pela posição os que espera? Adicione um log e confira, por favor.

Outro detalhe que vi é que você chama o clear e addAll do adapter, mas o Adapter do RecyclerView não possui esses métodos e, você também não implementou os mesmos... Talvez esteja usando o adapter errado!

Veja esses detalhes e me avisa com precisão o que está ou não sendo utilizado.

[]s

eu realmente estava com outro adapter, mas eu removi e mesmo assim esta criando os view holders toda vez que entro na lista, coloquei o projeto no git se puder dar uma olhada :

https://gitlab.com/RafaelAlmeid/cadastro-de-aluno

estou com um bug no deletar do swiped tambem, se excluir o primeiro ou o ultimo item da lista a aplicacao trava.

Oi Rafael, testei o seu App e está criando os alunos, qual é o problema dessa abordagem?

Da parte de remoção eu ajustei o seu código removendo as duas últimas linhas do onSwiped(), deixando-o da seguinte maneira:

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        int posicaodanotadeslizada = viewHolder.getAdapterPosition();

        GeradordeBancodeDados geradordeBancodeDados = new GeradordeBancodeDados();
        BancoDataBase database = geradordeBancodeDados.gera(context);
        AlunoDAO alunoDAO = database.getAlunoDAO();
        alunoDAO.deleta(adapter.remove(posicaodanotadeslizada));
        adapter.notifyDataSetChanged();
    }

Perceba que você já remove no adapter, com as duas últimas instruções atuais ele tenta remover denovo uma nota que já foi removida, portanto, dá o IndexOutOfBoundsException.

Sobre a notificação do adapter, recomendo que sempre encapsule e deixe apenas o adapter se preocupar com isso.

[]s

Caramba Alex, era um erro simples aqui mas eu realmente nao tinha visto, obg mesmo rs.

quanto a criacao dos alunos, coloquei o log como na sua video aula e ao entrar na lista ela cria os view holders necessarios pra exibir na tela, mas se eu avanco uma tela e volto na lista por exemplo ela recria todos novamente, no log fica assim

2019-02-20 07:19:21.806 23625-23625/com.example.rafaellara.app I/recyclerViewAdapter: quantidade view holder 1
2019-02-20 07:19:21.811 23625-23625/com.example.rafaellara.app I/recyclerViewAdapter: quantidade view holder 2
2019-02-20 07:19:26.448 23625-23625/com.example.rafaellara.app I/recyclerViewAdapter: quantidade view holder 1
2019-02-20 07:19:26.454 23625-23625/com.example.rafaellara.app I/recyclerViewAdapter: quantidade view holder 2
solução!

Oi Rafael, isso acontece pelo fato de que os fragments recriam suas views sempre que saem de foreground (quando é removida ou substituída), veja o ciclo de vida:

Fluxo de ciclo de vida de fragments

Portanto, não tem como evitar esse comportamento dado que está usando um fragment.

[]s

Agora eu entendi rs.

valeu Alex, obrigado pela ajuda tudo de bom ai... abraço!