如何解决片段内的 RecyclerView 不可点击
我正在对音乐播放器应用程序进行编程,并且由于某种原因 RecyclerView 不可点击,并且片段中的 RecyclerView(连接到我的主要活动中的选项卡布局)出现问题,当我按下某个项目时,该应用程序刚刚关闭. 你能帮我解决这个问题吗? 我添加了片段类和适配器类。
public class MusicAdapter extends RecyclerView.Adapter<MusicAdapter.MusicviewHolder> {
private List<Music> songs;
public Resources res;
Context context;
public MusicAdapter(Context context,List<Music> songs) {
String s = String.valueOf(R.drawable.lionkingposter);
songs.add(new Music("jgggug","Circle of life","Alton John ","Lion King",s));
// }
this.songs = songs;//constructor
this.context=context;
}
interface MusicListener {
void onMusicclicked(int position,View view);
// void onDeleteClicked(int position);
}
MusicListener listener;
public void setListener(MusicListener listener) {
this.listener = listener;
}
@Override
public MusicviewHolder onCreateViewHolder(ViewGroup parent,int viewType) {//function design the cell
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell,parent,false);
MusicviewHolder musicviewholder = new MusicviewHolder(view);
return musicviewholder;
}
@Override
public void onBindViewHolder(MusicviewHolder holder,int position) {//this function takes the object and put it in the cell
Music music = songs.get(position);
if (music.getPhoto() != null) {
try {
holder.songImg.setimageResource(Integer.parseInt(music.getPhoto()));
} catch (Exception e) {
//holder.songImg.setimageURI(Uri.parse(music.getPhoto()));
byte[] decodedString = Base64.decode(music.getPhoto(),Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString,decodedString.length);
holder.songImg.setimageBitmap(decodedByte);
}
} else {
holder.songImg.setimageResource(0);
}
holder.songName.setText(music.getTitle());
holder.movieName.setText(music.getAlbum());
holder.itemView.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Intent intent=new Intent(context,MediaPlayer.class);
//intent.putExtra("song",position);
//context.startActivity(intent);
Toast.makeText(context,"hello",Toast.LENGTH_SHORT);
}
});
}
@Override
public int getItemCount() {
return songs.size();
}
public class MusicviewHolder extends RecyclerView.ViewHolder {
TextView songName;
TextView movieName;
ImageView songImg;
public MusicviewHolder(@NonNull View itemView) {
super(itemView);
songName = itemView.findViewById(R.id.song_title);
movieName = itemView.findViewById(R.id.movie_title);
songImg = itemView.findViewById(R.id.song_img);
itemView.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null)
listener.onMusicclicked(getAdapterPosition(),v);
}
}
);
}
}
}
public class SongFragment extends Fragment {
// Todo: Rename parameter arguments,choose names that match
// the fragment initialization parameters,e.g. ARG_ITEM_NUMBER
private static final String ARG_ParaM1 = "param1";
private static final String ARG_ParaM2 = "param2";
// Todo: Rename and change types of parameters
private String mParam1;
private String mParam2;
private RecyclerView recyclerview;
private RecyclerView.Adapter myadapter;
private RecyclerView.LayoutManager layoutManager;
View view;
private ArrayList<Music> songs=new ArrayList<>();
private Resources res;
public Context context;
Bundle bundle;
// private ShowSongActivity show;
public SongFragment() {
// required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SongsFragment.
*/
// Todo: Rename and change types and number of parameters
public static SongFragment newInstance(String param1,String param2) {
SongFragment fragment = new SongFragment();
Bundle args = new Bundle();
args.putString(ARG_ParaM1,param1);
args.putString(ARG_ParaM2,param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_ParaM1);
mParam2 = getArguments().getString(ARG_ParaM2);
}
ArrayList<Music> listTemp = MusicManager.getInstance(getContext()).getMusics();
if (listTemp != null)
songs.addAll((Collection<? extends Music>) listTemp.clone());
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_songs,container,false);
recyclerview = (RecyclerView) view.findViewById(R.id.songs_recycler);
MusicAdapter musicAdapter = new MusicAdapter(context,songs);
recyclerview.setLayoutManager(new linearlayoutmanager(getActivity()));
recyclerview.setAdapter(musicAdapter);
recyclerview.setLayoutManager(new linearlayoutmanager(getContext(),RecyclerView.VERTICAL,false));
return view;
}
}
解决方法
尝试将 holder
上的 onClickListener 设置到 onBindViewHolder
方法中,并且在调用侦听器时需要将其传递到 setListener(MusicListener listener)
方法中。像这样:
holder.itemView.setOnClickListener(v -> this.listener.onMusicClicked(position,v);});
在我看来,最好像这样更改 interface MusicListener
:
interface MusicListener {
void onMusicClicked(int position,Music item);
}
并像这样直接返回点击的项目:
holder.itemView.setOnClickListener(v -> this.listener.onMusicClicked(position,songs.get(position);});
此外,最好在创建 RecyclerView Adapter 时传递 MusicListener
,因为您很容易忘记设置它,这会导致 Nullpointer Exception
。
我不知道你为什么要这样做:String s = String.valueOf(R.drawable.lionkingposter);
如果你想在类中保留 Drawable 资源 make property int (Integer) 并且在设置 drawable 资源时只保留 R.drawable.lionkingposter
到 ImageView 使用 setBackgroundResource
方法,如 here
我希望这有帮助;)
,我遇到了同样的问题,不知道真正的原因,但我找到了一个可行的解决方案。
您需要创建一个 Listener 类,它 implements RecyclerView.OnItemTouchListener
public class MatchClickListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public MatchClickListener(Context context,final RecyclerView recyclerView,final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(),e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child,recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv,MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(),e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child,rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(@NotNull RecyclerView rv,MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view,int position);
void onLongClick(View view,int position);}
}
然后从创建回收器视图的片段或主要活动中调用它
recyclerView.addOnItemTouchListener(new MatchClickListener
(getActivity(),recyclerView,new MatchClickListener.ClickListener() {
@Override
public void onClick(View view,int position) {
Intent in =new Intent(getActivity(),TournamentPage.class);
startActivity(in);
}
@Override
public void onLongClick(View view,int position) {
}
}));
,
首先,在片段中实现类似的接口。
public class SongFragment extends Fragment implements MusicAdapter.MusicListener
其次,重写方法。
@Override
public void onMusicClicked(int position,View view) {
}
第三,将视图传递给方法。但在适配器对象下方
musicAdapter.setListener(this::onItemClick);
这是完整的解决方案。
public class SongFragment extends Fragment implements MusicAdapter.MusicListener {
// TODO: Rename parameter arguments,choose names that match
// the fragment initialization parameters,e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private RecyclerView recyclerview;
private RecyclerView.Adapter myadapter;
private RecyclerView.LayoutManager layoutManager;
View view;
private ArrayList<Music> songs=new ArrayList<>();
private Resources res;
public Context context;
Bundle bundle;
// private ShowSongActivity show;
public SongFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SongsFragment.
*/
// TODO: Rename and change types and number of parameters
public static SongFragment newInstance(String param1,String param2) {
SongFragment fragment = new SongFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,param1);
args.putString(ARG_PARAM2,param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
ArrayList<Music> listTemp = MusicManager.getInstance(getContext()).getMusics();
if (listTemp != null)
songs.addAll((Collection<? extends Music>) listTemp.clone());
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_songs,container,false);
recyclerview = (RecyclerView) view.findViewById(R.id.songs_recycler);
MusicAdapter musicAdapter = new MusicAdapter(context,songs);
recyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerview.setAdapter(musicAdapter);
recyclerview.setLayoutManager(new LinearLayoutManager(getContext(),RecyclerView.VERTICAL,false));
musicAdapter.setListener(this::onItemClick);
return view;
}
@Override
public void onMusicClicked(int position,View view) {
// here implement which you want
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。