0

I'm trying to build a simple media player app. I created a RecyclerViewAdapter with CursorAdapter in it's constructor and managed to implement a way to use External Storage to create a playlist. Now I want to make an onClickListener but I'm having trouble. I just need to get the TAG of the view that is clicked so that I can get the necessary values from it and pass it on to media player to play. Please help. I tried to do this using an interface but it's not working.

This is my onClick method implementation through interface

public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.OnItemClickListener{

@Override
protected void onCreate(Bundle savedInstanceState) {

    ActivityCompat.requestPermissions(MainActivity.this,
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            1);

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



    selectedFile = (TextView) findViewById(R.id.selected_file);
    seekBar = (SeekBar) findViewById(R.id.seekbar);
    playButton = (ImageButton) findViewById(R.id.play);
    nextButton = (ImageButton) findViewById(R.id.next);
    prevButton = (ImageButton) findViewById(R.id.prev);

    player = new MediaPlayer();

    player.setOnCompletionListener(onCompletion);
    player.setOnErrorListener(onError);
    seekBar.setOnSeekBarChangeListener(seekBarChanged);
    recyclerView = (RecyclerView) findViewById(R.id.playlist);


    c = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null);

    if(null != c) {
        c.moveToFirst();

        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        mAdapter = new RecyclerViewAdapter(this, c);

        recyclerView.setAdapter(mAdapter);

        playButton.setOnClickListener(onButtonClick);
        nextButton.setOnClickListener(onButtonClick);
        prevButton.setOnClickListener(onButtonClick);
    }

public void onItemClick(View v) {
    songName = ((TextView) v.findViewById(R.id.songname)).getText().toString();
    albumName = ((TextView)v.findViewById(R.id.album)).getText().toString();
    currentFile = (String) v.getTag();

    Log.e("File","Selected");
    selectedFile.setText(songName);

    startPlay(currentFile);

}

/*other code */

And this is my recyclerview adapter

package com.veloxigami.android.audioplayerusingservice;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.provider.MediaStore;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.w3c.dom.Text;


public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

// Because RecyclerView.Adapter in its current form doesn't natively
// support cursors, we wrap a CursorAdapter that will do all the job
// for us.
CursorAdapter mCursorAdapter;

Context mContext;

public interface OnItemClickListener {
    void onItemClick(View view);
}

public RecyclerViewAdapter.OnItemClickListener clickListener;

public RecyclerViewAdapter(Context context, Cursor c) {

    mContext = context;
    mCursorAdapter = new CursorAdapter(mContext, c, 0) {

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // Binding operations
            TextView songName = (TextView) view.findViewById(R.id.songname);
            TextView album = (TextView) view.findViewById(R.id.album);
            TextView duration = (TextView) view.findViewById(R.id.duration);

            songName.setText(cursor.getString(
                    cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
            ));

            album.setText(cursor.getString(
                    cursor.getColumnIndex(MediaStore.Audio.AlbumColumns.ALBUM)
            ));

            if(cursor.getString(cursor.getColumnIndex(
                    MediaStore.Audio.AudioColumns.DURATION
            ))!=null){
                long durationInMs = Long.parseLong(cursor.getString(
                        cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)
                ));

                int durationInMin = ((int) durationInMs / 1000) /60;

                int durationInSec = ((int) durationInMs / 1000) % 60;

                duration.setText(""+ durationInMin+ ":" +String.format("%02d",durationInSec));

                view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
            }



        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // Inflate the view here
            LayoutInflater inflater = LayoutInflater.from(context);
            View v = inflater.inflate(R.layout.list_item,parent,false);

            bindView(v,context,cursor);
            return v;
        }


    };
}

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView songName, album, duration;
    View layout;
    CursorAdapter mCursorAdapter;
    LinearLayout ll;

    public ViewHolder(View itemView) {
        super(itemView);
        layout = itemView;
        songName = (TextView) itemView.findViewById(R.id.songname);
        album = (TextView) itemView.findViewById(R.id.album);
        duration = (TextView) itemView.findViewById(R.id.duration);
        ll = (LinearLayout) itemView.findViewById(R.id.playlist_item);
        ll.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v == ll)
            clickListener.onItemClick(ll);
    }
}

@Override
public int getItemCount() {
    return mCursorAdapter.getCount();
}


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Passing the inflater job to the cursor-adapter
    View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // Passing the binding operation to cursor loader
    mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :)
    mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());

}


}

This is the error it shows:

 FATAL EXCEPTION: main
                                                                                            Process: com.veloxigami.android.audioplayerusingservice, PID: 24341
                                                                                            java.lang.NullPointerException: Attempt to invoke interface method 'void com.veloxigami.android.audioplayerusingservice.RecyclerViewAdapter$OnItemClickListener.onItemClick(android.view.View)' on a null object reference
                                                                                                at com.veloxigami.android.audioplayerusingservice.RecyclerViewAdapter$ViewHolder.onClick(RecyclerViewAdapter.java:106)
                                                                                                at android.view.View.performClick(View.java:5207)
                                                                                                at android.view.View$PerformClick.run(View.java:21168)
                                                                                                at android.os.Handler.handleCallback(Handler.java:746)
                                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                                at android.os.Looper.loop(Looper.java:148)
                                                                                                at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Veloxigami
  • 97
  • 10

1 Answers1

1

You need to assign the listener.

You can try this since you made the Activity implement the listener.

public RecyclerViewAdapter.OnItemClickListener clickListener;

public RecyclerViewAdapter(Context context, Cursor c) {

    mContext = context;
    if (context instanceof RecyclerViewAdapter.OnItemClickListener) {
        clickListener = (RecyclerViewAdapter.OnItemClickListener) context;
    }

Also a good idea to always null-check the listener.

@Override
public void onClick(View v) {
    if(v == ll && clickListener != null)
        clickListener.onItemClick(ll);
}
OneCricketeer
  • 126,858
  • 14
  • 92
  • 185