简体   繁体   中英

Using Recyclerview with Volley not working in fragment

I am trying to use Volley to get data via JSON and populate the data in RecyclerView in fragment. I have tested the code with normal activity and it works, but I am finding it difficult implementing thesame thing in fragment. I can see the response in JSON format when I Log in console but it seems no data is added to the list item, thus nothing is displayed in fragment and no error in LogCat.

explore_content.xml

This is the xml that'l be inflated in the adapter

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/imagesExplore1"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/testUrl"
            android:layout_below="@+id/imagesExplore1"
            android:paddingLeft="50dp"
            android:textSize="19sp"
            />

</RelativeLayout>

fragment_challenge.xml

This is where I put the RecyclerView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="fragments.ChallengeFragment">


<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/testRecyclerView"
    android:paddingBottom="20dp"
    android:paddingStart="10dp"
    android:paddingEnd="10dp"
    android:scrollbars="vertical"
    android:layout_marginTop="20dp"
    />

</RelativeLayout>

ExploreImagesAdapter.java

The adapter I use

public class ExploreImagesAdapter extends RecyclerView.Adapter<ExploreImagesAdapter.MyViewHolder> {
private Context context;
private List<ExploreImages> exploreImagesList;
RequestOptions options;

public ExploreImagesAdapter(Context context, List<ExploreImages> exploreImagesList) {
    this.context = context;
    this.exploreImagesList = exploreImagesList;
    options = new RequestOptions().centerCrop().placeholder(R.drawable.add_photo).error(R.drawable.back_left_icon);
}

@NonNull
@Override
public ExploreImagesAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.explore_content, parent, false);
    return new ExploreImagesAdapter.MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {

Glide.with(context).load(exploreImagesLlist.get(position).getImage_url()).apply(options).into(holder.imageView);
holder.testUrl.setText(exploreImagesList.get(position).getImage_url());
}

@Override
public int getItemCount() {
    int a ;

    if(exploreImagesList != null && exploreImagesList.isEmpty()) {

        a = exploreImagesList.size();
    }
    else {

        a = 0;

    }
    return a;
}

public static class MyViewHolder extends RecyclerView.ViewHolder{

    ImageView imageView;
    TextView testUrl;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        imageView = itemView.findViewById(R.id.imagesExplore1);
        testUrl = itemView.findViewById(R.id.testUrl);

    }
}

public void setItems(List<ExploreImages> data) {
    exploreImagesList = data;
    notifyDataSetChanged();

}

public void addData (List<ExploreImages> data) {
    exploreImagesList.addAll(data);
    notifyDataSetChanged();
}
}

ExploreImages.java

A model for the data

ublic class ExploreImages {

private String image_id;
private String image_url;
private String photo_year;

public ExploreImages(){

}

public ExploreImages(String image_id, String image_url, String photo_year) {
    this.image_id = image_id;
    this.image_url = image_url;
    this.photo_year = photo_year;
}

public String getImage_id() {
    return image_id;
}

public String getImage_url() {
    return image_url;
}

public String getPhoto_year(){
    return  photo_year;
}


public void setImage_id(String image_id) {
    this.image_id = image_id;
}

public void setImage_url(String image_url) {
    this.image_url = image_url;
}

public void setPhoto_year(String photo_year){ this.photo_year = photo_year;}

}

ExploreFragment.java

Finally the fragment where I make the network call and set the Adapter

public class ExploreFragment extends Fragment {

private JsonArrayRequest request;
private RequestQueue requestQueue;
private List<ExploreImages> lstAnime;
private ArrayList<ExploreImages> tempList;


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

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

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


    lstAnime = new ArrayList<>();

    View root = inflater.inflate(R.layout.fragment_explore, container, false);

    RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.testRecyclerView);

    ExploreImagesAdapter myAdapter = new ExploreImagesAdapter(getActivity(), lstAnime);


    recyclerView.setAdapter(myAdapter);

    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

   /* myAdapter.notifyDataSetChanged();*/

    jsonrequest();

    // Inflate the layout for this fragment
    return root;
}


private void jsonrequest() {
    request = new JsonArrayRequest(EndPoints.EXPLORE_IMAGES_URL, new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {

            /*Log.e("Errorrr", "["+response+"]");*/
            JSONObject jsonObject = null;
            int i;

            for(i=0; i<response.length(); i++){
                try {
                    jsonObject = response.getJSONObject(i);
                    ExploreImages anime = new ExploreImages();
                    anime.setImage_id(jsonObject.getString("id"));
                    anime.setImage_url(jsonObject.getString("url"));
                    anime.setPhoto_year(jsonObject.getString("photo_year"));;
                    Log.e("CHAAAA", "["+response+"]");
                    lstAnime.add(anime);
                    ExploreImagesAdapter myAdapter = new ExploreImagesAdapter(getActivity(), 
lstAnime);
                    myAdapter.setItems(lstAnime);
                }
                catch (JSONException e){
                    e.printStackTrace();
                    Log.e("TESTERROR", "["+response+"]");
                }

                /*ExploreImagesAdapter myAdapter = new ExploreImagesAdapter(getActivity(), lstAnime);

                myAdapter.addData(lstAnime);*/

               setRecyclerView(lstAnime);
            }


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

        }
    });

    requestQueue = Volley.newRequestQueue(getActivity());
    requestQueue.add(request);
}


private void setRecyclerView(List<ExploreImages> lstAnime) {
    RecyclerView recyclerViewx = getActivity().findViewById(R.id.testRecyclerView);
    ExploreImagesAdapter myAdapter = new ExploreImagesAdapter(getActivity(), lstAnime);
    recyclerViewx.setAdapter(myAdapter);
    recyclerViewx.setLayoutManager(new LinearLayoutManager(getActivity()));
}
}

I have searched Everywhere and tried everything but no data is displayed even when the JSON is parsed in Volley

you are doing several things wrong here

  1. make ExploreImagesAdapter as global variable inside of fragment and use it everywhere else
  2. now when you will get your data just call your adapter and add Data in it you already have function for that.

First of all you're always creating a new Adapter instance and you shouldn't. Keep one instance global to this Fragment and you're good to go. Then update that same instance.

Using your code:

private ExploreImagesAdapter myAdapter;


  @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {
    lstAnime = new ArrayList<>();
    View root = inflater.inflate(R.layout.fragment_explore, container, false);
    RecyclerView recyclerViewx = getActivity().findViewById(R.id.testRecyclerView);
    myAdapter = new ExploreImagesAdapter(getActivity(), lstAnime);
    recyclerViewx.setAdapter(myAdapter);
    recyclerViewx.setLayoutManager(new LinearLayoutManager(getActivity()));
    jsonrequest();
    return root;
}


private void jsonrequest() {
    request = new JsonArrayRequest(EndPoints.EXPLORE_IMAGES_URL, new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {

            /*Log.e("Errorrr", "["+response+"]");*/
            JSONObject jsonObject = null;
            int i;

            for(i=0; i<response.length(); i++){
                try {
                    jsonObject = response.getJSONObject(i);
                    ExploreImages anime = new ExploreImages();
                    anime.setImage_id(jsonObject.getString("id"));
                    anime.setImage_url(jsonObject.getString("url"));
                    anime.setPhoto_year(jsonObject.getString("photo_year"));;
                    Log.e("CHAAAA", "["+response+"]");
                    lstAnime.add(anime);                      
                }
                catch (JSONException e){
                    e.printStackTrace();
                    Log.e("TESTERROR", "["+response+"]");
                }
            }
            myAdapter.setItems(lstAnime);    
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });

    requestQueue = Volley.newRequestQueue(getActivity());
    requestQueue.add(request);
}

Do these things

1) Set linearlayout manager after declaring recyclerview

2) Declare recyclerview and adapter class globally

3) Update adapter after parsing JSON array to arraylist

Eg

public class ExploreFragment extends Fragment {

private JsonArrayRequest request;
private RequestQueue requestQueue;
private List<ExploreImages> lstAnime;
private ArrayList<ExploreImages> tempList;
ExploreImagesAdapter myAdapter;

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

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    lstAnime = new ArrayList<>();
    View root = inflater.inflate(R.layout.fragment_explore, container, false);

    RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.testRecyclerView);
// set layout manager here
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    myAdapter = new ExploreImagesAdapter(getActivity(), lstAnime);
    recyclerView.setAdapter(myAdapter);

    jsonrequest();

    // Inflate the layout for this fragment
    return root;
}


private void jsonrequest() {
    request = new JsonArrayRequest(EndPoints.EXPLORE_IMAGES_URL, new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {

            /*Log.e("Errorrr", "["+response+"]");*/
            JSONObject jsonObject = null;
            int i;

            for(i=0; i<response.length(); i++){
                try {
                    jsonObject = response.getJSONObject(i);
                    ExploreImages anime = new ExploreImages();
                    anime.setImage_id(jsonObject.getString("id"));
                    anime.setImage_url(jsonObject.getString("url"));
                    anime.setPhoto_year(jsonObject.getString("photo_year"));;
                    Log.e("CHAAAA", "["+response+"]");
                    lstAnime.add(anime);

                }
                catch (JSONException e){
                    e.printStackTrace();
                    Log.e("TESTERROR", "["+response+"]");
                }


            }
       // update adapter here
                    myAdapter.notifyDataSetChanged();


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

        }
    });

    requestQueue = Volley.newRequestQueue(getActivity());
    requestQueue.add(request);
}



}
RecyclerView recyclerViewx = getActivity().findViewById(R.id.testRecyclerView);

this line refers to the RecyclerView in your activity. You should use in the fragment

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM