Lỗi khi chuyển dữ liệu giữa recyclerview fragment A sang recyclerview fragment B

Chào mọi người, mình đang viết một app có giao diện tablayout với 2 Fragment khác nhau,
tab 1 chứa danh sách item trong recyclerview khi nhấn button của của các item thì bên tab2 sẽ xuất hiện các item được nhấn đó
mình là viết một interface để gửi data

public interface OnFavClick {
        void favclick(String id,String songTitle, String singer, boolean isFav);
}

đây là class

public class Song {
        private String mID;
        private String mSongTittle;
        private String mSongSinger;
        private boolean mSongFavorite;
        public Song(String id,String title,String singer, boolean favorite) {
            mID = id;
            mSongTittle = title;
            mSongSinger = singer;
            mSongFavorite = favorite;
        }
        public void setmID(String mID) {
            this.mID = mID;
        }
        public void setmSongTittle(String mSongTittle) {
            this.mSongTittle = mSongTittle;
        }
        public void setmSongSinger(String mSongSinger) {
            this.mSongSinger = mSongSinger;
        }
        public void setmSongFavorite(boolean mSongFavorite) {
            this.mSongFavorite = mSongFavorite;
        }
        public String getmID() {
            return mID;
        }
        public String getmSongTittle() {
            return mSongTittle;
        }

        public String getmSongSinger() {
            return mSongSinger;
        }
        public boolean ismSongFavorite() {
            return mSongFavorite;
        }
    }

Đây là Adapter của mình

public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
private Context mContext;
private List<Song> mSongList;
OnFavClick mFavclick;
public SongAdapter(OnFavClick callback) {
    this.mFavclick = callback;
}
public SongAdapter(List<Song> songList,Context context, OnFavClick favClick) {
    mSongList = songList;
    mContext = context;
    mFavclick = favClick;
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    if (mContext == null) {
        mContext = parent.getContext();
    }
    View view = LayoutInflater.from(mContext).inflate(R.layout.layout_song_item, parent, false);
    return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final SongAdapter.ViewHolder holder,final int position) {
    final Song song = mSongList.get(position);
    holder.txtId.setText(song.getmID());
    holder.txtSongTitle.setText(song.getmSongTittle());
    holder.txtSinger.setText(song.getmSongSinger());
    holder.imageButtonFav.setImageResource(song.ismSongFavorite() ? R.drawable.favorited : R.drawable.favorite);
    holder.imageButtonFav.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(holder.imageButtonFav.getTag().equals(false)){
                holder.imageButtonFav.setImageResource(R.drawable.favorited);
                holder.imageButtonFav.setTag(true);
                mFavclick.favclick(song.getmID(),song.getmSongTittle(),song.getmSongSinger(),song.ismSongFavorite());
            } else {
                holder.imageButtonFav.setImageResource(R.drawable.favorite);
                holder.imageButtonFav.setTag(false);
            }
        }
    });
}
@Override
public int getItemCount() {
    return mSongList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
     TextView txtSongTitle,txtSinger,txtId;
     ImageButton imageButtonFav;
     public ViewHolder(View itemView) {
        super(itemView);
        txtId = itemView.findViewById(R.id.txtId);
        txtSongTitle = itemView.findViewById(R.id.txtSongTitle);
        txtSinger = itemView.findViewById(R.id.txtSinger);
        imageButtonFav = itemView.findViewById(R.id.imageButtonFav);
    }
}
}

Đây là fragment 1 của tab1

public class flayout_home extends Fragment {
    private RecyclerView rvSongs;
    SongAdapter adpter;
    private List<Song> songlist = new ArrayList<>();
    OnFavClick mOnClick;

    public Song[] songs = {
            new Song("01","Song 1","Singer A",false),
            new Song("02","Song 2","Singer B",false),
            new Song("03","Song 3","Singer C",false),
            new Song("04","Song 4","Singer D",false)
    };
    public flayout_home(){}
    public void setOnFavClick(OnFavClick onFavClick) {
        this.mOnClick = onFavClick;
    }
    public static flayout_home getInstance(){
        return new flayout_home();
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_flayout_home, container, false);
        rvSongs = view.findViewById(R.id.rvSongs);
        GridLayoutManager layoutManager = new GridLayoutManager(this.getContext(), 1);//Parameter: context, number of columns
        adpter = new SongAdapter(songlist,getContext(),mOnClick);
        rvSongs.setAdapter(adpter);
        rvSongs.setLayoutManager(layoutManager);
        return view;
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initSongs();
    }
    private void initSongs() {
        for (int i = 0; i < songs.length; i++) {
            songlist.add(songs[i]);
        }
    }
}

Đây là fragment 2 của tab2

public class flayout_fav extends Fragment implements OnFavClick{
    private Context mContext;
    private RecyclerView rvSongsFav;
    OnFavClick mOnClickFav = this;
    SongAdapter adpter;
    private  List<Song> songlist = new ArrayList<>();
    public flayout_fav() { }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_flayout_fav, container, false);
        rvSongsFav = view.findViewById(R.id.rvSongsFav);
        return view;
    }
    @Override
    public void favclick(String id,String title,String singer, boolean favorite) {
        songlist.add(new Song(id,title,singer,favorite));
        GridLayoutManager layoutManager = new   GridLayoutManager(this.getContext(), 1);
        adpter = new SongAdapter(songlist);
        rvSongsFav.setAdapter(adpter);
        rvSongsFav.setLayoutManager(layoutManager);
    }
}

Khi mình nhấn vào button thì bị lỗi

java.lang.NullPointerException: Attempt to invoke interface method ‘void io.vacnex.songlib.OnFavClick.favclick(java.lang.String, java.lang.String, java.lang.String, boolean)’ on a null object reference

Không biết mình sai chỗ nào, mọi người xem giúp mình với.
cám ơn các bạn

Lỗi ngay dòng này phải không?

Mình thấy cách triển khai 2 tab của bạn có gì hơi lộn xộn. Bạn dùng RecycleView để quản lý sự kiện chỉ xảy ra tương đối (chỉ ở tab 1).
Mình chưa thấy chỗ bạn truyền tham số sự kiện cho RecycleView.

3 Likes

Đúng rồi bạn mình lỗi ngay dòng đó, lỗi báo là truyền vào một object rỗng,

là thế nào bạn? mình không hiểu lắm.

Có phải trong RecycleView (SongAdapter) của bạn có 2 hàm dựng (1 và 3 tham số), trong đó có 1 tham số kiểu OnFavClick. Bạn có truyền 1 đối tượng != null chưa?

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?