java - que - recyclerview personalizado
RecyclerView Sin adaptador conectado; omitiendo el diseƱo, los datos no se muestran (2)
Intente configurar el adaptador en onLoadFinished()
y también use getActivity()
para el contexto en el objeto adaptador
@Override
public void onLoadFinished(Loader<List<Song>> loader, List<Song> data) {
mSongs = data;
mSongListAdapter = new SongListAdapter(getActivity(), mSongs);
mRecyclerView.setAdapter(mSongListAdapter);
}
también en este mRecyclerView = new FastScrollRecyclerView(getContext());
a
mRecyclerView = new FastScrollRecyclerView(getActivity());
Básicamente use getActivity()
para el contexto en la clase de fragmento
Estoy haciendo una aplicación de reproducción de música en la que estoy usando un cargador para cargar datos de canciones en el adaptador que se muestra con un RecyclerView. Sin embargo, estoy obteniendo este extraño error de que los métodos de mi adaptador no funcionan. Solo se llama al método constructor del adaptador. También recibo el mensaje "No hay ningún adaptador conectado; omitiendo el diseño" a pesar de pasar por todas las soluciones disponibles aquí en el desbordamiento de la pila.
Pocos puntos a tener en cuenta:
- He intentado con todas las soluciones para "Sin adaptador conectado; omitiendo el diseño" en recyclerview No hay ningún adaptador conectado; omitiendo el hilo de diseño y todos los hilos duplicados asociados.
- El RecyclerView que estoy usando no es el habitual, sino FastScrollRecyclerView , pero como se extiende desde el RecyclerView normal y no hay problemas identificables mencionados en github, estoy convencido de que usar esta biblioteca no es un problema aquí.
- También probé todas las soluciones para los métodos de adaptador que no fueron llamados desde este hilo, pero no tuve suerte.
Aquí está el código:
SongsFragment.java
public class SongsFragment extends Fragment
implements LoaderManager.LoaderCallbacks<List<Song>>{
public static final String LOG_TAG = SongsFragment.class.getSimpleName();
private static final int LOADER_ID = 1;
private ContentResolver mContentResolver;
private SongListAdapter mSongListAdapter;
private List<Song> mSongs;
@BindView(R.id.rvSongs) FastScrollRecyclerView mRecyclerView;
public SongsFragment() {}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(getActivity());
mSongs = new ArrayList<>();
mRecyclerView = new FastScrollRecyclerView(getContext());
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mSongListAdapter = new SongListAdapter(getContext(), mSongs);
mRecyclerView.setAdapter(mSongListAdapter);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this).forceLoad();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_songs, container, false);
}
@Override
public Loader<List<Song>> onCreateLoader(int id, Bundle args) {
mContentResolver = getActivity().getContentResolver();
return new SongsLoader(getContext(), mContentResolver);
}
@Override
public void onLoadFinished(Loader<List<Song>> loader, List<Song> data) {
mSongs = data;
mSongListAdapter.setData(mSongs);
}
@Override
public void onLoaderReset(Loader<List<Song>> loader) {
mSongListAdapter.setData(new ArrayList<Song>());
}
}
SongsListAdapter.java
public class SongListAdapter
extends FastScrollRecyclerView.Adapter<SongListAdapter.SongItemViewHolder>
implements FastScrollRecyclerView.SectionedAdapter{
public static final String LOG_TAG = SongListAdapter.class.getSimpleName();
private Context mContext;
private List<Song> mSongList = new ArrayList<>();
public SongListAdapter(Context context, List<Song> songList) {
Log.d(LOG_TAG, "Constructor called");
mContext = context;
mSongList = songList;
}
@NonNull
@Override
public String getSectionName(int position) {
return String.valueOf(mSongList.get(position).getTitle().charAt(0)).toUpperCase();
}
@Override
public SongItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d(LOG_TAG, "onCreateViewHolder called");
View view = LayoutInflater.from(mContext).inflate(R.layout.list_item_song, null);
return new SongItemViewHolder(view);
}
@Override
public void onBindViewHolder(SongItemViewHolder holder, int position) {
Log.d(LOG_TAG, "onBindViewHolder called");
Uri albumArtUri = mSongList.get(position).getAlbumArtUri();
Glide.with(mContext)
.load(albumArtUri)
.into(holder.albumArt);
holder.titleText.setText(mSongList.get(position).getTitle());
holder.artistText.setText(mSongList.get(position).getArtistName());
Log.d("Data", albumArtUri.toString() + "/n" + mSongList.get(position).getTitle() + "/n" + mSongList.get(position).getArtistName());
}
@Override
public int getItemCount() {
Log.d(LOG_TAG, "getItemCount called");
return (mSongList != null ? mSongList.size() : 0);
}
public void setData(List<Song> songs){
mSongList = songs;
notifyDataSetChanged();
}
public class SongItemViewHolder extends FastScrollRecyclerView.ViewHolder {
ImageView albumArt;
TextView titleText;
TextView artistText;
SongItemViewHolder(View view) {
super(view);
Log.d(LOG_TAG, "SongItemViewHolder called");
albumArt = (ImageView) view.findViewById(R.id.item_song_image);
titleText = (TextView) view.findViewById(R.id.item_song_title);
artistText = (TextView) view.findViewById(R.id.item_song_artist_name);
}
}
}
fragment_songs.xml (SongsFragment está inflando este diseño)
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
android:id="@+id/rvSongs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fastScrollPopupBgColor="@color/colorAccent"
app:fastScrollPopupTextColor="@android:color/primary_text_dark"
app:fastScrollThumbColor="@color/colorAccent"/>
</ScrollView>
list_item_song.xml (Artículo individual en la vista de reciclador)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:background="#FFFFFF"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingStart="8dp"
android:paddingTop="10dp">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_song_image"
android:layout_width="64dp"
android:src="@drawable/music_placeholder"
android:layout_height="64dp"/>
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/item_song_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Song_Title"/>
<TextView
android:id="@+id/item_song_artist_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:textSize="12sp"
android:text="Song_Artist"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Esto ha sido realmente frustrante. Por favor revisa el código y ayúdame con esto. Creo que he hecho todo correctamente, pero puedo estar equivocado. Sé que scrollview y recyclerview no funcionan tan bien, pero he visto la vista previa y se muestra la vista del reciclador. Cualquier ayuda será apreciada. ¡Gracias!
¡Uf! Perdí mucho tiempo en esto, pero finalmente salí con la solución. Quité el enlace de Butterknife y usé findViewById
convencional dentro onCreateView()
de SongsFragment
después de capturar la instancia de vista cambiando el objeto onCreateView()
a este:
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_songs, container, false);
mRecyclerView = (FastScrollRecyclerView) rootView.findViewById(R.id.rvSongs);
//Rest of the things
}
Resulta que estaba usando ButterKnife de forma incorrecta, por lo que la instancia mRecyclerView
era nula, pero más tarde con la línea mRecyclerView = new FastScrollRecyclerView(getContext());
ya no era nulo pero todavía no estaba conectado a la vista, así que no obtuve NullPointerException
y el código no funcionó.
Sé que fue un error novato: D
La forma correcta de usar ButterKnife con fragmentos recogidos del sitio web oficial es:
public class FancyFragment extends Fragment {
@BindView(R.id.button1) Button button1;
@BindView(R.id.button2) Button button2;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
}