簡體   English   中英

片段內的 RecyclerView 不可點擊

[英]RecyclerView inside fragment is not clickable

我正在編寫一個音樂播放器應用程序,並且由於某種原因 RecyclerView 不可點擊並且當我按下一個項目時應用程序剛剛關閉,因此片段內的 RecyclerView 存在問題(它連接到我的主要活動中的選項卡布局)。 你能幫我嗎? 我添加了片段 class 和適配器 class。

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, 0, 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 適配器時傳遞MusicListener ,因為您很容易忘記設置它,這將導致Nullpointer Exception

我不知道你為什么這樣做: String s = String.valueOf(R.drawable.lionkingposter); 如果要將 Drawable 資源保留在 class 中,請將可繪制資源設置為setBackgroundResource方法時僅保留R.drawable.lionkingposter

我希望這會有所幫助;)

我遇到了同樣的問題,不知道實際原因,但我找到了一個可行的解決方案。 您需要創建一個implements RecyclerView.OnItemTouchListener的監聽器 class

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) {
}

第三,將視圖傳遞給方法。 但在適配器下方 object

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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM