2

I, have implemented image slider using view-pager in my project. Now I want when I click on particular image of the slider. It will open a new Detail Fragment. Where according to that Image Slider information is available. So I tried to implement interface by getting image position using setOnClickListner. But now the problem is I am getting exception when I click on image. and my app gets crashed. Below is my code...

Slider Image Adapter:

public class SliderImageAdapter extends SliderViewAdapter<SliderImageAdapter.SliderAdapterVH>{

    public List<Banner> bannerList;
    public Context context;
    private OnItemClicked onClick;

    public interface OnItemClicked {
        void onItemClick(int position);
    }

    public SliderImageAdapter(Context context, List<Banner> bannerList) {

        this.bannerList = bannerList;
        this.context = context;
    }

    @Override
    public SliderAdapterVH onCreateViewHolder(ViewGroup parent) {
        View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_slider_myshop, parent, false);
        return new SliderAdapterVH(inflate);
    }

    @Override
    public void onBindViewHolder(final SliderAdapterVH viewHolder, final int position) {

        Glide.with(viewHolder.itemView)
                .load(bannerList.get(position).getmSliderImage())
                .fitCenter()
                .into(viewHolder.imageViewBackground);

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                onClick.onItemClick(position);
            }
        });
    }

    @Override
    public int getCount() {
        return bannerList.size();
    }

    public int getItemPosition (Object object) {
        return POSITION_NONE;
    }

    public void setOnClick(OnItemClicked onClick) {
        this.onClick = onClick;
    }



    class SliderAdapterVH extends SliderViewAdapter.ViewHolder {

        View itemView;
        ImageView imageViewBackground;
        ImageView imageGifContainer;

        public SliderAdapterVH(View itemView) {
            super(itemView);
            imageViewBackground = itemView.findViewById(R.id.iv_auto_image_slider);
            imageGifContainer = itemView.findViewById(R.id.iv_gif_container);
            this.itemView = itemView;
        }
    }
}

Here I am getting the exception in Image Slider Adapter: java.lang.NullPointerException: Attempt to invoke interface method SliderImageAdapter$OnItemClicked.onItemClick(int)' on a null object reference.

@Override
    public void onBindViewHolder(final SliderAdapterVH viewHolder, final int position) {

        Glide.with(viewHolder.itemView)
                .load(bannerList.get(position).getmSliderImage())
                .fitCenter()
                .into(viewHolder.imageViewBackground);

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                onClick.onItemClick(position);
            }
        });
    }

Home Fragment Code:

public class HomeFragment extends Fragment implements SliderImageAdapter.OnItemClicked {

private SliderImageAdapter sliderImageAdapter;
    private List<Banner> bannerList;

bannerList = new ArrayList<>();
        sliderImageAdapter = new SliderImageAdapter(getActivity(), bannerList);

sliderMyshop = view.findViewById(R.id.imageSlider);
        sliderMyshop.setSliderAdapter(sliderImageAdapter);
        sliderMyshop.setIndicatorAnimation(IndicatorAnimations.WORM); //set indicator animation by using SliderLayout.IndicatorAnimations. :WORM or THIN_WORM or COLOR or DROP or FILL or NONE or SCALE or SCALE_DOWN or SLIDE and SWAP!!
        sliderMyshop.setSliderTransformAnimation(SliderAnimations.SIMPLETRANSFORMATION);
        sliderMyshop.setIndicatorSelectedColor(Color.WHITE);
        sliderMyshop.setIndicatorUnselectedColor(Color.GRAY);
        sliderMyshop.startAutoCycle();

mFirestore.collection("Banner").orderBy("mSliderImage", Query.Direction.DESCENDING).addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(@javax.annotation.Nullable QuerySnapshot documentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) {
                if (e != null) {
                    Log.d(TAG, "Error : " + e.getMessage());
                }
                assert documentSnapshots != null;

                for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {

                    if (doc.getType() == DocumentChange.Type.ADDED) {
                        String doc_id = doc.getDocument().getId();
                        Banner banner = doc.getDocument().toObject(Banner.class).withDocId(doc_id);
                        bannerList.add(doc.getNewIndex(), banner);
                        sliderImageAdapter.notifyDataSetChanged();

                    } else if (doc.getType() == DocumentChange.Type.MODIFIED) {
                        String docID = doc.getDocument().getId();
                        Banner changedModel = doc.getDocument().toObject(Banner.class).withDocId(docID);
                        if (doc.getOldIndex() == doc.getNewIndex()) {
                            // Item changed but remained in same position
                            bannerList.set(doc.getOldIndex(), changedModel);
                        } else {
                            // Item changed and changed position
                            bannerList.remove(doc.getOldIndex());
                            bannerList.add(doc.getNewIndex(), changedModel);
                        }
                    } else if (doc.getType() == DocumentChange.Type.REMOVED) {
                        // remove
                        bannerList.remove(doc.getOldIndex());
                    }
                    sliderImageAdapter.notifyDataSetChanged();
                }
            }
        });

@Override
    public void onItemClick(int position) {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.fragment_container_dashboard, SliderClickFragment.newInstance(bannerList.get(position).getmSliderImage()));
        ft.addToBackStack(null);  // this line responsible for adding fragment in backstack.
        ft.commit();
    }

Detail Fragment Code:

public abstract class SliderClickFragment extends Fragment {

public static Fragment newInstance(String getmSliderImage) {
        Bundle args = new Bundle();
        HomeFragment fragment = new HomeFragment();
        fragment.setArguments(args);
        return fragment;
    }

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable final Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.slider_click_listner, container, false);
        return view;
    }
}
  • You didn't initialize your `OnItemClicked` listener. Call `setOnClick` from your `fragment` like `sliderImageAdapter.setOnClick(this)` – Md. Asaduzzaman Jan 12 '20 at 06:41

1 Answers1

2

So the issue would probably be that you are calling the OnItemClicked.onClick without an instance of OnItemClicked. Just a quick look through

private OnItemClicked onClick;

public interface OnItemClicked {
    void onItemClick(int position);
}

public SliderImageAdapter(Context context, List<Banner> bannerList) {

    this.bannerList = bannerList;
    this.context = context;
}

And then you use it here

viewHolder.itemView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            onClick.onItemClick(position);
        }
    });

You are using trying to call the OnClick method on a null instance of OnItemClicked. One way to do it would be to add OnItemClicked onclick to the contructor as a parameter and then have what ever fragment implement the OnItemClicked interface. Something like this.

private OnItemClicked onClick;

public interface OnItemClicked {
  void onItemClick(int position);
}

public SliderImageAdapter(Context context, List<Banner> bannerList, 
    OnItemClicked onClick) {

   this.bannerList = bannerList;
   this.onClick = onClick;
   this.context = context;
}

Then at the HomeFragment

public class HomeFragment extends Fragment implements 
SliderImageAdapter.OnItemClicked{
   private SliderImageAdapter sliderImageAdapter
   = new SliderImageAdapter(getActivity(), bannerList, this);
}
christoandrew
  • 437
  • 4
  • 17