X09
X09

Reputation: 3956

Why Cant I Pass This JSON Object to Another Activity

I am fetching news Items from Json using Volley. In the MainActivity I have successfully fetched and parsed the json, so I have no problem with that. Now each news item contains a title and an excerpt of the news. What I wanted was that each time the news excerpt is clicked, it will start another activity called NewsDetails, during the starting, the "ID" (a json object) of the news excerpt clicked, will be sent to NewsDetails.

In NewsDetails I will concatenate the "ID" and the url of the website; this will also return a json array. Then I'll parse the json and display it; hopefully this won't give me a problem.

Where I am experiencing difficulties is trying to send the "ID" and starting the "NewsDetails".

So far this is what I have been doing:

All MainActivity class

  public class MainActivity extends AppCompatActivity{

    private final String TAG = "MainActivity";

    //Creating a list of newss
    private List<NewsItems> mNewsItemsList;

    //Creating Views
    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private ProgressDialog mProgressDialog;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "Device rotated and onCreate called");

        //Initializing Views
        recyclerView = (RecyclerView) findViewById(R.id.news_recycler);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);



        //Initializing the newslist
        mNewsItemsList = new ArrayList<>();
        adapter = new NewsAdapter(mNewsItemsList, this);

        recyclerView.setAdapter(adapter);



        //Caling method to get data
         getData();

    }


    //This method will get data from the web api

    private void getData(){


        Log.d(TAG, "getData called");
        //Showing progress dialog
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setCancelable(false);
        mProgressDialog.setMessage(this.getResources().getString(R.string.load_news));
        mProgressDialog.show();


        //Creating a json request
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigNews.GET_URL,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d(TAG, "onResponse called");
                        //Dismissing the progress dialog
                        if (mProgressDialog != null) {
                            mProgressDialog.hide();
                        }
                        /*progressDialog.dismiss();*/


                        //calling method to parse json array
                        parseData(response);

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });

        //Creating request queue
        RequestQueue requestQueue = Volley.newRequestQueue(this);

        //Adding request to the queue
        requestQueue.add(jsonArrayRequest);

    }

    //This method will parse json data
    private void parseData(JSONArray array){
        Log.d(TAG, "Parsing array");

        for(int i = 0; i<array.length(); i++) {
            NewsItems newsItem = new NewsItems();
            JSONObject jsonObject = null;
            try {
                jsonObject = array.getJSONObject(i);
                newsItem.setNews_title(jsonObject.getString(ConfigNews.TAG_NEWS_TITLE));
                newsItem.setNews_excerpt(jsonObject.getString(ConfigNews.TAG_NEWS_EXCERPT));
                newsItem.setNewsId(jsonObject.getInt(ConfigNews.TAG_NEWS_ID));

            } catch (JSONException w) {
                w.printStackTrace();
            }
            mNewsItemsList.add(newsItem);

        }

        adapter.notifyItemRangeChanged(0, adapter.getItemCount());


    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy called");
        if (mProgressDialog != null){
            mProgressDialog.dismiss();
            Log.d(TAG, "mProgress dialog dismissed");

        }
    }

}

No problem from the code above.

The Whole NewsItems class

public class NewsItems {
      private String news_title;
      private String news_excerpt;
      private String news_id;

      public String getNews_title() {
          return news_title;
      }

      public void setNews_title(String news_title) {
          this.news_title = news_title;
      }

      public String getNews_excerpt() {
          return news_excerpt;
      }

      public void setNews_excerpt(String news_excerpt) {
          this.news_excerpt = news_excerpt;
      }

      public String getNews_id() {
          return news_id;
      }

      public void setNews_id(String news_id) {
          this.news_id = news_id;
      }

  }

Still no problems from above code.

All of NewsAdapter

   public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    private ImageLoader imageLoader;
    private Context mContext;

    //List of newss
    private List<NewsItems> mNewsItems;

    private final int VIEW_ITEM = 0;
    private final int VIEW_PROG = 1;

    private int lastPosition = -1;

   public NewsAdapter(List<NewsItems> newsItems, Context context) {
       super();

       //Getting all newss
       this.mNewsItems = newsItems;
       this.mContext = context;
   }

    @Override
    public int getItemViewType(int position) {
        if (isPositionItem(position))
            return VIEW_ITEM;
        return VIEW_PROG;
    }

    private boolean isPositionItem(int position) {
       return position != getItemCount()-1;
    }



    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
        if (viewType == VIEW_ITEM) {
            View v =  LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.news_summ, parent, false);
            return new TextViewHolder(v);
        } else if (viewType == VIEW_PROG){
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.recyclerfooter, parent, false);
            return new ProgressViewHolder(v);
        }

        return null;
    }



    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {


        if (holder instanceof TextViewHolder) {
            NewsItems newsList = mNewsItems.get(position);
            ((TextViewHolder) holder).newsTitle.setText(newsList.getNews_title());
            ((TextViewHolder) holder).newsExcerpt.setText(newsList.getNews_excerpt());
            ((TextViewHolder) holder).newsId.setText(String.valueOf(newsList.getNewsId()));

        } else {
            ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
            ((ProgressViewHolder) holder).loadButton.setText(R.string.reload);
        }


    }


    @Override
    public int getItemCount(){
        //Return the number of items in the data set
        return mNewsItems.size();
    }




    public static class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView newsTitle,newsExcerpt, newsId;
        public ImageButton imageButton;
        public NewsItems dNewsItems;

        public TextViewHolder (final View newsView) {
            super(newsView);
            newsTitle = (TextView) newsView.findViewById(R.id.news_title);
            newsExcerpt = (TextView) newsView.findViewById(R.id.news_excerpt);
            newsId = (TextView) newsView.findViewById(R.id.news_id);

            newsExcerpt.setOnClickListener(this);


        }



        @Override
        public void onClick(View v) {


            if (v.getId() == newsExcerpt.getId()) {
               if (v.getId() == newsExcerpt.getId()) {
               Intent i = NewsDetails.newIntent(getActivity(), dNewsItems.getNews_id());
               startActivity(i);
               }
            }
        }
    }

    public static class ProgressViewHolder extends RecyclerView.ViewHolder implements  View.OnClickListener{
        Button loadButton;
        ProgressBar progressBar;
        public ProgressViewHolder(View footerView){
            super(footerView);
            loadButton = (Button) footerView.findViewById(R.id.reload_button);
            progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);

            loadButton.setOnClickListener(this);

            if(NetworkCheck.isAvailableAndConnected(footerView.getContext())) {
                progressBar.setVisibility(View.VISIBLE);


            } else if (!NetworkCheck.isAvailableAndConnected(footerView.getContext())) {
                loadButton.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onClick(View v) {
            if (v.getId() == loadButton.getId()) {
                //
            }
        }
    }


}

This is the part that's giving me problems.

Specifically lines

Intent i = NewsDetails.newIntent(getActivity(), dNewsItems.getNews_id());
                   startActivity(i);

When I hover I hove newIntent it says "Cannot resolve method 'newIntent(?, java.lang.String)'". Then I hover getActivity() it says "Cannot resolve method 'getActivity()'". For startActivity(i); it's "Cannot resolve method 'startActivity(android.content.Intent)'"

So now, my question is what am I doing wrong and how should I correct it?

NewsAdapter After Implementing Rohit Arya's answer

public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    private ImageLoader imageLoader;
    private Context mContext;

    //List of newss
    private List<NewsItems> mNewsItems;

    private final int VIEW_ITEM = 0;
    private final int VIEW_PROG = 1;

    private int lastPosition = -1;

   public NewsAdapter(List<NewsItems> newsItems, Context context) {
       super();

       //Getting all newss
       this.mNewsItems = newsItems;
       this.mContext = context;
   }

    @Override
    public int getItemViewType(int position) {
        if (isPositionItem(position))
            return VIEW_ITEM;
        return VIEW_PROG;
    }

    private boolean isPositionItem(int position) {
       return position != getItemCount()-1;
    }



    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
        if (viewType == VIEW_ITEM) {
            View v =  LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.news_summ, parent, false);
            return new TextViewHolder(v, mContext);
        } else if (viewType == VIEW_PROG){
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.recyclerfooter, parent, false);
            return new ProgressViewHolder(v);
        }

        return null;
    }



    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {


        if (holder instanceof TextViewHolder) {
            NewsItems newsList = mNewsItems.get(position);
            ((TextViewHolder) holder).newsTitle.setText(newsList.getNews_title());
            ((TextViewHolder) holder).newsExcerpt.setText(newsList.getNews_excerpt());
            ((TextViewHolder) holder).newsId.setText(String.valueOf(newsList.getNewsId()));

        } else {
            ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
            ((ProgressViewHolder) holder).loadButton.setText(R.string.reload);
        }


    }


    @Override
    public int getItemCount(){
        //Return the number of items in the data set
        return mNewsItems.size();
    }




    public static class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView newsTitle,newsExcerpt, newsId;
        public ImageButton imageButton;
        public NewsItems dNewsItems;
        private Context context;

        public TextViewHolder (final View newsView, final Context context) {
            super(newsView);
            newsTitle = (TextView) newsView.findViewById(R.id.news_title);
            newsExcerpt = (TextView) newsView.findViewById(R.id.news_excerpt);
            newsId = (TextView) newsView.findViewById(R.id.news_id);

            newsExcerpt.setOnClickListener(this);


        }



        @Override
        public void onClick(View v) {


            if (v.getId() == newsExcerpt.getId()) {
               int newsid = 4536;
               Intent myItent = new Intent(context, NewsDetails.class);
               myItent.putExtra("key", newsid);
               context.startActivity(myItent);
               }
            }
        }
    }

    public static class ProgressViewHolder extends RecyclerView.ViewHolder implements  View.OnClickListener{
        Button loadButton;
        ProgressBar progressBar;
        public ProgressViewHolder(View footerView){
            super(footerView);
            loadButton = (Button) footerView.findViewById(R.id.reload_button);
            progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);

            loadButton.setOnClickListener(this);

            if(NetworkCheck.isAvailableAndConnected(footerView.getContext())) {
                progressBar.setVisibility(View.VISIBLE);


            } else if (!NetworkCheck.isAvailableAndConnected(footerView.getContext())) {
                loadButton.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onClick(View v) {
            if (v.getId() == loadButton.getId()) {
                //
            }
        }
    }


}

Stacktrace from implementing Rohit Arya's answer

04-12 20:15:25.424 8772-8772/com.newsus.app E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: com.newsus.app, PID: 8772
                                                                   java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                                       at android.content.ComponentName.<init>(ComponentName.java:77)
                                                                       at android.content.Intent.<init>(Intent.java:4336)
                                                                       at com.newsus.app.NewsAdapter$TextViewHolder.onClick(NewsAdapter.java:181)
                                                                       at android.view.View.performClick(View.java:5076)
                                                                       at android.view.View$PerformClick.run(View.java:20279)
                                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                       at android.os.Looper.loop(Looper.java:135)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5910)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

From the stacktrace, line 81, coressponds to line Intent myIntent = new Intent(context, NewsDetails.class); of his answer.

Upvotes: 1

Views: 320

Answers (2)

Rohit Arya
Rohit Arya

Reputation: 6791

Change TextViewHolder's constructor to receive context like this:

public static class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
      public TextView newsTitle, newsExcerpt;
      public ImageButton imageButton;
      public NewsItems dNewsItems;
      private Context context;

      public TextViewHolder (final View newsView, final Context context) {
          super(newsView);
          this.context = context;   // EDIT 1: You are missing this
          newsTitle = (TextView) newsView.findViewById(R.id.news_title);
          newsExcerpt = (TextView) newsView.findViewById(R.id.news_excerpt);
          newsExcerpt.setOnClickListener(this);
      }

Now use this context to launch activity like this:

Intent myIntent = new Intent(context, NewsDetails.class);
myIntent.putExtra("key", value); //Optional parameters
context.startActivity(myIntent);

Upvotes: 2

tyczj
tyczj

Reputation: 73946

ViewHolder does not have a method getActivity() if you need context in a viewholder you have to pass it in your constructor.

same thing with startActivity() you need context for that too

Upvotes: 0

Related Questions