微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

片段内的 RecyclerView 不可点击

如何解决片段内的 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 举报,一经查实,本站将立刻删除。