简体   繁体   中英

RecyclerView Does Not Load Data Initially

I'm using a Spinner and a RecyclerView in a Fragment in my Android project. My RecyclerView does not show any data until I select an item in the Spinner. What should I do to show the RecyclerView's result without selecting an item from the Spinner? at the first recycler should show 10 attraction.

My code:

Attraction.java

 package com.rayantec.reservation.reservationdemo.Model; import android.app.ProgressDialog; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.android.volley.DefaultRetryPolicy; 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.JsonArrayRequest; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.Volley; import com.rayantec.reservation.reservationdemo.Adapter.AttractionAdapter; import com.rayantec.reservation.reservationdemo.G; import com.rayantec.reservation.reservationdemo.Lists.AttractionList; import com.rayantec.reservation.reservationdemo.Lists.CityList; import com.rayantec.reservation.reservationdemo.R; import com.toptoche.searchablespinnerlibrary.SearchableSpinner; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; public class Attractions extends Fragment { RecyclerView recyclerView; ArrayList<AttractionList> AttractionData = new ArrayList<>(); public SearchableSpinner spinnerCitiest; ArrayList<CityList> cityLists = new ArrayList<>(); ProgressDialog progressDialog; public void showCity(View view) { spinnerCitiest = (SearchableSpinner) view.findViewById(R.id.SpinnerCitiestId); spinnerCitiest.setTitle("Please Select City"); spinnerCitiest.setPositiveButton("Ok"); //spinnerCitiest.setSelection(2); JsonArrayRequest JsonObjectRequest = new JsonArrayRequest(Request.Method.GET, G.serverURL + "/android/jsyncs/getdata/city", null, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { //progressDialog.dismiss(); try { for (int i = 0; i < response.length(); i++) { JSONObject jsonOBJ = response.getJSONObject(i); String id = jsonOBJ.getString("id"); String title = jsonOBJ.getString("title"); cityLists.add(new CityList(id, title)); } } catch (JSONException e1) { e1.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //progressDialog.dismiss(); Toast.makeText(G.context, "Server Connection error", Toast.LENGTH_SHORT).show(); } }); JsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(7000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); RequestQueue requestQueue = Volley.newRequestQueue(G.context); requestQueue.add(JsonObjectRequest); ArrayAdapter<CityList> adapterCities = new ArrayAdapter<CityList>(G.context, android.R.layout.simple_spinner_item, cityLists); adapterCities.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerCitiest.setAdapter(adapterCities); spinnerCitiest.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) { CityList cityList = (CityList) adapterView.getSelectedItem(); Toast.makeText(G.context, "City ID: " + cityList.getId() + ", City Name : " + cityList.getTitle(), Toast.LENGTH_SHORT).show(); } @Override public void onNothingSelected(AdapterView<?> adapterView) { } }); } public void showRandomAttractions(View view) { recyclerView = (RecyclerView) view.findViewById(R.id.RecyclerAttracionId); JsonArrayRequest JsonObjectRequests = new JsonArrayRequest(Request.Method.GET, G.serverURL + "/android/jsyncs/getdata/randattraction", null, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { progressDialog.dismiss(); //AttractionList sampledata = new AttractionList(); try { for (int i = 0; i < response.length(); i++) { JSONObject jsonOBJs = response.getJSONObject(i); String id = jsonOBJs.getString("id"); String title = jsonOBJs.getString("title"); String imageUrl = jsonOBJs.getString("imageUrl"); String location = jsonOBJs.getString("location"); String type = jsonOBJs.getString("type"); String body = jsonOBJs.getString("body"); AttractionData.add(new AttractionList(id, title, body, location, imageUrl, type)); } } catch (JSONException e1) { e1.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { progressDialog.dismiss(); Toast.makeText(G.context, "Server Connection error", Toast.LENGTH_SHORT).show(); } }); JsonObjectRequests.setRetryPolicy(new DefaultRetryPolicy(7000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); RequestQueue requestQueue = Volley.newRequestQueue(G.context); requestQueue.add(JsonObjectRequests); recyclerView.setLayoutManager(new LinearLayoutManager(G.context, LinearLayoutManager.VERTICAL, false)); AttractionAdapter attractionAdapter = new AttractionAdapter(AttractionData); recyclerView.setAdapter(attractionAdapter); } public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.attraction, container, false); progressDialog = new ProgressDialog(getActivity()); progressDialog.setMessage("Please wait ..."); progressDialog.setCancelable(false); progressDialog.show(); showCity(view); showRandomAttractions(view); return view; } } 

Attraction.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.CardView android:id="@+id/cardviewattraction" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginStart="8dp" android:layout_marginTop="16dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:padding="3dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <com.toptoche.searchablespinnerlibrary.SearchableSpinner android:id="@+id/SpinnerCitiestId" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:padding="3dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.v7.widget.CardView> <android.support.v7.widget.RecyclerView android:id="@+id/RecyclerAttracionId" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/cardviewattraction" tools:ignore="MissingConstraints" /> </android.support.constraint.ConstraintLayout> 

AttractionAdapter

 package com.rayantec.reservation.reservationdemo.Adapter; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.rayantec.reservation.reservationdemo.Lists.AttractionList; import com.rayantec.reservation.reservationdemo.R; import com.squareup.picasso.Picasso; import java.util.ArrayList; public class AttractionAdapter extends RecyclerView.Adapter<AttractionAdapter.AttractionViewHolder> { ArrayList<AttractionList> attractionArrayList; public AttractionAdapter(ArrayList<AttractionList> attractions) { attractionArrayList = new ArrayList<>(); attractionArrayList = attractions; } @NonNull @Override public AttractionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_attraction, parent, false); return new AttractionViewHolder(view); } @Override public void onBindViewHolder(@NonNull AttractionViewHolder holder, int position) { AttractionList dataModel = attractionArrayList.get(position); holder.txtTitle.setText(dataModel.getTitle()); holder.txtBody.setText(dataModel.getBody()); holder.txtType.setText(dataModel.getType()); holder.txtLocation.setText(dataModel.getLocation()); Picasso.get().load(dataModel.getImgUrl()).resize(130, 100).centerCrop().into(holder.imgAttraction); } @Override public int getItemCount() { return attractionArrayList.size(); } public class AttractionViewHolder extends RecyclerView.ViewHolder{ public ImageView imgAttraction; public TextView txtTitle; public TextView txtBody; public TextView txtLocation; public TextView txtType; public AttractionViewHolder(View itemView) { super(itemView); imgAttraction = (ImageView)itemView.findViewById(R.id.img_recycler_attraction); txtTitle = (TextView)itemView.findViewById(R.id.txt_recycler_attractionTitle); txtBody = (TextView)itemView.findViewById(R.id.txt_recycler_attractionBody); txtLocation = (TextView)itemView.findViewById(R.id.txt_recycler_attractionPositions); txtType = (TextView)itemView.findViewById(R.id.txt_recycler_attractionType); } // } } 

AttractionList.java

 package com.rayantec.reservation.reservationdemo.Lists; public class AttractionList { private String id; private String title; private String body; private String location; private String imgUrl; public AttractionList(String id, String title, String body, String location, String imgUrl, String type) { this.id = id; this.title = title; this.body = body; this.location = location; this.imgUrl = imgUrl; this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } private String type; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public String getImgUrl() { return imgUrl; } public void setImgUrl(String imgUrl) { this.imgUrl = imgUrl; } } 

There are a few things that you should test, did you check to see if you're receiving the onResponse callback in your showRandomAttractions(View view) method? This would verify that the Get call is working as intended.

If you are receiving that onResponse call, try calling attractionAdapter.notifyDataSetChanged() after your for-loop when you're done adding data to your AttractionData ArrayList. It would look like this:

            try {
                for (int i = 0; i < response.length(); i++) {
                    JSONObject jsonOBJs = response.getJSONObject(i);
                    String id = jsonOBJs.getString("id");
                    String title = jsonOBJs.getString("title");
                    String imageUrl = jsonOBJs.getString("imageUrl");
                    String location = jsonOBJs.getString("location");
                    String type = jsonOBJs.getString("type");
                    String body = jsonOBJs.getString("body");
                    AttractionData.add(new AttractionList(id, title, body, location, imageUrl, type));

                    // Notify your adapter that its data has changed.
                    attractionAdapter.notifyDataSetChanged();
                }
            } catch (JSONException e1) {
                e1.printStackTrace();
            }

You can check out this documentation for more info on how notifyDataSetChanged works.

I believe your request to the server to collect the Data is Asynchronous and happens on a Worker Thread . If that's the case then your View is rendered before actually getting the data.

I would suggest to add a setData function in your adapter:

public void setData(ArrayList<Attractions> attractions){
        this.attractionArrayList = attractions
        notifyDataSetChanged()
}

Then on your activity when you get the response and build the array of attraction, just call adapter.setData(attractions)

UPDATE: Make sure to set your adapter when the view is actually initialized, so you need to call it on onViewCreated:

public void onViewCreated(View view,Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    showCity(view);
    showRandomAttractions(view);
}

by replace this line after try/catch this problem solved

recyclerView.setLayoutManager(new LinearLayoutManager(G.context, LinearLayoutManager.VERTICAL, false));
            AttractionAdapter attractionAdapter = new AttractionAdapter(AttractionData);
            recyclerView.setAdapter(attractionAdapter);

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