A visualização de reciclagem não chama onCreateViewHolder


150

Meu RecyclerViewnão chama onCreateViewHolder, onBindViewHoldermesmo MenuViewHolderconstrutor, pois nada aparece RecyclerView. Coloquei logs para depuração e nenhum log é mostrado. Qual pode ser o problema?

Meu adaptador:

public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.MenuViewHolder> {
private LayoutInflater inflater;
List<Menu> data = Collections.emptyList();

public MenuAdapter(Context context, List<Menu> data) {
    Log.i("DEBUG", "Constructor");
    inflater = LayoutInflater.from(context);
    Log.i("DEBUG MENU - CONSTRUCTOR", inflater.toString());
    this.data = data;
    for(Menu menu: this.data){
        Log.i("DEBUG MENU - CONSTRUCTOR", menu.menu);
    }
}

@Override
public MenuViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.row_menu, parent, false);
    MenuViewHolder holder = new MenuViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(MenuViewHolder holder, int position) {
    Log.i("DEBUG MENU", "onBindViewHolder");
    Menu current = data.get(position);
    holder.title.setText(current.menu);
}

@Override
public int getItemCount() {
    return 0;
}

class MenuViewHolder extends RecyclerView.ViewHolder {
    TextView title;
    ImageView icon;

    public MenuViewHolder(View itemView) {
        super(itemView);
        title = (TextView) itemView.findViewById(R.id.menuText);
    }
}

Meu XML de linha personalizado:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/menuText"
    android:text="Dummy Text"
    android:layout_gravity="center_vertical"
    android:textColor="#222"/>

e meu fragmento:

public NavigationFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mUserLearnedDrawer = Boolean.valueOf(readFromPreferences(getActivity(), KEY_USER_LEARNED_DRAWER, "false"));
    if (savedInstanceState != null) {
        mFromSavedInstaceState = true;
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    View view = inflater.inflate(R.layout.fragment_navigation, container, false);
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.drawer_list);
    MenuAdapter adapter = new MenuAdapter(getActivity(), getData());
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setAdapter(adapter);
    return view;
}

por que você definiu recyclerView.setAdapter (adaptador); 2 vezes?
Panayiotis Irakleous

Outra causa desse problema é fazer com que o layout do item coincida com a altura do pai, por isso apenas um item é exibido por vez.
Joe Lapp

No meu caso, ajude isso: invoicesRecyclerView.setHasFixedSize (true) invoicesRecyclerView.setLayoutManager (GridLayoutManager (this, 1))
a_subscriber

Respostas:


239

O seu getItemCountmétodo returns 0. Portanto, RecyclerViewnunca tenta instanciar uma exibição. Faça com que ele retorne alguma coisa greater than 0.

por exemplo

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

25
Oh Deus, eu me sinto tão burro agora! : facepalm: Obrigado por isso!
Shinta S

3
Eu perdi uma hora nisso porque o getItemCount estava muito abaixo de todo o outro código e não o vi. : |
Joel

Eu tinha um adaptador personalizado e tinha esquecido de definir o meu itemcount ao tamanho da minha coleção
Dooie

3
minha contagem de itens é de 3 ainda não visível, sem pontos de depuração vem em onBind ou onCreateHolder ... mas ele vem em getItemCount
Dr. Andro

Oh cara! Eu também estava lutando com isso para descobrir por que diabos meu ponto de interrupção não está atingindo e agora eu sei ... LOL! DROGA!!! OBRIGADO!
Vincy

409

Outra é certificar-se de definir o gerenciador de layout como RecyclerView:

recycler.setLayoutManager(new LinearLayoutManager(this));

2
Volto a esta resposta waaay com muita freqüência ...
finki 17/04


15

Isso não se aplica ao seu caso específico. Mas isso pode ajudar outra pessoa.

Esse motivo pode ser o uso descuidado do método a seguir

recyclerView.setHasFixedSize(true);

Se não for usado com cuidado, isso pode causar onBindViewe onCreateViewHoldernão ser chamado, sem nenhum erro nos logs.


12

Defina o gerenciador de layout RecyclerViewcomo abaixo do código:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view_right);
//set your recycler view adapter here
NavigationAdapter adapter = new NavigationAdapter(this, FragmentDrawer.getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

9

Pelo que vale, observei quando defini o adaptador de visualização do reciclador antes que o adaptador fosse realmente inicializado. A solução foi garantir que recyclerView.setAdapter(adapter)foi chamado com um adaptador não nulo


9

Eu realmente realmente espero que isso ajude alguém algum dia. Eu passo mais de uma hora nessa louca!

Eu tive isso:

projects_recycler_view.apply {
            this.layoutManager = linearLayoutManager
            this.adapter = adapter
        }

Quando eu deveria ter tido isso:

projects_recycler_view.apply {
            this.layoutManager = linearLayoutManager
            this.adapter = projectAdapter
        }

Como liguei tolamente para meu adaptador adapter, ele estava sendo ocultado pelo adaptador da visualização da recicladora no bloco de aplicação! Renomeei o adaptador para projectAdapter para diferenciá-lo e resolver o problema!


6

Definir a altura do TextViewno custom.xmlou RecyclerView. Se a altura for wrap-content, o RecyclerViewnão será visível.


Passamos muito tempo nisso ... a altura da exibição do reciclador era zero. Quando usado em uma atividade, de alguma forma se expandiu. Em um fragmento dentro de outros layouts .. não
Asif Shiraz

4

Isso aconteceu quando eu RecyclerViewestava dentro de um ScrollViewe eu estava usando a Android Support Library 23.0. Para corrigir, atualizei para a Android Support Library 23.2:

No build.gradle:

dependencies {
    ...
    compile 'com.android.support:appcompat-v7:23.2.+'
    compile 'com.android.support:cardview-v7:23.2.+'
}

4

Adicione isso à sua classe de adaptador

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

Além disso, é uma duplicata
Ricardo A.

4

Talvez ajude alguém, mas se você definir a visibilidade do RecycleView como GONE, os métodos do adaptador não serão chamados ... Levou algum tempo para descobrir isso.


inacreditável !!!!! ... tanques demais ,,,
X-Black ...

3

Eu tive o mesmo problema, porque estava usando o android.support.constraint.ConstraintLayoutrecurso de layout. Mudando para FrameLayoutajudou.


Obrigado pela sua solução. Alguma idéia de por que se comporta assim se o pai de exibição é android.support.constraint.ConstraintLayout?
Adrian Buciuman

2

Outra opção é se você enviar esta lista objetc usando get, verifique se você tem a referência correta, por exemplo

private list<objetc> listObjetc;
//Incorrect
public void setListObjetcs(list<objetc> listObjetc){
  listObjetc = listObjetc;
}

//Correct
public void setListObjetcs(list<objetc> listObjetc){
  this.listObjetc = listObjetc;
}

2

Eu lutei com esse problema por muitas horas. Eu estava usando um fragmento. E o problema não estava retornando o view. Abaixo está o meu código:

ProductGridBinding binding = DataBindingUtil.inflate( inflater, R.layout.product_grid, container, false);



    mLinearLayoutManager = new LinearLayoutManager(getActivity());
    mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    binding.rvNumbers.setHasFixedSize(true);
    binding.rvNumbers.setLayoutManager(mLinearLayoutManager);
    binding.rvNumbers.setAdapter(adapter);


    View view = binding.getRoot();


    return view;

Código estranho. Essas variáveis ​​e classes são difíceis de entender.
precisa saber é o seguinte

2

Veja minha resposta se você estiver usando a biblioteca de ligação de dados do Android - verifique se está configurando o layout para a visualização de reciclagem e a contagem de itens deve ser maior que 0

 @BindingAdapter({"entries", "layout"})
    public static void setEntries(RecyclerView view, ArrayList<LoginResponse.User> listOfUsers, int layoutId) {
        if (view.getAdapter() == null) {
            view.setLayoutManager(new LinearLayoutManager(view.getContext()));
            SingleLayoutAdapter adapter = new SingleLayoutAdapter(layoutId) {
                @Override
                protected Object getObjForPosition(int position) {

                    return listOfUsers.get(position);
                }

                @Override
                public int getItemCount() {
                    return listOfUsers.size();
                }
            };
            view.setAdapter(adapter);
        }
    }

Happy coding :-)


1

No meu caso, defino o ID do meu RecyclerView como "recyclerView". Parece que esse ID já estava definido em algum lugar, porque quando eu mudei para um ID diferente, os métodos do adaptador foram chamados corretamente.


1

Se estiver usando um adaptador personalizado, não esqueça de definir o ItemCount para o tamanho da sua coleção.


1

No meu caso, o tamanho da minha lista era 0 e não estava chamando o método onCreateViewHolder. Eu precisava exibir uma mensagem no centro para a lista vazia como espaço reservado, então eu fiz assim e funcionou como um encanto. Responder por @Konstantin Burov ajudou.

  @Override
public int getItemCount() {
    if (contactList.size() == 0) {
        return 1;
    } else {
        return contactList.size();
    }
}

Esta não é uma boa ideia. É melhor definir a visibilidade da mensagem vazia ao colocar dados no adaptador.
O incrível Jan

1

Meu contato foi o método substituído onBindViewHolder (suporte, posição) do RecyclerView.adaptor que não está sendo chamado. O método onCreateViewHolder foi chamado, getItemCount foi chamado. Se você ler as especificações do Recyclerview Adapter, aprenderá que, se você substituir o onBindViewHolder (titular, posição, carga útil da lista), será chamado a favor. Então, por favor, tenha cuidado.


Como você resolveu um problema de não ligar onBindViewHolder?
precisa saber é o seguinte

1

Se você colocar wrap_content como a altura da sua lista e também a da lista de itens, nada será exibido e nenhuma das funções do recyclerView será chamada. Corrija a altura do item ou coloque match_parent para a altura da lista. Isso resolveu meu problema.


1

Meu erro foi inflar a exibição errada no Fragment onCreateView.



0

Por favor, faça o seguinte

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

0

No meu caso, depois de alterar Activity para usar o ViewModel e o DataBinding, esqueci de remover a setContentViewchamada de onCreatemétodo do método. Ao removê-lo, meu problema foi resolvido.


0

Para mim, foi porque o setHasStableIds (true); método foi definido. Remova isso e vai funcionar


Mas esse método não parece estar no exemplo mínimo reproduzível da pergunta. Se a remoção dessa dica corrigir alguma coisa, provavelmente é uma indicação de um erro na implementação do detentor da visualização ou talvez do notificador.

0

recyclerView.setAdapter (adaptador); chamado A lista recyclerView é preenchida chamando o método


0

Verifique se o seu código XMLe Koltin/Javacoincide. No meu caso, tive um problema com o ViewHolderque escrevi:

var txt: AppCompatTextView = itemView.findViewById(R.id.txt)

Mas como meu código XML é:

<TextView
        android:id="@+id/txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        .../>

Eu tive que mudar a linha privada para:

var txt: TextView = itemView.findViewById(R.id.txt)

Além disso, eu também tive que remover:

recyclerView.setHasFixedSize(true);

Espero que isso possa ajudá-lo :)


0

No meu caso, estava faltando uma chamada notifyDataSetChanged()após definir a lista no adaptador.

public void setUserList(List<UserList> userList) {
      this.userList = userList;
        notifyDataSetChanged();
}

0

No meu caso, sinto falta de definir a orientação no meu LinearLayout.

Depois de adicionar o problema de orientação corrigido.

 android:orientation="vertical"

0

Meu problema era layout_heighte layout_widthdo RecyclerView definido como 0dp.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.