I'm trying to add a load more.
I tried to apply what I'd search and it doesn't work.
here's my code.
LatestGradeFragment
public class LatestGradeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
List<ListGradeData> sectionList;
RecyclerView recyclerView;
SwipeRefreshLayout mSwipeRefreshLayout;
public static LatestGradeFragment newInstance() {
return new LatestGradeFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_latest_grade, container, false);
//RecyclerView+CardView for section
recyclerView = (RecyclerView) rootView.findViewById(R.id.display_recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
sectionList = new ArrayList<>();
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeRefreshSection);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary,
android.R.color.holo_green_dark,
android.R.color.holo_orange_dark,
android.R.color.holo_blue_dark);
mSwipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
// Fetching data from server
loadSection();
}
});
return rootView;
}
#Override
public void onRefresh() {
loadSection();
}
private void loadSection() {
mSwipeRefreshLayout.setRefreshing(true);
StringRequest stringRequest = new StringRequest(Request.Method.GET, Constants.USER_GRADE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONArray array = new JSONArray(response);
if(sectionList!=null) {
sectionList.clear();
}
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject sections = array.getJSONObject(i);
//adding the product to product list
sectionList.add(new ListGradeData(
sections.getInt("id"),
sections.getString("section"),
sections.getString("level"),
sections.getString("schoolyear")
));
}
//creating adapter object and setting it to recyclerview
LatestGradeAdapter adapter = new LatestGradeAdapter(getActivity(), sectionList);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
// Stopping swipe refresh
mSwipeRefreshLayout.setRefreshing(false);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Stopping swipe refresh
mSwipeRefreshLayout.setRefreshing(false);
}
});
//adding our stringrequest to queue
Volley.newRequestQueue(getActivity().getApplicationContext()).add(stringRequest);
}
#Override
public String toString() {
return "LatestGradeFragment";
}
}`
and here's my LatestGradeAdapter:
public class LatestGradeAdapter extends RecyclerView.Adapter<LatestGradeAdapter.RecyclerViewHolder> {
private Context mCtx;
private List<ListGradeData> sectionList;
`public LatestGradeAdapter(Context mCtx, List<ListGradeData> sectionList) {
this.mCtx = mCtx;
this.sectionList = sectionList;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.section_data_list, parent, false);
return new LatestGradeAdapter.RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
final ListGradeData sections = sectionList.get(position);
//BIND DATA
holder.textViewSection.setText(sections.getSection());
holder.textViewLevel.setText(sections.getLevel());
holder.textViewSchoolYear.setText(sections.getSchoolyear());
}
#Override
public int getItemCount() {
return sectionList.size();
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
//Variables for list
TextView textViewSection, textViewLevel, textViewSchoolYear;
//Variables for head section
TextView textHeaderSection, textHeaderLevel, textHeaderSchoolYear;
public RecyclerViewHolder(final View itemView) {
super(itemView);
textViewSection = (TextView) itemView.findViewById(R.id.textSection);
textViewLevel = (TextView) itemView.findViewById(R.id.textLevel);
textViewSchoolYear = (TextView) itemView.findViewById(R.id.textYear);
}
}
}`
Add this code in your LatestGradeFragment.class
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int lastVisiblePosition = layoutManager.findLastVisibleItemPosition();
if (lastVisiblePosition == recyclerView.getChildCount()) {
progrssBar.setVisibility(View.VISIBLE);
loadMore(); //This methos is used for load next set of items.
}
}
});
public void loadMore(){
//load next set of items to adapter
adapter.notifyDataSetChanged();
progrssBar.setVisibility(View.GONE);
}
Create your fragment_latest_grade like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/progressBar" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:visibility="gone" />
</RelativeLayout>
Related
I know there is other questions like this with answers but they don't help me...
So I have a Fragment, in this one I use Volley to get a JSON from a Web API. What I want to do is to "refresh" my recycler view with the data I get in my response.
I have tried to add a method in my adapter. But nothing append when I try to change my adapter in my Volley.onresponse() method.
There is my Fragment :
public class TicketsIncidentsFragment extends Fragment implements Response.ErrorListener, Response.Listener<String> {
RequestQueue queue;
StringRequest stringRequest;
ListView listView;
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
String url;
private TicketsIncidentsViewModel ticketsIncidentsViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
ticketsIncidentsViewModel =
ViewModelProviders.of(this).get(TicketsIncidentsViewModel.class);
View root = inflater.inflate(R.layout.fragment_ticketsincidents, container, false);
return root;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
RecyclerView recyclerView = (RecyclerView)getView().findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager= new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
MyAdapterTI myAdapterTI=new MyAdapterTI();
recyclerView.setAdapter(myAdapterTI);
queue = Volley.newRequestQueue(getActivity().getApplicationContext());
url = "http://myip/select/ticketsI";
stringRequest = new StringRequest(GET, url, TicketsIncidentsFragment.this, TicketsIncidentsFragment.this);
queue.add(stringRequest);
}
#Override
public void onErrorResponse(VolleyError error) {
}
#Override
public void onResponse(String response) {
RecyclerView recyclerView = (RecyclerView)getView().findViewById(R.id.recyclerview);
Gson gsonTicketsIncidents = new Gson();
ResponseJson responseJson = new ResponseJson();
responseJson = (ResponseJson) gsonTicketsIncidents.fromJson(response, ResponseJson.class);
List<Object> listTicketsIncidents = responseJson.getResponse();
try {
JSONArray tis = new JSONArray(listTicketsIncidents.toArray());
ArrayList<String> date = new ArrayList<String>();
ArrayList<String> nomUser = new ArrayList<String>();
for (int i = 0 ; i< tis.length(); i++) {
JSONObject ticketIncident = tis.getJSONObject(i);
nomUser.add(ticketIncident.get("NOMUSER").toString());
date.add(ticketIncident.get("DateSAISIE").toString());
}
MyAdapterTI myAdapterTI=new MyAdapterTI();
myAdapterTI.getList(nomUser, date);
recyclerView.setAdapter(myAdapterTI);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
There is my adapter :
public class MyAdapterTI extends RecyclerView.Adapter<MyAdapterTI.MyViewHolder> {
private List<Pair<String, String>> TI;
public void getList(ArrayList<String> nomUser, ArrayList<String> date){
for(int i =0; i<nomUser.size();i++){
TI = Arrays.asList( Pair.create(nomUser.get(i), date.get(i)));
}
}
#NonNull
#Override
public MyAdapterTI.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.list_cell_ti, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyAdapterTI.MyViewHolder holder, int position) {
Pair<String, String> pair = TI.get(position);
holder.display(pair);
}
#Override
public int getItemCount() {
return 0;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
private TextView nomUser;
private TextView date;
private Pair<String, String> currentPair;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
nomUser=(TextView)itemView.findViewById(R.id.nomuser);
date=(TextView)itemView.findViewById(R.id.date);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
}
});
}
public void display(Pair<String, String> pair) {
currentPair=pair;
nomUser.setText(pair.first);
date.setText(pair.second);
}
}
}
And there is the layout :
<androidx.constraintlayout.widget.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">
<ListView
android:id="#+id/listview_TI"
android:layout_width="97dp"
android:layout_height="34dp"
android:layout_marginTop="24dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.917"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="409dp"
android:layout_height="680dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.039" />
</androidx.constraintlayout.widget.ConstraintLayout>
Thank's for you're help
UPDATE :
Now my MyAdapter.getList() looks like this :
public void getList(ArrayList<String> nomUser, ArrayList<String> date){
for(int i =1; i<nomUser.size();i++){
TI.add(Pair.create(nomUser.get(i), date.get(i)));
}
notifyDataSetChanged();
}
But nothing change yet.
Last UPDATE :
The problem has been solved.
It's a ridiculous mistake I've made in my Adapter.
I used to return 0 but the solution is this :
#Override
public int getItemCount() {
return TI.size();
}
just change
#Override
public int getItemCount() {
return 0;
}
to
#Override
public int getItemCount() {
if(TI == null)
return 0;
else
return TI.size;
}
private List<Pair<String, String>> TI = new ArrayList();
public void getList(ArrayList<String> nomUser, ArrayList<String> date){
for(int i =0; i<nomUser.size();i++){
TI.add(Pair.create(nomUser.get(i), date.get(i)));
}
notifyDataSetChanged();
}
layoutManager= new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
MyAdapterTI myAdapterTI=new MyAdapterTI(getActivity().getApplicationContext(),ThisIsYourList);
recyclerView.setAdapter(myAdapterTI);
Don't do this in response
MyAdapterTI myAdapterTI=new MyAdapterTI();
recyclerView.setAdapter(myAdapterTI);
myAdapterTI make this global variable
Only update your list and then
myAdapterTI.notifyDataSetChanged();
Or in your adapter, you can do
this.notifyDataSetChanged(); ////in getList
I am using a Fragment to view a RecyclerView. But I always get this error
E/RecyclerView: No adapter attached; skipping layout
I have created an adapter for my recyclerview but the layout does not display. The php backend is working fine. Can somebody please help. Here are my codes for the fragment and adapter
Tips.java
public class Tips extends Fragment {
Configuration config = new Configuration();
String HttpUrl = config.viewtips_url;
List<TipModel> tipList;
RecyclerView recyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tips, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
tipList = new ArrayList<>();
loadTips();
return view;
}
private void loadTips() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, HttpUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
tipList.add(new TipModel(
jsonObject.getInt("id"),
jsonObject.getString("tip")
));
}
TipAdapter tipAdapter = new TipAdapter(getActivity(), tipList);
recyclerView.setAdapter(tipAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
TipAdapter.java
public class TipAdapter extends RecyclerView.Adapter<TipAdapter.TipViewHolder> {
private Context context;
private List<TipModel> tipList;
public TipAdapter(Context context, List<TipModel> tipList) {
this.context = context;
this.tipList = tipList;
}
#Override
public TipViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.itemlayout, null);
return new TipViewHolder(view);
}
#Override
public void onBindViewHolder(TipViewHolder holder, int position) {
TipModel tipModel = tipList.get(position);
holder.textViewTip.setText(tipModel.getTip());
}
#Override
public int getItemCount() {
return tipList.size();
}
class TipViewHolder extends RecyclerView.ViewHolder {
TextView textViewTip;
public TipViewHolder(View view) {
super(view);
textViewTip = view.findViewById(R.id.textViewTip);
}
}
It happens because RecyclerView is expecting an adapter when dispatching layout on view created, so it is fine if there is no adapter when the view is created, it will just skip the layout part.
If you are worried about the error, then you could set an empty adapter when the view is created:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tips, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
tipList = new ArrayList<>();
recyclerView.setAdapter(new TipAdapter(getActivity(), tipList));
}
Then adjust your code in the response callback:
#Override
public void onResponse(String response) {
// Instead of setting adapter here...
// TipAdapter tipAdapter = new TipAdapter(getActivity(), tipList);
// recyclerView.setAdapter(tipAdapter);
// Just notify the adapter that tipList has changed.
recyclerView.getAdapter().notifyDataSetChanged();
// ...
}
TipList is the Adapter's datastore, it belongs to the Adapter and not to the Fragment
I have edited your code ( don't have access to Android Studio, doing it in Text Editor, please check for syntax errors )
Fragment
public class Tips extends Fragment {
Configuration config = new Configuration();
String HttpUrl = config.viewtips_url;
RecyclerView recyclerView;
TipAdapter tipAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Initialize the Tip Adapter
tipAdapter = new TipAdapter(getActivity());
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tips, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// Assign the Adapter to recyclerView
recyclerView.setAdapter(tipAdapter);
return view;
}
private void loadTips() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, HttpUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
// Create a new TipList
List<TipModel> tipList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
tipList.add(new TipModel(
jsonObject.getInt("id"),
jsonObject.getString("tip")
));
}
tipAdapter.updateWith(tipList)
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
TipAdapter
public class TipAdapter extends RecyclerView.Adapter<TipAdapter.TipViewHolder> {
private Context context;
private List<TipModel> tipList = new ArrayList<>();
public TipAdapter(Context context) {
this.context = context;
}
#Override
public TipViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.itemlayout, null);
return new TipViewHolder(view);
}
#Override
public void onBindViewHolder(TipViewHolder holder, int position) {
TipModel tipModel = tipList.get(position);
holder.textViewTip.setText(tipModel.getTip());
}
#Override
public int getItemCount() {
return tipList.size();
}
class TipViewHolder extends RecyclerView.ViewHolder {
TextView textViewTip;
public TipViewHolder(View view) {
super(view);
textViewTip = view.findViewById(R.id.textViewTip);
}
}
public updateWith(List<TipModel> tipList) {
this.tipList = tipList;
notifyDataSetChanged();
}
This is how I did it, when I had a similar problem while inflating recycler view in fragment. This code worked perfectly for me:
P.S. - This is the patch of code what I used in my application. I am sorry for any inconvenience.
First of all, in the onCreateView() of your Display Fragment:
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
Firebase.setAndroidContext(getActivity());
((Home_Drawer) getActivity())
.setActionBarTitle("Home");
recyclerView = (RecyclerView) root.findViewById(R.id.recycler_view_home_frag);
progressBar = (ProgressBar) root.findViewById(R.id.mainPageProgressBar);
// Log.i("inside", "rv initiated" +mLayoutManager.toString());
// Assign activity this to progress dialog.
progressDialog = new ProgressDialog(getActivity());
// Setting up message in Progress dialog.
progressDialog.setMessage("Loading Images From Firebase.");
// Showing progress dialog.
progressDialog.show();
// The path is already defined in MainActivity.
databaseReference = FirebaseDatabase.getInstance().getReference().child("productDisplay");
Log.i("inside", databaseReference.toString());
return root;
}
Then, we call onStart(). This is because recycler view generally does not inflate, ehile setting the adapter in onCreateView().
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<DisplayItemsModel> item_info =
new FirebaseRecyclerOptions.Builder<DisplayItemsModel>()
.setQuery(databaseReference, DisplayItemsModel.class)
.build();
final FirebaseRecyclerAdapter<DisplayItemsModel, ViewHolder> info_adapter =
new FirebaseRecyclerAdapter<DisplayItemsModel, ViewHolder>(item_info) {
#Override
protected void onBindViewHolder(final ViewHolder holder, final int position, final DisplayItemsModel model) {
mContext = getContext();
final DatabaseReference dref = getRef(position).getRef();
Log.i("dref", dref.toString());
// Adding Add Value Event Listener to databaseReference.
dref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(final DataSnapshot snapshot) {
holder.item_name_single_card.setText(snapshot.child("name").getValue().toString());
holder.price_single_card.setText(snapshot.child("price").getValue().toString());
String image_url = snapshot.child("image").getValue().toString();
Picasso.get().load(image_url).into(holder.thumbnail);
// Continue with your code.
This worked perfectly for me. Hope it solves your problem.
This is my LatestGradeAdapter
public class LatestGradeAdapter extends RecyclerView.Adapter<LatestGradeAdapter.RecyclerViewHolder> {
private Context mCtx;
private List<ListGradeData> sectionList;
public LatestGradeAdapter(Context mCtx, List<ListGradeData> sectionList) {
this.mCtx = mCtx;
this.sectionList = sectionList;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.section_data_list, parent, false);
return new LatestGradeAdapter.RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
final ListGradeData sections = sectionList.get(position);
//BIND DATA
holder.textViewSection.setText(sections.getSection());
holder.textViewLevel.setText(sections.getLevel());
holder.textViewSchoolYear.setText(sections.getSchoolyear());
}
#Override
public int getItemCount() {
return sectionList.size();
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
//Variables for list
TextView textViewSection, textViewLevel, textViewSchoolYear;
//Variables for head section
TextView textHeaderSection, textHeaderLevel, textHeaderSchoolYear;
public RecyclerViewHolder(final View itemView) {
super(itemView);
textViewSection = (TextView) itemView.findViewById(R.id.textSection);
textViewLevel = (TextView) itemView.findViewById(R.id.textLevel);
textViewSchoolYear = (TextView) itemView.findViewById(R.id.textYear);
}
}
}`
This is my LatestGradeFragment
`public class LatestGradeFragment extends Fragment {
List<ListGradeData> sectionList;
RecyclerView recyclerView;
public static LatestGradeFragment newInstance() {
return new LatestGradeFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_latest_grade, container, false);
//RecyclerView+CardView for section
recyclerView = (RecyclerView) rootView.findViewById(R.id.display_recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
sectionList = new ArrayList<>();
loadSection();
return rootView;
}
private void loadSection() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, Constants.USER_GRADE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONArray array = new JSONArray(response);
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject sections = array.getJSONObject(i);
//adding the product to product list
sectionList.add(new ListGradeData(
sections.getInt("id"),
sections.getString("section"),
sections.getString("level"),
sections.getString("schoolyear")
));
}
//creating adapter object and setting it to recyclerview
LatestGradeAdapter adapter = new LatestGradeAdapter(getActivity(), sectionList);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//adding our stringrequest to queue
Volley.newRequestQueue(getActivity().getApplicationContext()).add(stringRequest);
}
#Override
public String toString() {
return "HomeFragment";
}
}`
I tried everything what I've searched for and when I apply it, it doesn't work.
could anyone help me?
private boolean loading = true;
private int pastVisiblesItems, visibleItemCount, totalItemCount;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if(dy > 0) //check for scroll down{
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
loadSection();
}
}
}
}
});
hi guys i have a card view that populate it's data from a json. I parse json with volley and it is successfull .
but in card view there is nothing to show
here is my json
{"photo":[{"id":"4","profile_id":"mahdi","caption":"hello","image_url":"https:\/\/hemispheric-suggest.000webhostapp.com\/img\/img\/birjand.jpg","profile_img_url":"https:\/\/hemispheric-suggest.000webhostapp.com\/prof\/prof\/prof_1.jpg","insert_time":"2017-07-09 11:21:44"}
and my fragment adapter :
private RecyclerView recyclerView;
private RequestQueue mRequestQueue;
ArrayList<Card> list = new ArrayList<>();
String url = "My url";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag,container,false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler);
mRequestQueue = Volley.newRequestQueue(getActivity());
list();
LinearLayoutManager MyLayoutManager = new LinearLayoutManager(getActivity());
MyLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setAdapter(new Adapter(list));
return view;
}
public class Adapter extends RecyclerView.Adapter<Adapter.MyviewHolder>{
// private ArrayList<Card> list;
public Adapter(ArrayList<Card> data) {
list = data;
}
public class MyviewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public ImageView imageView;
public MyviewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textView);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
}
}
#Override
public MyviewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_row,parent,false);
return new MyviewHolder(view);
}
#Override
public void onBindViewHolder(MyviewHolder holder, int position) {
Card card = list.get(position);
holder.textView.setText(card.getName());
Glide.with(getActivity()).load(card.getImg()).into(holder.imageView);
}
#Override
public int getItemCount() {
return list.size();
}
}
public void list() {
JsonObjectRequest object = new JsonObjectRequest(Request.Method.GET, url,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try{
JSONArray array = response.getJSONArray("photo");
for (int i = 0; i <array.length() ; i++) {
JSONObject temp = array.getJSONObject(i);
Card card = new Card();
card.setName(temp.getString("profile_id"));
card.setImg(temp.getString("image_url"));
list.add(card);
}
}catch (Exception ex){
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
mRequestQueue.add(object);
}
}
Volley is asynchronus, so when you call:
recyclerView.setAdapter(new Adapter(list));
just a few milliseconds after you enqueued your request, It's very likely that the list is still empty because Volley hasn't received any response yet. You should set your adapter once you get the response inside the onResponse callback.
please any one explain RecyclerView in fragment using volley to get json data.
Already i refered below link coding Google recyclerview in fragment
this is my first project in android, so i cannot understand that coding.
Please any one help me.
My fragmnet Coding:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View drawer = inflater.inflate(R.layout.fragment_progress, container, false);
orderLists = new ArrayList<>();
getProgressData();
recyclerView = (RecyclerView) drawer.findViewById(R.id.progress);
adapter = new ProgressOrderListAdapter(orderLists, this);
adapter.clearAdaptor();
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
private void getProgressData(){
String mobilecustomertoken = SharedPreferencesManager.readPreferenceString("MobileCustomerToken", "D/N");
JSONObject progressData = new JSONObject();
try{
progressData.put("mobilecustomertoken", mobilecustomertoken);
JsonObjectRequest progressObject = new JsonObjectRequest(1, Common.OrderDetails + "progress", progressData, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject progressResponse) {
Log.d("Responseprogress", progressResponse.toString());
try {
int status = progressResponse.getInt("status");
if(status == 1) {
progressOrderProgress(progressResponse);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.d("Response", "PROGRESS ERROR");
}
});
progressObject.setShouldCache(false);
ServiceBellApp.getInstance().addToRequestQueue(progressObject);
}
catch (JSONException localJSONException){
localJSONException.printStackTrace();
return;
}
}
private void progressOrderProgress(JSONObject progressResponse) throws JSONException {
JSONArray result = progressResponse.getJSONArray("orderdata");
OrderList orderListModule = new OrderList();
for(int i=0; i<result.length(); i++){
JSONObject orderData = result.getJSONObject(i);
orderListModule.setPackage_name(orderData.getString("package_name"));
orderListModule.setOrderdate(orderData.getString("orderdate"));
orderListModule.setServicedate(orderData.getString("servicedate"));
orderListModule.setServicetime(orderData.getString("servicetime"));
orderListModule.setOrderid(orderData.getString("orderid"));
orderListModule.setOrdstatus(orderData.getString("ordstatus"));
orderListModule.setOrderamount(orderData.getInt("orderamount"));
}
orderLists.add(orderListModule);
}
My adapter code:
public class OrderListAdapter extends RecyclerView.Adapter<OrderListAdapter.ViewHolder> {
List<OrderList> List;
private FragmentPending mContext;
public OrderListAdapter(List<OrderList> List, FragmentPending context) {
this.mContext = context;
this.List = List;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_list_view, null);
ViewHolder holder = new ViewHolder(view);
// this is where the each item is inflated.
return holder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
OrderList orderListsPos = List.get(position);
// this is where the data for each item is assigned
holder.textViewPackageName.setText(orderListsPos.getPackage_name());
holder.textOrderdate.setText(orderListsPos.getOrderdate());
holder.textServicedate.setText(orderListsPos.getServicedate());
holder.textServicetime.setText(orderListsPos.getServicetime());
holder.textOrderid.setText(orderListsPos.getOrderid());
holder.textOrderamount.setText("Rs." + orderListsPos.getOrderamount());
holder.textStatus.setText(orderListsPos.getOrdstatus());
}
#Override
public int getItemCount() {
return List.size();
}
public void clearAdaptor() {
List.clear();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewPackageName;
public TextView textServicedate;
public TextView textServicetime;
public TextView textOrderdate;
public TextView textOrderid;
public TextView textOrderamount;
public TextView textStatus;
public ViewHolder(View itemView) {
super(itemView);
textViewPackageName = (TextView) itemView.findViewById(R.id.productName);
textOrderdate = (TextView) itemView.findViewById(R.id.orderdate);
textOrderid = (TextView) itemView.findViewById(R.id.orderno);
textOrderamount = (TextView) itemView.findViewById(R.id.orderprice);
textStatus = (TextView) itemView.findViewById(R.id.orderstatus);
}
}}
First you need four things
1 ) layout that holds the each recycler view layout item
2 ) A view holder for creating each layout
3 ) A Model Class to holds the data
4 ) Recycler Adaptor which deals with the data for the Each Layout item
FIrst create a layout item
for eample lets create a single view with only TextView in it
XML
each_item.xml
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:gravity="start|center_vertical"
android:textColor="#color/white"
android:textSize="18sp" />
and lets now create a view holder
i will post both code for the view holder and RecyclerAdaptor
public class Adaptor extends RecyclerView.Adapter<Adaptor.ViewHolder> {
List<Model> List = Collections.emptyList();
private Context mContext;
private LayoutInflater inflater;
public Adaptor(Context context, List<Model> List) {
inflater = LayoutInflater.from(context);
this.mContext = context;
this.List = List;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.each_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
// this is where the each item is inflated.
return holder;
}
#Override
public void onBindViewHolder(WinnersViewHolder holder, int position) {
Model mModel = List.get(position);
// this is where the data for each item is assigned
holder.nameView.setText("" + mModel.getName());
}
#Override
public int getItemCount() {
return List.size();
}
public void clearAdaptor() {
List.clear();
}
public class ViewHolder extends RecyclerView.ViewHolder {
protected TextView nameView;
public ViewHolder(View itemView) {
super(itemView);
this.nameView = (TextView) itemView.findViewById(R.id.name);
}
}
}
Now the model class
public class Model {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
}
Now the back end is done, Lets implement it on the Fragment
List<Model> List = new ArrayList<>();
private RecyclerView mRecyclerView;
private Adaptor adaptor;
public Fragment() {
// constructor of fragment
// Required empty public constructor
}
in the onCreatView() get the id of recyclerView
View fragmentView = inflater.inflate(R.layout.fragment_layout, container, false);
mRecyclerView = (RecyclerView) fragmentView .findViewById(R.id.recycler_view);
and then pass the data to the Adaptor by creating its object
adaptor = new Adaptor(getContext(), List);
adaptor.clearAdaptor();
mRecyclerView.setAdapter(adaptor);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
You are done now, only thing pending is if you are accessing data form server call notifyDataSetChanged() or adaptor = new Adaptor(getContext(), getList()); where the getList() returns the Model data and do not call adaptor.clearAdaptor() .
hope this helps ..
EDIT
you can two ways infalte the each layout item .. one is above and second is in onCreateViewHolder
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.each_item, null);
Check this link It is really helpful for beginners for understanding concepts from start to mastering the RecyclerView.
https://github.com/codepath/android_guides/wiki/Using-the-RecyclerView
Hope this helps you to understand recycler view concepts.
RecycerView + Fragment + Volley
Fragment Code:
public class DogListFragment extends Fragment{
private RecyclerView rv;
private StaggeredGridLayoutManager llm;
private DogListAdapter adapter;
private ArrayList<DogModel> dogList;
private Context context;
public static DogListFragment getInstance(){
return new DogListFragment();
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
dogList = new ArrayList<>();
adapter = new DogListAdapter(context, dogList, this);
getListFromServer();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_dog_list, parent, false);
rv = view.findViewById(R.id.rv);
llm = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
rv.setLayoutManager(llm);
rv.setAdapter(adapter);
return view;
}
public void getListFromServer(){
String url = "https://dog.ceo/api/breed/hound/images/random/20";
RequestQueue requestQueue = Volley.newRequestQueue(context);
StringRequest request = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("message");
for(int i=0;i<array.length();i++){
String imageUrl = array.getString(i);
dogList.add(new DogModel(imageUrl));
}
adapter.updateDataSet(dogList);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
requestQueue.add(request);
}
}
Full code
Woof Repository
It has the following implementations
Fragment communication via interface
Reusing fragment by
getSupportFragmentManager().findFragmentByTag(TAG)
Which lifecycle method should have API call so that it is called just
once
How to save RecylcerView state in Fragment (Scroll position + content)
Pagination in RecyclerView
Rest Calls (Volley)
Image Rendering (Glide)
JSON Parsing