我正在尝试构建一个简单的媒体播放器应用。我在其构造函数中创建了一个带有CursorAdapter的RecyclerViewAdapter,并设法实现一种使用外部存储来创建播放列表的方法。现在我想创建一个onClickListener,但我遇到了麻烦。我只需要获取被点击的视图的TAG,这样我就可以从中获取必要的值并将其传递给媒体播放器进行播放。请帮忙。我尝试使用界面执行此操作,但它无法正常工作。
这是我通过接口
实现的onClick方法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 */
这是我的recyclerview适配器
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());
}
}
这是它显示的错误:
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)
答案 0 :(得分:1)
您需要分配侦听器。
您可以尝试这个,因为您使Activity实现了侦听器。
public RecyclerViewAdapter.OnItemClickListener clickListener;
public RecyclerViewAdapter(Context context, Cursor c) {
mContext = context;
if (context instanceof RecyclerViewAdapter.OnItemClickListener) {
clickListener = (RecyclerViewAdapter.OnItemClickListener) context;
}
总是空检查监听器也是一个好主意。
@Override
public void onClick(View v) {
if(v == ll && clickListener != null)
clickListener.onItemClick(ll);
}