0

Ok, so im currently working on a app that gives memes, its a project for my own learning but im really stuck at one point from 4 days and this error is just a small part of it... so now i have created a method in afragment called Explore Fragment and i have created a switch in mainactivity which changes the fragment when a particular button in bottom navigation is clicked, so there i call this method when the user clicks on explore tab, but when i click on explore tab the app crashes and returns 2 errors. errors are -

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference at com.example.memeit.ExploreFragment$2.onResponse(ExploreFragment.java:148) at com.example.memeit.ExploreFragment$2.onResponse(ExploreFragment.java:136)

line 148 - list.add(class_object);

line 136 - JsonObjectRequest response = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener()

please help

Main Activity -

package com.example.memeit;

import android.content.Context;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    BottomNavigationView bottomnavigation;
    Toolbar toolbar;
    FragmentTransaction transaction;
    ArrayList<exploreclass> list;
    public RecyclerView rcv1_explore;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setSupportActionBar(toolbar);

        transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.framelayout, new HomeFragment());
        transaction.commit();
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        bottomnavigation = (BottomNavigationView) findViewById(R.id.bottom_navigation);
        rcv1_explore =(RecyclerView) findViewById(R.id.rcv_explore);
        list = new ArrayList<>();

        bottomnavigation.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@org.jetbrains.annotations.NotNull MenuItem item) {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

                switch (item.getItemId())
                {
                    case R.id.home :
                        transaction.replace(R.id.framelayout, new HomeFragment());
                        break;

                    case R.id.explore:
                        transaction.replace(R.id.framelayout, new ExploreFragment());
                        ExploreFragment exploreFragment = new ExploreFragment();
                        exploreFragment.ExtractMemes(getApplicationContext(), "https://meme-api.herokuapp.com/gimme/30");
                        break;

                    case R.id.saved:
                        transaction.replace(R.id.framelayout, new SavedFragment());
                        break;

                    case R.id.settings:
                        transaction.replace(R.id.framelayout, new SettingsFragment());
                        break;
                }
                transaction.commit();

                return true;
            }
        });

    }

}

Explore Fragment -

package com.example.memeit;

import static com.android.volley.VolleyLog.TAG;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link ExploreFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class ExploreFragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    public String BASEURL = "https://meme-api.herokuapp.com/gimme/30";
    public TextView tv1_likes;
    public RecyclerView rcv1_explore;
    public Context context;
    public ArrayList<exploreclass> list;
    public boolean isScrolling = false;
    public int currentItems, totalItems, scrolledOutItems;
    public LinearLayoutManager manager;
    public explore_adapter adapter;

    public ExploreFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment ExploreFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ExploreFragment newInstance(String param1, String param2) {
        ExploreFragment fragment = new ExploreFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_explore, container, false);
        tv1_likes =(TextView) view.findViewById(R.id.tv1_explore);
        list = new ArrayList<>();
        rcv1_explore =(RecyclerView) view.findViewById(R.id.rcv_explore);
        rcv1_explore.setHasFixedSize(true);

        rcv1_explore.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if(newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                    isScrolling = true;
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                totalItems = manager.getItemCount();
                currentItems = manager.getChildCount();
                scrolledOutItems = manager.findFirstVisibleItemPosition();


                if(isScrolling && (totalItems == currentItems + scrolledOutItems)) {
                    isScrolling = false;
                    fetchMoreData();
                }
            }
        });

        return view;
    }


    public void ExtractMemes(Context context, String url) {
        RequestQueue queue = Volley.newRequestQueue(context);
        JsonObjectRequest response = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray memes_array = response.getJSONArray("memes");
                    for(int i=0; i<memes_array.length(); i++) {
                        JSONObject memes_object = memes_array.getJSONObject(i);

                        exploreclass class_object = new exploreclass();
                        class_object.setUps(memes_object.getInt("ups"));
                        class_object.setUrl(memes_object.getString("url"));
                        class_object.setPostLink(memes_object.getString("postLink"));
                        list.add(class_object);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                LinearLayoutManager manager = new LinearLayoutManager(getContext());
                explore_adapter adapter = new explore_adapter(list, getContext());
                rcv1_explore.setLayoutManager(manager);
                rcv1_explore.setAdapter(adapter);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getContext(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
            }
        });

        queue.add(response);

    }



    private void fetchMoreData() {

        RequestQueue queue = Volley.newRequestQueue(getContext());
        JsonObjectRequest response = new JsonObjectRequest(Request.Method.GET, BASEURL, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {

                try {
                    JSONArray memes_array = response.getJSONArray("memes");
                    for(int i=0; i<memes_array.length(); i++) {
                        JSONObject memes_object = memes_array.getJSONObject(i);

                        exploreclass class_object = new exploreclass();
                        class_object.setUps(memes_object.getInt("ups"));
                        class_object.setUrl(memes_object.getString("url"));
                        class_object.setPostLink(memes_object.getString("postLink"));
                        list.add(class_object);
                        adapter.notifyDataSetChanged();
                        Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getContext(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
            }
        });

        queue.add(response);

    }
}

1 Answers1

0

It seems your list is not initialized when you call the method ExtractMemes so the object is null.

The method is called before the onCreateView

Try to init it at the declaration.

Edit :

In first case, you are initializing the fragment twice and use the method in the instance who is not send to the FragmentTransaction. Here a correct way :

case R.id.explore:
        ExploreFragment exploreFragment = new ExploreFragment();
        transaction.replace(R.id.framelayout, exploreFragment);
        exploreFragment.ExtractMemes(getApplicationContext(), "https://meme-api.herokuapp.com/gimme/30");
        break;

Then, in ExtractMemes method, you are using list who is initialized in OnCreatView.

But, the createView is called after the transaction.commit(). You have to init list at the declaration or at the creation of the Fragment.

Weyrloc
  • 16
  • 3
  • Sorry I'm not so good at android, i didn't understood your response, you said that the method is called before onCreateView, but the method is called in the switch statement after on create, so I didn't understood what you meant? Also you said I have to initialize it, so that means I should initialize it in the switch case 2 statement? – Jeet Saluja Nov 05 '21 at 11:46
  • I just edited my answer. – Weyrloc Nov 05 '21 at 13:41