Android 回收视图没有显示任何内容

Android 回收视图没有显示任何内容,android,android-recyclerview,Android,Android Recyclerview,我是这个安卓世界的新手。我目前正在从事android项目,即音乐播放器,但有一次我被停止了,因为我的回收器视图没有显示任何应该是歌曲列表的内容。 我甚至检查了我的日志,但无法确定数据是否绑定。任何帮助都将不胜感激 SongListAdapter.java public class SongListAdapter extends RecyclerView.Adapter<SongListAdapter.MyViewHolder> { ArrayList<SongDetailsJ

我是这个安卓世界的新手。我目前正在从事android项目,即音乐播放器,但有一次我被停止了,因为我的回收器视图没有显示任何应该是歌曲列表的内容。 我甚至检查了我的日志,但无法确定数据是否绑定。任何帮助都将不胜感激

SongListAdapter.java

public class SongListAdapter extends RecyclerView.Adapter<SongListAdapter.MyViewHolder> {

ArrayList<SongDetailsJDO> mSongDetailsJDOs;
LayoutInflater mLayoutInflater;
Context mContext;
private static final String TAG = "SongListAdapter";
private boolean mIsSongPlaying = false;
private String mCurrentSongId = "-1";

public SongListAdapter(Context context, ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
    mContext = context;
    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mSongDetailsJDOs = pSongDetailsJDOs;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View lView = mLayoutInflater.inflate(R.layout.recycler_view_item, parent, false);

    return new MyViewHolder(lView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    Uri lUri = null;
    if (mSongDetailsJDOs.get(position).getAlbumId() != null && !mSongDetailsJDOs.get(position).getAlbumId().equals("")) {
        lUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), Long.parseLong(mSongDetailsJDOs.get(position).getAlbumId()));
        Picasso.with(mContext).load(lUri).resize(100, 100).placeholder(R.drawable.placeholder).into(holder.albumImageIV);
    } else
        holder.albumImageIV.setImageResource(R.drawable.placeholder);

    String lTrackName = mSongDetailsJDOs.get(position).getTitle();
    if (lTrackName != null)
        holder.trackNameTV.setText(lTrackName.trim());
    else
        holder.trackNameTV.setText("<Unknown>");

    String lAlbumName = mSongDetailsJDOs.get(position).getAlbumName();
    if (lAlbumName != null)
        holder.albumAndArtistDetailsTV.setText(lAlbumName.trim());
    else
        holder.albumAndArtistDetailsTV.setText("<Unknown>");

    if (mSongDetailsJDOs.get(position).getFavouriteStatus() == 1)
        holder.favouriteIV.setImageResource(R.drawable.fav);
    else
        holder.favouriteIV.setImageResource(R.drawable.fav_u);

    // TODO: @holder.animationDrawable use it change Visibility and start (Animation)
    if (mIsSongPlaying && mSongDetailsJDOs.get(position).getSongId().equals(mCurrentSongId)) {
        holder.eqIv.setVisibility(View.VISIBLE);
        holder.animationDrawable = (AnimationDrawable) holder.eqIv.getBackground();
        holder.animationDrawable.start();

    } else {
        holder.eqIv.setVisibility(View.INVISIBLE);
    }
}

@Override
public int getItemCount() {
    if (mSongDetailsJDOs != null)
        return mSongDetailsJDOs.size();
    else
        return 0;
}

/**
 * Called when data is being updated in DB
 */
public void favChanged(int pPosition, int pFavStatus) {
    mSongDetailsJDOs.get(pPosition).setFavouriteStatus(pFavStatus);
    notifyItemChanged(pPosition);
}


/**
 * View Holder class for Rec view
 */
class MyViewHolder extends RecyclerView.ViewHolder {

    ImageView albumImageIV;
    TextView trackNameTV;
    TextView albumAndArtistDetailsTV;
    ImageView favouriteIV;
    ImageView eqIv;
    AnimationDrawable animationDrawable;

    MyViewHolder(View itemView) {
        super(itemView);
        albumImageIV = (ImageView) itemView.findViewById(R.id.album_artwork_iv);
        trackNameTV = (TextView) itemView.findViewById(R.id.title_name_tv);
        albumAndArtistDetailsTV = (TextView) itemView.findViewById(R.id.artist_author_name_tv);
        favouriteIV = (ImageView) itemView.findViewById(R.id.fav_iv);
        eqIv = (ImageView) itemView.findViewById(R.id.eq_iv);
    }
}

/**
 * Swap the data with the new JDO list
 *
 * @param pSongDetailsJDOs
 */
public void swapData(ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
    mSongDetailsJDOs = pSongDetailsJDOs;
    notifyDataSetChanged();
}


/**
 * Returns the list of currently loaded JDO's
 * @return
 */
public List<SongDetailsJDO> getData() {
    return mSongDetailsJDOs;
}

/**
 * Gets the @{@link SongDetailsJDO} object at the specified position
 * @param pPosition
 * @return the {@link SongDetailsJDO} object
 */
public SongDetailsJDO getItemAtPosition(int pPosition) {
    return mSongDetailsJDOs.get(pPosition);
}

/**
 * Update Song Play status
 * @param pStatus the status weather is playing or not
 * @param lSongId the song id the playing song
 */
public void updateSongPlayStatus(boolean pStatus, String lSongId) {
    mIsSongPlaying = pStatus;
    mCurrentSongId = lSongId;
    notifyDataSetChanged();
}


}
 public class SongsListActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, SharedPreferences.OnSharedPreferenceChangeListener {

    private RecyclerView mRecyclerView;
    private SongListAdapter mAdapter;
    private ArrayList<SongDetailsJDO> mSongDetailsJDOs;
    private TextView mNoSongTV;

    private static final int LOADER_ID = 101;
    private int REQUEST_CODE = 102;

    private static final String TAG = "SongsListActivity";
    private SharedPreferences mSharedPreferences;
    private SharedPreferences.Editor mPrefEditor;
    private SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener;
    private FirebaseAnalytics mFirebaseAnalytics;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.rec_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(SongsListActivity.this));
        mNoSongTV = (TextView) findViewById(R.id.no_song_tv);
        mSongDetailsJDOs = new ArrayList<>();

        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        mPrefEditor = mSharedPreferences.edit();
        mSharedPreferences.registerOnSharedPreferenceChangeListener(this);

        FirebaseApp.initializeApp(this);
        mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);

        loadData();

    }



    private void loadData() {
        FirebaseCrash.report(new Exception("OMG An Exception"));
        boolean lIsAppLoadingFirstTime = mSharedPreferences.getBoolean(getString(R.string.is_app_loading_first_time), true);

        if (lIsAppLoadingFirstTime) {

            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
            } else {
                mPrefEditor.putBoolean(getString(R.string.is_app_loading_first_time), false);
                mPrefEditor.apply();
                new LoadDataToDbBackground().execute();

                // TODO: Create Loader here
            }
        } else {
            loadDataToRecyclerView();

            if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
                // TODO: Create Loader here
                SongDetailsJDO lJDO = getSongJDO(mSharedPreferences.getString(getString(R.string.song_id), ""));
                startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
                        .putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);
            }

        }

    }


    private class LoadDataToDbBackground extends AsyncTask<Void, Integer, Void> {

        ProgressDialog mProgressDialog;

        @Override
        protected void onPreExecute() {
            mProgressDialog = new ProgressDialog(SongsListActivity.this);
            mProgressDialog.setMessage("Please Wait");
            mProgressDialog.setTitle("Loading");
            mProgressDialog.show();
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            mProgressDialog.dismiss();
            super.onPostExecute(aVoid);
        }

        @Override
        protected Void doInBackground(Void... params) {

            CommonHelper lHelper = new CommonHelper();
            lHelper.loadSongToDB(SongsListActivity.this);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    loadDataToRecyclerView();
                }
            });

            return null;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 0) {
            boolean lGranted = true;
            for (int lResult : grantResults) {
                if (lResult == PackageManager.PERMISSION_DENIED)
                    lGranted = false;
            }
            if (lGranted)
                loadData();
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE) {
            if (data != null && data.getExtras() != null && resultCode == PlayerActivity.RESULT_CODE) {
                //if data changed reload the recyclerView
                if (data.getBooleanExtra(getString(R.string.is_data_changed), false)) {
                    mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
                    mAdapter.swapData(mSongDetailsJDOs);
                }
            }
        }
//        updateCurrentSongIndication();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater lMenuInflater = getMenuInflater();
        lMenuInflater.inflate(R.menu.menu_song_list, menu);

        SearchManager lSearchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
        SearchView lSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        lSearchView.setSearchableInfo(lSearchManager.getSearchableInfo(getComponentName()));
        lSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                filterRecView(newText);
                return true;
            }
        });

        return true;
    }


    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.TITLE + " ASC");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        ArrayList<SongDetailsJDO> lSongDetailsNew = new ArrayList<>();

        if (data.moveToFirst()) {
            do {
                lSongDetailsNew.add(new SongDetailsJDO(data.getString(data.getColumnIndex(MediaStore.Audio.Media.TITLE)),
                        data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM)),
                        data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)),
                        data.getString(data.getColumnIndex(MediaStore.Audio.Media._ID)),
                        data.getInt(data.getColumnIndex(MediaStore.Audio.Media.DURATION)), 0));
            } while (data.moveToNext());
        }
        compareDataAndMakeChangesToDB(lSongDetailsNew);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {

    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        Log.d(TAG, "onWindowFocusChanged: ");
        updateCurrentSongIndication();
    }


    private void updateCurrentSongIndication() {
        if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
            mAdapter.updateSongPlayStatus(true, mSharedPreferences.getString(getString(R.string.song_id), ""));
            mRecyclerView.smoothScrollToPosition(getPositionOfSongId(mSharedPreferences.getString(getString(R.string.song_id), "")));
        } else {
            if(mAdapter!=null)
                mAdapter.updateSongPlayStatus(false, "-1");
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        updateCurrentSongIndication();
    }



    private void compareDataAndMakeChangesToDB(ArrayList<SongDetailsJDO> pSongDetailsNew) {

        Log.d(TAG, "compareDataAndMakeChangesToDB: Called ============");

        ArrayList<String> lSongIdsToBeDeleted = new ArrayList<>();
        for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
            lSongIdsToBeDeleted.add(lSongDetailsJDO.getSongId());
        }
        ArrayList<SongDetailsJDO> lNewSongsToBeAdded = new ArrayList<>();

        for (SongDetailsJDO lSongDetailsJDO : pSongDetailsNew) {
            if (lSongIdsToBeDeleted.contains(lSongDetailsJDO.getSongId())) {
                lSongIdsToBeDeleted.remove(lSongDetailsJDO.getSongId());
            } else
                lNewSongsToBeAdded.add(lSongDetailsJDO);
        }


        if (lSongIdsToBeDeleted.size() > 0 || lNewSongsToBeAdded.size() > 0) {

            SongDetailTable lSongDetailTable = new SongDetailTable(this);
            lSongDetailTable.removeSongsForIds(lSongIdsToBeDeleted);
            lSongDetailTable.insertSongs(lNewSongsToBeAdded);
            loadDataToRecyclerView();

//
//            SongPlayerService lSongPlayerService = SongPlayerService.getRunningInstance();
//            if (lSongPlayerService != null)
//                lSongPlayerService.dataChanged();
        }

    }


    public void onFavClick(View pView) {

        //Firebase Logging
        Bundle lBundle = new Bundle();
        lBundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY,"Favourite Clicked");
        mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM,lBundle);

        int lPosition = mRecyclerView.getChildLayoutPosition((View) pView.getParent());

        SongDetailsJDO lSongDetailsJDO = mAdapter.getItemAtPosition(lPosition);
        String lSongId = lSongDetailsJDO.getSongId();
        SongDetailTable lSongDetailTable = new SongDetailTable(this);

        int lNewFavStatus = lSongDetailsJDO.getFavouriteStatus() == 0 ? 1 : 0;
        lSongDetailTable.setFavouriteStatus(lSongId, lNewFavStatus);
        mAdapter.favChanged(lPosition, lNewFavStatus);

        SongPlayerService mSongPlayerService = SongPlayerService.getRunningInstance();
        if (mSongPlayerService != null)
            mSongPlayerService.favChanged(lPosition, lNewFavStatus);
    }


    public void onRowClick(View pView) {

        int lPosition = mRecyclerView.getChildLayoutPosition(pView);
        SongDetailsJDO lJDO = mAdapter.getItemAtPosition(lPosition);

        startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
                .putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);

        overridePendingTransition(R.anim.from_right, R.anim.scale_down);
    }


    private SongDetailsJDO getSongJDO(String pSongId) {
        SongDetailsJDO lJDO = null;
        for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
            if (lSongDetailsJDO.getSongId().equals(pSongId)) {
                lJDO = lSongDetailsJDO;
                break;
            }
        }
        return lJDO;
    }


    private void filterRecView(String pText) {
        if (pText != null) {
            if (pText.equals("")) {
                mAdapter.swapData(mSongDetailsJDOs);
                toggleVisibilityForNoResult(mSongDetailsJDOs.size(), pText);
            } else {
                ArrayList<SongDetailsJDO> lSongDetailsJDOs = new ArrayList<>();

                pText = pText.toLowerCase();
                for (SongDetailsJDO lDetailsJDO : mSongDetailsJDOs) {
                    if (lDetailsJDO.getTitle().toLowerCase().contains(pText) || lDetailsJDO.getAlbumName() != null && lDetailsJDO.getAlbumName().toLowerCase().contains(pText))
                        lSongDetailsJDOs.add(lDetailsJDO);
                }
                toggleVisibilityForNoResult(lSongDetailsJDOs.size(), pText);
                mAdapter.swapData(lSongDetailsJDOs);
            }
        }

    }


    public void toggleVisibilityForNoResult(int pNumberOfSongs, String query) {

        if (pNumberOfSongs == 0) {
            mNoSongTV.setVisibility(View.VISIBLE);
            mNoSongTV.setText(getString(R.string.nosong) + " " + query);
        } else
            mNoSongTV.setVisibility(View.INVISIBLE);
    }


    public void loadDataToRecyclerView() {
        //Loading data to RecyclerView
        mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
        mAdapter = new SongListAdapter(SongsListActivity.this, mSongDetailsJDOs);
        mRecyclerView.setAdapter(mAdapter);
    }


    public int getPositionOfSongId(String pSongId) {
        int lPostion = -1;
        for (int i = 0; i < mSongDetailsJDOs.size(); i++) {
            if (mSongDetailsJDOs.get(i).getSongId().equals(pSongId)) {
                lPostion = i;
                break;
            }
        }
        return lPostion;
    }
}
公共类SongListAdapter扩展了RecyclerView.Adapter{
ArrayList mSongDetailsJDOs;
放平机MLAYOUTIONFLATER;
语境;
私有静态最终字符串标记=“SongListAdapter”;
私有布尔值mIsSongPlaying=false;
私有字符串mCurrentSongId=“-1”;
公共SongListAdapter(上下文,ArrayList pSongDetailsJDOs){
mContext=上下文;
mLayoutInflater=(LayoutInflater)context.getSystemService(context.LAYOUT\u INFLATER\u SERVICE);
mSongDetailsJDOs=pSongDetailsJDOs;
}
@凌驾
公共MyViewHolder onCreateViewHolder(视图组父级,int-viewType){
视图lView=mLayoutInflater.flate(R.layout.recycler\u View\u项目,父项,false);
返回新的MyViewHolder(lView);
}
@凌驾
公共无效onBindViewHolder(MyViewHolder,int位置){
uriluri=null;
if(mSongDetailsJDOs.get(position).getAlbumId()!=null&&!mSongDetailsJDOs.get(position).getAlbumId()等于(“”){
lUri=ContentUris.withAppendedId(Uri.parse(“content://media/external/audio/albumart),Long.parseLong(mSongDetailsJDOs.get(position.getAlbumId());
毕加索.with(mContext).load(lUri).resize(100100).placeholder(R.drawable.placeholder).into(holder.albumImageIV);
}否则
holder.albumImageIV.setImageResource(R.drawable.placeholder);
字符串lTrackName=mSongDetailsJDOs.get(position.getTitle();
如果(lTrackName!=null)
holder.trackNameTV.setText(lTrackName.trim());
其他的
holder.trackNameTV.setText(“”);
字符串lAlbumName=mSongDetailsJDOs.get(position.getAlbumName();
if(lAlbumName!=null)
holder.album和artistdetailstv.setText(lAlbumName.trim());
其他的
holder.Album和ArtistDetailsTV.setText(“”);
if(mSongDetailsJDOs.get(position).getFavoriteStatus()==1)
持有者.FavoriteIV.setImageResource(R.drawable.fav);
其他的
持有者。收藏IV。设置图像资源(R.可绘制。fav_);
//TODO:@holder.animationDrawable使用它更改可见性并启动(动画)
if(mIsSongPlaying&&mSongDetailsJDOs.get(position.getSongId().equals(mCurrentSongId)){
holder.eqIv.setVisibility(视图可见);
holder.animationDrawable=(animationDrawable)holder.eqIv.getBackground();
holder.animationDrawable.start();
}否则{
holder.eqIv.setVisibility(视图不可见);
}
}
@凌驾
public int getItemCount(){
if(mSongDetailsJDOs!=null)
返回mSongDetailsJDOs.size();
其他的
返回0;
}
/**
*在数据库中更新数据时调用
*/
公共无效FAV变更(内部冲突,内部状态){
mSongDetailsJDOs.get(position).setFavoriteStatus(pFavStatus);
改变(预设);
}
/**
*Rec视图的视图保持器类
*/
类MyViewHolder扩展了RecyclerView.ViewHolder{
ImageView-ImageIV;
TextView-trackNameTV;
TextView相册和ArtistDetailsTV;
图像视图偏好IV;
图像视图;
AnimationDrawable AnimationDrawable;
MyViewHolder(查看项目视图){
超级(项目视图);
albumImageIV=(ImageView)itemView.findViewById(R.id.album\u artwork\u iv);
trackNameTV=(TextView)itemView.findviewbyd(R.id.title\u name\u tv);
albumAndArtistDetailsTV=(TextView)itemView.findViewById(R.id.artist\u author\u name\u tv);
FavoriteIV=(ImageView)itemView.findViewById(R.id.fav_iv);
eqIv=(ImageView)itemView.findViewById(R.id.eq_iv);
}
}
/**
*用新的JDO列表交换数据
*
*@param pSongDetailsJDOs
*/
公共无效交换数据(ArrayList pSongDetailsJDOs){
mSongDetailsJDOs=pSongDetailsJDOs;
notifyDataSetChanged();
}
/**
*返回当前加载的JDO的列表
*@返回
*/
公共列表getData(){
返回mSongDetailsJDOs;
}
/**
*获取位于指定位置的@{@link SongDetailsJDO}对象
*@param-position
*@返回{@link SongDetailsJDO}对象
*/
public SongDetailsJDO getItemAtPosition(内部预设){
返回mSongDetailsJDOs.get(position);
}
/**
*更新歌曲播放状态
*@param pStatus状态天气是否正在播放
*@param lSongId歌曲id播放歌曲
*/
public void updateSongPlayStatus(布尔pStatus,字符串lSongId){
mIsSongPlaying=pStatus;
mCurrentSongId=lSongId;
notifyDataSetChanged();
}
}
SongListActivity.java

public class SongListAdapter extends RecyclerView.Adapter<SongListAdapter.MyViewHolder> {

ArrayList<SongDetailsJDO> mSongDetailsJDOs;
LayoutInflater mLayoutInflater;
Context mContext;
private static final String TAG = "SongListAdapter";
private boolean mIsSongPlaying = false;
private String mCurrentSongId = "-1";

public SongListAdapter(Context context, ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
    mContext = context;
    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mSongDetailsJDOs = pSongDetailsJDOs;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View lView = mLayoutInflater.inflate(R.layout.recycler_view_item, parent, false);

    return new MyViewHolder(lView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    Uri lUri = null;
    if (mSongDetailsJDOs.get(position).getAlbumId() != null && !mSongDetailsJDOs.get(position).getAlbumId().equals("")) {
        lUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), Long.parseLong(mSongDetailsJDOs.get(position).getAlbumId()));
        Picasso.with(mContext).load(lUri).resize(100, 100).placeholder(R.drawable.placeholder).into(holder.albumImageIV);
    } else
        holder.albumImageIV.setImageResource(R.drawable.placeholder);

    String lTrackName = mSongDetailsJDOs.get(position).getTitle();
    if (lTrackName != null)
        holder.trackNameTV.setText(lTrackName.trim());
    else
        holder.trackNameTV.setText("<Unknown>");

    String lAlbumName = mSongDetailsJDOs.get(position).getAlbumName();
    if (lAlbumName != null)
        holder.albumAndArtistDetailsTV.setText(lAlbumName.trim());
    else
        holder.albumAndArtistDetailsTV.setText("<Unknown>");

    if (mSongDetailsJDOs.get(position).getFavouriteStatus() == 1)
        holder.favouriteIV.setImageResource(R.drawable.fav);
    else
        holder.favouriteIV.setImageResource(R.drawable.fav_u);

    // TODO: @holder.animationDrawable use it change Visibility and start (Animation)
    if (mIsSongPlaying && mSongDetailsJDOs.get(position).getSongId().equals(mCurrentSongId)) {
        holder.eqIv.setVisibility(View.VISIBLE);
        holder.animationDrawable = (AnimationDrawable) holder.eqIv.getBackground();
        holder.animationDrawable.start();

    } else {
        holder.eqIv.setVisibility(View.INVISIBLE);
    }
}

@Override
public int getItemCount() {
    if (mSongDetailsJDOs != null)
        return mSongDetailsJDOs.size();
    else
        return 0;
}

/**
 * Called when data is being updated in DB
 */
public void favChanged(int pPosition, int pFavStatus) {
    mSongDetailsJDOs.get(pPosition).setFavouriteStatus(pFavStatus);
    notifyItemChanged(pPosition);
}


/**
 * View Holder class for Rec view
 */
class MyViewHolder extends RecyclerView.ViewHolder {

    ImageView albumImageIV;
    TextView trackNameTV;
    TextView albumAndArtistDetailsTV;
    ImageView favouriteIV;
    ImageView eqIv;
    AnimationDrawable animationDrawable;

    MyViewHolder(View itemView) {
        super(itemView);
        albumImageIV = (ImageView) itemView.findViewById(R.id.album_artwork_iv);
        trackNameTV = (TextView) itemView.findViewById(R.id.title_name_tv);
        albumAndArtistDetailsTV = (TextView) itemView.findViewById(R.id.artist_author_name_tv);
        favouriteIV = (ImageView) itemView.findViewById(R.id.fav_iv);
        eqIv = (ImageView) itemView.findViewById(R.id.eq_iv);
    }
}

/**
 * Swap the data with the new JDO list
 *
 * @param pSongDetailsJDOs
 */
public void swapData(ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
    mSongDetailsJDOs = pSongDetailsJDOs;
    notifyDataSetChanged();
}


/**
 * Returns the list of currently loaded JDO's
 * @return
 */
public List<SongDetailsJDO> getData() {
    return mSongDetailsJDOs;
}

/**
 * Gets the @{@link SongDetailsJDO} object at the specified position
 * @param pPosition
 * @return the {@link SongDetailsJDO} object
 */
public SongDetailsJDO getItemAtPosition(int pPosition) {
    return mSongDetailsJDOs.get(pPosition);
}

/**
 * Update Song Play status
 * @param pStatus the status weather is playing or not
 * @param lSongId the song id the playing song
 */
public void updateSongPlayStatus(boolean pStatus, String lSongId) {
    mIsSongPlaying = pStatus;
    mCurrentSongId = lSongId;
    notifyDataSetChanged();
}


}
 public class SongsListActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, SharedPreferences.OnSharedPreferenceChangeListener {

    private RecyclerView mRecyclerView;
    private SongListAdapter mAdapter;
    private ArrayList<SongDetailsJDO> mSongDetailsJDOs;
    private TextView mNoSongTV;

    private static final int LOADER_ID = 101;
    private int REQUEST_CODE = 102;

    private static final String TAG = "SongsListActivity";
    private SharedPreferences mSharedPreferences;
    private SharedPreferences.Editor mPrefEditor;
    private SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener;
    private FirebaseAnalytics mFirebaseAnalytics;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.rec_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(SongsListActivity.this));
        mNoSongTV = (TextView) findViewById(R.id.no_song_tv);
        mSongDetailsJDOs = new ArrayList<>();

        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        mPrefEditor = mSharedPreferences.edit();
        mSharedPreferences.registerOnSharedPreferenceChangeListener(this);

        FirebaseApp.initializeApp(this);
        mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);

        loadData();

    }



    private void loadData() {
        FirebaseCrash.report(new Exception("OMG An Exception"));
        boolean lIsAppLoadingFirstTime = mSharedPreferences.getBoolean(getString(R.string.is_app_loading_first_time), true);

        if (lIsAppLoadingFirstTime) {

            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
            } else {
                mPrefEditor.putBoolean(getString(R.string.is_app_loading_first_time), false);
                mPrefEditor.apply();
                new LoadDataToDbBackground().execute();

                // TODO: Create Loader here
            }
        } else {
            loadDataToRecyclerView();

            if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
                // TODO: Create Loader here
                SongDetailsJDO lJDO = getSongJDO(mSharedPreferences.getString(getString(R.string.song_id), ""));
                startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
                        .putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);
            }

        }

    }


    private class LoadDataToDbBackground extends AsyncTask<Void, Integer, Void> {

        ProgressDialog mProgressDialog;

        @Override
        protected void onPreExecute() {
            mProgressDialog = new ProgressDialog(SongsListActivity.this);
            mProgressDialog.setMessage("Please Wait");
            mProgressDialog.setTitle("Loading");
            mProgressDialog.show();
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            mProgressDialog.dismiss();
            super.onPostExecute(aVoid);
        }

        @Override
        protected Void doInBackground(Void... params) {

            CommonHelper lHelper = new CommonHelper();
            lHelper.loadSongToDB(SongsListActivity.this);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    loadDataToRecyclerView();
                }
            });

            return null;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 0) {
            boolean lGranted = true;
            for (int lResult : grantResults) {
                if (lResult == PackageManager.PERMISSION_DENIED)
                    lGranted = false;
            }
            if (lGranted)
                loadData();
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE) {
            if (data != null && data.getExtras() != null && resultCode == PlayerActivity.RESULT_CODE) {
                //if data changed reload the recyclerView
                if (data.getBooleanExtra(getString(R.string.is_data_changed), false)) {
                    mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
                    mAdapter.swapData(mSongDetailsJDOs);
                }
            }
        }
//        updateCurrentSongIndication();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater lMenuInflater = getMenuInflater();
        lMenuInflater.inflate(R.menu.menu_song_list, menu);

        SearchManager lSearchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
        SearchView lSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        lSearchView.setSearchableInfo(lSearchManager.getSearchableInfo(getComponentName()));
        lSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                filterRecView(newText);
                return true;
            }
        });

        return true;
    }


    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.TITLE + " ASC");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        ArrayList<SongDetailsJDO> lSongDetailsNew = new ArrayList<>();

        if (data.moveToFirst()) {
            do {
                lSongDetailsNew.add(new SongDetailsJDO(data.getString(data.getColumnIndex(MediaStore.Audio.Media.TITLE)),
                        data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM)),
                        data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)),
                        data.getString(data.getColumnIndex(MediaStore.Audio.Media._ID)),
                        data.getInt(data.getColumnIndex(MediaStore.Audio.Media.DURATION)), 0));
            } while (data.moveToNext());
        }
        compareDataAndMakeChangesToDB(lSongDetailsNew);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {

    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        Log.d(TAG, "onWindowFocusChanged: ");
        updateCurrentSongIndication();
    }


    private void updateCurrentSongIndication() {
        if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
            mAdapter.updateSongPlayStatus(true, mSharedPreferences.getString(getString(R.string.song_id), ""));
            mRecyclerView.smoothScrollToPosition(getPositionOfSongId(mSharedPreferences.getString(getString(R.string.song_id), "")));
        } else {
            if(mAdapter!=null)
                mAdapter.updateSongPlayStatus(false, "-1");
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        updateCurrentSongIndication();
    }



    private void compareDataAndMakeChangesToDB(ArrayList<SongDetailsJDO> pSongDetailsNew) {

        Log.d(TAG, "compareDataAndMakeChangesToDB: Called ============");

        ArrayList<String> lSongIdsToBeDeleted = new ArrayList<>();
        for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
            lSongIdsToBeDeleted.add(lSongDetailsJDO.getSongId());
        }
        ArrayList<SongDetailsJDO> lNewSongsToBeAdded = new ArrayList<>();

        for (SongDetailsJDO lSongDetailsJDO : pSongDetailsNew) {
            if (lSongIdsToBeDeleted.contains(lSongDetailsJDO.getSongId())) {
                lSongIdsToBeDeleted.remove(lSongDetailsJDO.getSongId());
            } else
                lNewSongsToBeAdded.add(lSongDetailsJDO);
        }


        if (lSongIdsToBeDeleted.size() > 0 || lNewSongsToBeAdded.size() > 0) {

            SongDetailTable lSongDetailTable = new SongDetailTable(this);
            lSongDetailTable.removeSongsForIds(lSongIdsToBeDeleted);
            lSongDetailTable.insertSongs(lNewSongsToBeAdded);
            loadDataToRecyclerView();

//
//            SongPlayerService lSongPlayerService = SongPlayerService.getRunningInstance();
//            if (lSongPlayerService != null)
//                lSongPlayerService.dataChanged();
        }

    }


    public void onFavClick(View pView) {

        //Firebase Logging
        Bundle lBundle = new Bundle();
        lBundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY,"Favourite Clicked");
        mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM,lBundle);

        int lPosition = mRecyclerView.getChildLayoutPosition((View) pView.getParent());

        SongDetailsJDO lSongDetailsJDO = mAdapter.getItemAtPosition(lPosition);
        String lSongId = lSongDetailsJDO.getSongId();
        SongDetailTable lSongDetailTable = new SongDetailTable(this);

        int lNewFavStatus = lSongDetailsJDO.getFavouriteStatus() == 0 ? 1 : 0;
        lSongDetailTable.setFavouriteStatus(lSongId, lNewFavStatus);
        mAdapter.favChanged(lPosition, lNewFavStatus);

        SongPlayerService mSongPlayerService = SongPlayerService.getRunningInstance();
        if (mSongPlayerService != null)
            mSongPlayerService.favChanged(lPosition, lNewFavStatus);
    }


    public void onRowClick(View pView) {

        int lPosition = mRecyclerView.getChildLayoutPosition(pView);
        SongDetailsJDO lJDO = mAdapter.getItemAtPosition(lPosition);

        startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
                .putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);

        overridePendingTransition(R.anim.from_right, R.anim.scale_down);
    }


    private SongDetailsJDO getSongJDO(String pSongId) {
        SongDetailsJDO lJDO = null;
        for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
            if (lSongDetailsJDO.getSongId().equals(pSongId)) {
                lJDO = lSongDetailsJDO;
                break;
            }
        }
        return lJDO;
    }


    private void filterRecView(String pText) {
        if (pText != null) {
            if (pText.equals("")) {
                mAdapter.swapData(mSongDetailsJDOs);
                toggleVisibilityForNoResult(mSongDetailsJDOs.size(), pText);
            } else {
                ArrayList<SongDetailsJDO> lSongDetailsJDOs = new ArrayList<>();

                pText = pText.toLowerCase();
                for (SongDetailsJDO lDetailsJDO : mSongDetailsJDOs) {
                    if (lDetailsJDO.getTitle().toLowerCase().contains(pText) || lDetailsJDO.getAlbumName() != null && lDetailsJDO.getAlbumName().toLowerCase().contains(pText))
                        lSongDetailsJDOs.add(lDetailsJDO);
                }
                toggleVisibilityForNoResult(lSongDetailsJDOs.size(), pText);
                mAdapter.swapData(lSongDetailsJDOs);
            }
        }

    }


    public void toggleVisibilityForNoResult(int pNumberOfSongs, String query) {

        if (pNumberOfSongs == 0) {
            mNoSongTV.setVisibility(View.VISIBLE);
            mNoSongTV.setText(getString(R.string.nosong) + " " + query);
        } else
            mNoSongTV.setVisibility(View.INVISIBLE);
    }


    public void loadDataToRecyclerView() {
        //Loading data to RecyclerView
        mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
        mAdapter = new SongListAdapter(SongsListActivity.this, mSongDetailsJDOs);
        mRecyclerView.setAdapter(mAdapter);
    }


    public int getPositionOfSongId(String pSongId) {
        int lPostion = -1;
        for (int i = 0; i < mSongDetailsJDOs.size(); i++) {
            if (mSongDetailsJDOs.get(i).getSongId().equals(pSongId)) {
                lPostion = i;
                break;
            }
        }
        return lPostion;
    }
}
公共类SongsListActivity扩展AppCompativity实现LoaderManager.LoaderCallbacks、SharedReferences.OnSharedPreferenceChangeListener{
私人回收视图mRecyclerView;
私有歌曲列表适配器mAdapter;
私有数组列表mSongDetailsJDOs;
私有文本视图mNoSongTV;
私有静态最终整数加载器_ID=101;
私人int请求_代码=102;
私有静态最终字符串标记=“songslistativity”;
私人共享参考mSharedPreferences;
私有共享引用编辑器mPrefEditor;
private SharedReferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener;
私有FirebaseAnalytics mFirebaseAnalytics;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
mRecyclerView=(RecyclerView)findViewById(R.id.rec_视图);
setLayoutManager(新的LinearLayoutManager(SongsListActivity.this));
mNoSongTV=(TextView)findviewbyd(R.id.no\u song\u tv);
mSongDetailsJDOs=newarraylist();
mSharedPreferences=PreferenceManager.getDefaultSharedReferences(此);
mPrefEditor=mSharedPrefere