Joey Joey - 5 months ago 27
Android Question

NullPointerException on OnclickListener

I'm new at programming and I've been dealing for a couple of hours with a null pointer exception error.

I have one Activity in the project with a Navigation View menu populated with RSS Feeds Categories obtained from a JSON file. When I click a category, a Fragment ("FragmentRSSFeedContainer") gets loaded. This Fragments loads a ViewPager where each page contains a RecyclerView with news from a RSSFeed.json file. When I click one item of the Recycler view is where the nullpointer error occurs. This should .replace current "FragmentRSSFeedContainer" and load a "FragmentRSSNewsContainer". This Fragment will load another ViewPager with the info of the selected news, and each page will have a different news of the selected RSSFeed. When I had all the news hardcoded it was working OK. I have issues with a inner class variable, I believe. I detail more about it below.

This is the error:


java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String ar.com.thomas.mydailynews.model.RSSFeed.getTitle()'
on a null object reference

at
ar.com.thomas.mydailynews.view.MainActivity.getNotifications(MainActivity.java:47)
at
ar.com.thomas.mydailynews.view.RSSFeedsActivity.FragmentRSSFeedViewPager$1$1.onClick(FragmentRSSFeedViewPager.java:63)
at
ar.com.thomas.mydailynews.model.NewsAdapter.onClick(NewsAdapter.java:53)


Here's the MainActivity method that calls the error:

@Override
public void getNotifications(News selectedNews, Integer newsPosition, List<News>newsList) {

FragmentNewsContainer fragmentNewsContainer = new FragmentNewsContainer();
Bundle arguments = new Bundle();
arguments.putString(FragmentNewsContainer.NEWS_TITLE, selectedNews.getTitle());
arguments.putString(FragmentNewsContainer.RSS_SOURCE, newsList.get(newsPosition).getRssFeed().getTitle());
arguments.putInt(FragmentNewsContainer.POSITION, newsPosition);

fragmentNewsContainer.setArguments(arguments);
getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.fragment_container, fragmentNewsContainer).commit();
setTitle(selectedNews.getRssFeed().getTitle());
}


Here's the Fragment where the error is produced. The conflict is in the line "fragmentCalls.getNotifications(itemClicked,itemPosition,newsList". The newsList, for some reason I don't understand, is null. Variable "result" is not null.

public class FragmentRSSFeedViewPager extends Fragment {

public static final String RSS_FEED = "RSSFeed";
public static final String RSS_FEED_LINK = "rssFeedLink";
private RecyclerView recyclerView;
private String rssFeed;
private FragmentCalls fragmentCalls;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

final View view = inflater.inflate(R.layout.fragment_rssfeed_viewpager,container,false);
NewsController newsController = new NewsController();

Bundle bundle = getArguments();
rssFeed = bundle.getString(RSS_FEED);
String rssFeedLink = bundle.getString(RSS_FEED_LINK);


newsController.getNews(new ResultListener<List<News>>() {
@Override
public void finish(List<News> result) {

final List<News> newsList = result;


NewsAdapter newsAdapter = new NewsAdapter(result);
newsAdapter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Integer itemPosition = recyclerView.getChildAdapterPosition(v);
News itemClicked = newsList.get(itemPosition);
fragmentCalls.getNotifications(itemClicked,itemPosition,newsList);
}
});

recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(newsAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
}
}, rssFeedLink);

return view;
}

public static FragmentRSSFeedViewPager generateFragment (RSSFeed rssFeed){

FragmentRSSFeedViewPager fragmentRSSFeedViewPager = new FragmentRSSFeedViewPager();

Bundle arguments = new Bundle();
arguments.putString(RSS_FEED, rssFeed.getTitle());
arguments.putString(RSS_FEED_LINK, rssFeed.getFeedLink());
fragmentRSSFeedViewPager.setArguments(arguments);
fragmentRSSFeedViewPager.setRssFeed(rssFeed.getTitle());
return fragmentRSSFeedViewPager;
}

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
fragmentCalls = (FragmentCalls) activity;
}

public String getRssFeed() {
return rssFeed;
}

public void setRssFeed(String rssFeed) {
this.rssFeed = rssFeed;
}

public interface FragmentCalls{
public void getNotifications(News selectedNews, Integer newsPosition, List<News> newsList);
}


And finally the @Override onClick method on the Adapter

@Override
public void onClick(View v) {
if(listener !=null){
listener.onClick(v);
}
}


I really could use some help here and it will be greatly appreciated. Is there anything else I could upload here to see where the error might be? Or any idea where could I be failing?

edit; my post isn't a duplicate from the one suggested in the comments. I don't know why this is downvoted, but thanks anyway to all that helped! My issue was solved thanks to the input of user Drv. Thanks again! If anyone has a suggestion to improve this, let me know, please. Thanks

Drv Drv
Answer

You need to initialize the list first and then you can use addAll() to add whole other list to your list. So edit your code as below:

      newsController.getNews(new ResultListener<List<News>>() {
    @Override
    public void finish(List<News> result) {

        final List<News> newsList = new ArrayList<News>();
        newsList.addAll(result);

        recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
        NewsAdapter newsAdapter = new NewsAdapter(result);
        recyclerView.setAdapter(newsAdapter);
        newsAdapter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Integer itemPosition = recyclerView.getChildAdapterPosition(v);
                News itemClicked = newsList.get(itemPosition);
                fragmentCalls.getNotifications(itemClicked,itemPosition,newsList);
            }
        });


    }
}, rssFeedLink);