0

Ich mache eine Musik-Player-Anwendung, wo ich einen Loader verwende, um Song-Daten auf den Adapter zu laden, der mit einem RecyclerView angezeigt werden soll. Allerdings bekomme ich diesen merkwürdigen Fehler, dass meine Adaptermethoden nicht funktionieren. Nur die Konstruktormethode des Adapters wird aufgerufen. Ich bekomme auch "Kein Adapter angeschlossen; Layout überspringen", obwohl ich hier alle verfügbaren Lösungen im Stack-Overflow durchlaufe.RecyclerView Kein Adapter angeschlossen; Layout überspringen, Daten werden nicht angezeigt

paar Punkte zu beachten:

  • ich alle Lösungen für die versucht haben, "No-Adapter angeschlossen, Layout-Skipping" in recyclerview No adapter attached; skipping layout Thread und alle damit verbundenen doppelten Threads.
  • Die RecyclerView Ich verwende nicht die reguläre aber FastScrollRecyclerView, aber da es von dem regulären RecyclerView erstreckt und es gibt keine relatable Fragen auf Github erwähnten so überzeugt, dass ich bin, dass diese Bibliothek nutzen, hier kein Problem
  • ist
  • Ich habe auch alle Lösungen für die Adapter-Methoden aus Thread versucht, aber kein Glück versucht.

Hier ist der Code:

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 dieses Layout aufbläst)

<?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 (Einzelposition in den Recycler Ansicht)

<?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> 

Das war wirklich frustrierend. Bitte überprüfen Sie den Code und helfen Sie mir dabei. Ich denke, ich habe alles richtig gemacht, aber vielleicht liege ich falsch. Ich weiß, dass Scrollview und Recyclerview nicht so gut laufen, aber ich habe die Vorschau und die Recycler-Ansicht gesehen. Jede Hilfe wird geschätzt. Vielen Dank!

+0

Log die Größe der Liste zugeführt wird zu 'SongListAdapter .setData() '. –

+0

Verwendet eine Log-Anweisung, um die Größe der Liste zu kennen, die an 'SongListAdapter.setData()' übergeben wird. Die Größe beträgt 609. 609 Songs werden für dieses Gerät an dieses Lied weitergegeben. – Pulak

+0

Erhalten Sie 'Log.d (LOG_TAG," getItemCount called ");'? –

Antwort

0

Pfui! Ich habe viel Zeit damit verschwendet, aber letztendlich kam die Lösung heraus.Ich entfernte Buttermesser Bindung und verwenden herkömmliche findViewById innerhalb onCreateView() von SongsFragment, nachdem sie von der Ansicht Instanz Erfassung der onCreateView() zu diesem Wechsel:

@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 
} 

Stellt sich heraus, ich war mit Buttermesser in die falsche Richtung, so dass die Instanz mRecyclerView null war, aber später mit der Linie mRecyclerView = new FastScrollRecyclerView(getContext()); es war nicht mehr null, aber es war immer noch nicht mit der Ansicht verbunden, so dass ich NullPointerException nicht bekommen und der Code hat nicht funktioniert.

Ich weiß, es war ein noob Fehler: D

korrekte Art und Weise Buttermesser mit Fragmenten zu verwenden, wie von der offiziellen Webseite aufgenommen ist:

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; 
    } 
} 
1

Versuchen Sie, Adapter in onLoadFinished() und auch getActivity() für Kontext-Objekt-Adapter verwenden

@Override 
public void onLoadFinished(Loader<List<Song>> loader, List<Song> data) { 
    mSongs = data; 
    mSongListAdapter = new SongListAdapter(getActivity(), mSongs); 
    mRecyclerView.setAdapter(mSongListAdapter); 
} 

auch in dieser mRecyclerView = new FastScrollRecyclerView(getContext()); zu

mRecyclerView = new FastScrollRecyclerView(getActivity()); 

Grundsätzlich getActivity() für Kontext in Fragment-Klasse verwenden

+0

aktualisiert meine Antwort und versuchen Sie es und lassen Sie es mich wissen –

+0

Habe schon versucht, Adapter in onLoadFinished() zu setzen, aber das hat nicht geklappt. Versuchte mit getActivity() aber nicht funktioniert :( – Pulak

+0

Danke @ quicklearner für einen Blick! Ich bin jetzt auf eine lange Zeit fest. Ich hoffe, ich bekomme die Lösung bald. – Pulak

Verwandte Themen