title: Android recycler View and shared preference
body: <p>I'm making a simple app that uses recyclerView which is populated by data from an online server. The data is displayed in a custom cardview layout which has a favorite button. I am having trouble in implementing the favorite button in recyclerView and the app keeps crashing.</p>
  
  <p><strong>LogCat</strong></p>
  
  <pre><code>10-03 23:22:06.609  23785-23785/com.smartdevelopers.kandie.nicedrawer E/AndroidRuntime﹕ FATAL EXCEPTION: main
      Process: com.smartdevelopers.kandie.nicedrawer, PID: 23785
      java.lang.NullPointerException
              at com.smartdevelopers.kandie.nicedrawer.newsAdapter.OtherNewsAdapter.checkFavoriteItem(OtherNewsAdapter.java:102)
              at com.smartdevelopers.kandie.nicedrawer.newsAdapter.OtherNewsAdapter.onBindViewHolder(OtherNewsAdapter.java:64)
              at com.smartdevelopers.kandie.nicedrawer.newsAdapter.OtherNewsAdapter.onBindViewHolder(OtherNewsAdapter.java:25)
              at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5084)
              at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4385)
              at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4278)
              at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1947)
              at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1359)
              at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1322)
              at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:556)
              at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2673)
              at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2971)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:581)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1888)
              at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1742)
              at android.widget.LinearLayout.onLayout(LinearLayout.java:1651)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
              at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1888)
              at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1742)
              at android.widget.LinearLayout.onLayout(LinearLayout.java:1651)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1043)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
              at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1888)
              at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1742)
              at android.widget.LinearLayout.onLayout(LinearLayout.java:1651)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
              at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1888)
              at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1742)
              at android.widget.LinearLayout.onLayout(LinearLayout.java:1651)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
              at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
              at android.view.View.layout(View.java:15125)
              at android.view.ViewGroup.layout(ViewGroup.java:4862)
              at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2317)
              at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2023)
              at android.view.ViewRootImpl.doT
  </code></pre>
  
  <p><strong>OtherNewsAdapter.java</strong></p>
  
  <pre><code>public class OtherNewsAdapter extends RecyclerView.Adapter&lt;OtherNewsAdapter.ViewHolder&gt; {
      private List&lt;Latest&gt; feedItemList;
      private Context mContext;
  
      SharedPreference sharedPreference;    
  
      public OtherNewsAdapter(Context context, List&lt;Latest&gt; feedItemList) {
          this.feedItemList = feedItemList;
          this.mContext = context;
      }
  
      @Override
      public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
          View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_other_news, null);
          ViewHolder mh = new ViewHolder(v);
  
          return mh;
      }
      //method to delete
      public void delete(int position){
          feedItemList.remove(position);
          notifyItemRemoved(position);    
      }
  
      @Override
      public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
          final Latest feedItem = feedItemList.get(i);
  
          Picasso.with(mContext).load(feedItem.getArticleImage())
                  .error(R.drawable.placeholder)
                  .placeholder(R.drawable.placeholder)
                  .into(viewHolder.thumbnail);
  
          viewHolder.title.setText(Html.fromHtml(feedItem.getExcerpt()));
  
          /*If a product exists in shared preferences then set heart_red drawable
           * and set a tag*/
          if (checkFavoriteItem(feedItem)) {
              viewHolder.favImage.setImageResource(R.drawable.heart_red);
              viewHolder.favImage.setTag("red");
              addItem(feedItem);
          } else {
              viewHolder.favImage.setImageResource(R.drawable.heart_grey);
              viewHolder.favImage.setTag("grey");
              addItem(feedItem);
          }   
      }
  
      @Override
      public int getItemCount() {
          return (null != feedItemList ? feedItemList.size() : 0);
      }
  
      View.OnClickListener clickListener = new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              OtherNewsRowHolder holder = (OtherNewsRowHolder) view.getTag();
              int position = holder.getPosition();
  
              Latest feedItem = feedItemList.get(position);
              Toast.makeText(mContext, feedItem.getExcerpt(), Toast.LENGTH_SHORT).show();
          }
      };    
  
      public void addItem(Latest lat){
          feedItemList.add(lat);
          notifyDataSetChanged();
      }
      /*Checks whether a particular product exists in SharedPreferences*/
      public boolean checkFavoriteItem(Latest checkProduct) {
          boolean check = false;
          List&lt;Latest&gt; favorites = sharedPreference.getFavorites(mContext);
          if (favorites != null) {
              for (Latest product : favorites) {
                  if (product.equals(checkProduct)) {
                      check = true;
                      break;
                  }
              }
          }
          return check;
      }    
  
  
      public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
          protected ImageView thumbnail, favImage;
          protected TextView title;
  
          public ViewHolder(View itemView) {
              super(itemView);
              this.thumbnail = (ImageView) itemView.findViewById(R.id.otherImage);
              this.title = (TextView) itemView.findViewById(R.id.otherExcerpt);
              this.favImage = (ImageView) itemView.findViewById(R.id.imgbtn_favorite);
             favImage.setOnClickListener(this);
          }
  
          @Override
          public void onClick(View v) {
  
              String tag = favImage.getTag().toString();
              if (tag.equalsIgnoreCase("grey")) {
                  sharedPreference.addFavorite(mContext, feedItemList.get(getItemCount()));
                  Toast.makeText(mContext,
                          mContext.getResources().getString(R.string.add_favr),
                          Toast.LENGTH_SHORT).show();
  
                  favImage.setTag("red");
                  favImage.setImageResource(R.drawable.heart_red);
              } else {
                  sharedPreference.removeFavorite(mContext, feedItemList.get(getItemCount()));
                  favImage.setTag("grey");
                  favImage.setImageResource(R.drawable.heart_grey);
                  Toast.makeText(mContext,
                          mContext.getResources().getString(R.string.remove_favr),
                          Toast.LENGTH_SHORT).show();
              }    
          }   
      }
  }
  </code></pre>
  
  <p><strong>SharedPreference.java</strong></p>
  
  <pre><code> public class SharedPreference {
      public static final String PREFS_NAME = "NEWS_APP";
      public static final String FAVORITES = "Article_Favorite";
  
      public SharedPreference() {
          super();
      }
      // This four methods are used for maintaining favorites.
      public void saveFavorites(Context context, List&lt;Latest&gt; favorites) {
          SharedPreferences settings;
          SharedPreferences.Editor editor;
  
          settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
          editor = settings.edit();
  
          Gson gson = new Gson();
          String jsonFavorites = gson.toJson(favorites);
  
          editor.putString(FAVORITES, jsonFavorites);
  
          editor.commit();
      }
      public void addFavorite(Context context, Latest product) {
          List&lt;Latest&gt; favorites = getFavorites(context);
          if (favorites == null)
              favorites = new ArrayList&lt;Latest&gt;();
          favorites.add(product);
          saveFavorites(context, favorites);
      }
  
      public void removeFavorite(Context context, Latest product) {
          ArrayList&lt;Latest&gt; favorites = getFavorites(context);
          if (favorites != null) {
              favorites.remove(product);
              saveFavorites(context, favorites);
          }
      }
  
      public ArrayList&lt;Latest&gt; getFavorites(Context context) {
          SharedPreferences settings;
          List&lt;Latest&gt; favorites;
  
          settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
  
          if (settings.contains(FAVORITES)) {
              String jsonFavorites = settings.getString(FAVORITES, null);
              Gson gson = new Gson();
              Latest[] favoriteItems = gson.fromJson(jsonFavorites, Latest[].class);
  
              favorites = Arrays.asList(favoriteItems);
              favorites = new ArrayList&lt;Latest&gt;(favorites);
          } else
              return null;
  
          return (ArrayList&lt;Latest&gt;) favorites;
      }
  }
  </code></pre>
  
  <p><strong>SportsFragment.java</strong></p>
  
  <pre><code>public class SportsFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
      private List&lt;Latest&gt; feedsList;
      private RecyclerView mRecyclerView;
      private OtherNewsAdapter adapter;
      private ProgressBar progressBar;
      private SwipeRefreshLayout swipeSports;
      final String url = "http://javatechig.com/?json=get_recent_posts&amp;count=45";
      public static final String TAG = "sports";
      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          return inflater.inflate(R.layout.sports_fragment_layout, container, false);
      }
  
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          getActivity().setTitle(R.string.sports);
  
          swipeSports=(SwipeRefreshLayout) getActivity().findViewById(R.id.swipeSports);
          swipeSports.setOnRefreshListener(this);
          // Initialize recycler view
          mRecyclerView = (RecyclerView) getActivity().findViewById(R.id.recycler_sports);
          mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
          progressBar = (ProgressBar) getActivity().findViewById(R.id.materialProgress);
          progressBar.setVisibility(View.VISIBLE);
  
          //Async Task
          // Downloading data from below url
  
          new AsyncHttpTask().execute(url);
      }
  
      public void setColorScheme(int colorRes1, int colorRes2, int colorRes3, int colorRes4) {
          swipeSports.setColorScheme(colorRes1, colorRes2, colorRes3, colorRes4);
      }
  
      @Override
      public void onRefresh() {
          new AsyncHttpTask().execute(url);
          setColorScheme(R.color.color_scheme_1_1, R.color.color_scheme_1_2,
                  R.color.color_scheme_1_3, R.color.color_scheme_1_4);
      }
      public class AsyncHttpTask extends AsyncTask&lt;String, Void, Integer&gt; {
  
          @Override
          protected void onPreExecute() {
          //getActivity().setProgressBarIndeterminateVisibility(true);
          }
  
          @Override
          protected Integer doInBackground(String... params) {
              Integer result = 0;
              HttpURLConnection urlConnection;
              try {
                  URL url = new URL(params[0]);
                  urlConnection = (HttpURLConnection) url.openConnection();
                  int statusCode = urlConnection.getResponseCode();
  
                  // 200 represents HTTP OK
                  if (statusCode == 200) {
                      BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                      StringBuilder response = new StringBuilder();
                      String line;
                      while ((line = r.readLine()) != null) {
                          response.append(line);
                      }
                      parseResult(response.toString());
                      result = 1; // Successful
                  } else {
                      result = 0; //"Failed to fetch data!";
                  }
              } catch (Exception e) {
                  Log.d(TAG, e.getLocalizedMessage());
              }
              return result; //"Failed to fetch data!";
          }
  
          @Override
          protected void onPostExecute(Integer result) {
              // Download complete. Let us update UI
              progressBar.setVisibility(View.GONE);
  
  
  
              if (result == 1) {
                  if(swipeSports.isRefreshing()){
                      swipeSports.setRefreshing(false);
                  }
  
  
                  adapter = new OtherNewsAdapter(getActivity(), feedsList);
                  mRecyclerView.setAdapter(adapter);
              } else {
                  adapter=null;
                  mRecyclerView.setAdapter(adapter);
                  if(swipeSports.isRefreshing()){
                      swipeSports.setRefreshing(true);
                  }
                //error.setVisibility(View.VISIBLE);
              }
          }
      }
  
      private void parseResult(String result) {
          try {
              JSONObject response = new JSONObject(result);
              JSONArray posts = response.optJSONArray("posts");
              feedsList = new ArrayList&lt;&gt;();
  
              for (int i = 0; i &lt; posts.length(); i++) {
                  JSONObject post = posts.optJSONObject(i);
                  Latest item = new Latest();
                  item.setExcerpt(post.optString("title"));
                  item.setArticleImage(post.optString("thumbnail"));
  
                  feedsList.add(item);
              }
          } catch (JSONException e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p><strong>row_other_news.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal" android:layout_width="match_parent"
      xmlns:card_view="http://schemas.android.com/apk/res-auto"
      android:layout_margin="5dp"
      card_view:cardCornerRadius="5dp"
      android:layout_height="wrap_content"&gt;
  
      &lt;RelativeLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:paddingBottom="5dp"
          android:paddingTop="5dp"
          android:paddingLeft="5dp"
          &gt;
  
          &lt;ImageView
              android:id="@+id/otherImage"
              android:layout_width="100dp"
              android:layout_height="100dp"
              android:scaleType="centerCrop"
              android:tint="@color/photo_tint"
              android:contentDescription="@string/country"
              android:layout_alignParentLeft="true"
              /&gt;
          &lt;TextView
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:id="@+id/otherExcerpt"
              android:layout_toRightOf="@+id/otherImage"
              android:padding="16dp"/&gt;
  
          &lt;ImageView
              android:id="@+id/imgbtn_favorite"
              android:layout_width="20dp"
              android:layout_marginTop="5dp"
              android:layout_height="20dp"
              android:layout_below="@+id/otherExcerpt"
              android:layout_alignParentRight="true"
              android:layout_marginRight="3dp"
              android:background="@null"
              android:contentDescription="@string/favorites"
              android:clickable="true"/&gt;    
      &lt;/RelativeLayout&gt;
  
  &lt;/android.support.v7.widget.CardView&gt;
  </code></pre>