How to set load next page data from data in Android - android

I want develop android application for one website. I read website posts from json and show its in RecyclerView every 10 posts and when user scrolling on RecyclerView show more 10 post and go to end! in this project i use okHTTP v3 and RecyclerView!
Json link : JSON LINK
I can load first 10 posts. i want when scrolling on RecyclerView show next 10 post, but show me again first 10 post!
MainActivity codes:
public class Main_page extends AppCompatActivity {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private RelativeLayout root;
private ImageView menu_image;
private RecyclerView main_recyclerView;
private MainAdapter2 mAdaper;
private List<MainDataModel> dataModels = new ArrayList<MainDataModel>();
private List<MainDataModel> dataModelsArray;
private Context context;
protected Handler handler;
private RelativeLayout loadLayout;
private LinearLayoutManager mLayoutManager;
private int pageCount = 1;
private String ServerAddress = ServerIP.getIP();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
handler = new Handler();
context = getApplicationContext();
loadLayout = (RelativeLayout) findViewById(R.id.main_empty_layout);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
}
LoadData(pageCount);
mLayoutManager = new LinearLayoutManager(this);
// Menu
root = (RelativeLayout) findViewById(R.id.main_root);
View guillotineMenu = LayoutInflater.from(this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
menu_image = (ImageView) toolbar.findViewById(R.id.toolbar_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), menu_image)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView and setData
main_recyclerView = (RecyclerView) findViewById(R.id.main_recycler);
main_recyclerView.setHasFixedSize(true);
main_recyclerView.setLayoutManager(mLayoutManager);
mAdaper = new MainAdapter2(this, main_recyclerView, dataModels);
main_recyclerView.setAdapter(mAdaper);
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
LoadData(pageCount);
}
});
}
#Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
if (dataModels.size() > 0) {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
mAdaper.setLoaded();
}
mAdaper.add(mainInfoModels);
mAdaper.notifyDataSetChanged();
++pageCount;
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
private void LoadData(int pageNumber) {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this, pageNumber);
}
}
AsyncTask code:
public class MainDataInfo {
private Context mContext;
private String ServerAddress = ServerIP.getIP();
public void getMainDataInfo(Context context, int pageNumber) {
mContext = context;
new getInfo().execute(ServerAddress + "page=" + pageNumber);
}
private class getInfo extends AsyncTask<String, Void, String> {
EventBus bus = EventBus.getDefault();
private String ou_response;
private List<MainDataModel> infoModels;
#Override
protected void onPreExecute() {
CustomProcessDialog.createAndShow(mContext);
infoModels = new ArrayList<>();
}
#Override
protected String doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(ServerAddress + "page=1")
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
Response response;
try {
response = client.newCall(request).execute();
ou_response = response.body().string();
response.body().close();
if (ou_response != null) {
try {
JSONObject postObj = new JSONObject(ou_response);
JSONArray postsArray = postObj.optJSONArray("posts");
infoModels = new ArrayList<>();
for (int i = 0; i <= infoModels.size(); i++) {
JSONObject postObject = (JSONObject) postsArray.get(i);
JSONObject images = postObject.optJSONObject("thumbnail_images");
JSONObject imagesPair = images.optJSONObject("medium");
int id = postObject.getInt("id");
String title = postObject.getString("title");
String content = postObject.getString("content");
String thumbnail = imagesPair.getString("url");
Log.d("Data", "Post id: " + id);
Log.d("Data", "Post title: " + title);
Log.d("Data", "Post title: " + thumbnail);
//Use the title and id as per your requirement
infoModels.add(new MainDataModel(id, title, content, thumbnail));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return ou_response;
}
#Override
protected void onPostExecute(String result) {
CustomProcessDialog.dissmis();
if (result != null) {
bus.post(infoModels);
}
}
}
}
How can show next 10 post when scrolling on RecyclerView instance of show again first 10 post?

I checked your JSON , and when you increase page number there is no result. Please fix it first to show your results in your app.
While this one returning you 10 post
When you set your page number 2 , it is not returning any post, this is why you are seeing everytime first 10 post.
Hope it helps.

You will have to make different pages. One page have data of only 10 blogs. To get information about, Request JSON fro next page when 10th item is shown.
To get item shown info you can use layoutManager.findLastVisbleItem() or lastComletlyVisibleItem().
once requested data is downloaded. There must be method like onRequestComleted() in Volley. notifysetChanged there.

Related

RecyclerView not showing JSON sent from localhost just blank screen

Hi guys I dont have much experience with AsyncTask and this is my first time using RecyclerView besides a couple of tutorials I done to learn about it.
If I use dummy data in EventActivity everything works fine and a list shown on the screen. But when I create an ArrayList of EventItems and pass that to the adapter it's just a blank screen. The JSON from localhost is being parsed and sent to the EventItem class. I have tried several things to get it to work but as my experience with AsyncTask and RecyclerView are limited I end up just crashing the app and getting a null pointer exception.
I think that the RecyclerView is being created before the JSON has been retrieved from localhost and this is what's causing the blank screen or null pointer exception but I'm not 100% sure and dont know how to fix the issue if I am correct.
Any help is appreciated.
EventActivity
public class EventActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event);
fetchEvents();//call EventBackgroundWorker
//ArrayList<EventItem> eventList = new EventItem().getRecyclerList();//causes java null pointer exception
ArrayList<EventItem> eventList = new ArrayList<>();
//Dummie data
// eventList.add(new EventItem (1, "Title1", "Date", "endDate", "Location1", 5, 1111));
// eventList.add(new EventItem (R.drawable.ic_favourite, "Title2", "11/07/2018", "11/07/2018", "Wales", 10, 5));
// eventList.add(new EventItem (R.drawable.ramspeed_custom, "Title3", "11/01/2018", "11/09/2018", "Paris, France", 0, 90));
// eventList.add(new EventItem (R.drawable.ramspeed_custom, "Title4", "12/01/2018", "11/09/2018", "New York", 20, 500));
// eventList.add(new EventItem (R.drawable.ic_favourite, "Title5", "Mon 11/05/2015", "11/09/2018", "London, England", 5, 500));
// eventList.add(new EventItem (R.drawable.biker, "Title6", "Mon 11/05/2018", "20/07/2018", "Swords Dublin", 0, 500));
mRecyclerView = (RecyclerView) findViewById(R.id.event_recycler_view);
mRecyclerView.setHasFixedSize(true);//increase performance of app if recyclerView does not increase in size
mLayoutManager = new LinearLayoutManager(this);
// mAdapter = new EventAdapter(eventList);
mAdapter = new EventAdapter(eventList);//context added for testing //////////////////////////////
// mAdapter = new EventAdapter(new ArrayList<EventItem>(0));
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
// buildRecyclerView();
}
//run background thread
private void fetchEvents(){
// String username = "user";
// String userPassword = "password";
String startConnectionCondition = "event";
//this passes the context
EventBackgroundWorker backgroundWorker = new EventBackgroundWorker(this);
backgroundWorker.execute(startConnectionCondition, null);
}
/* private void buildRecyclerView(){
ArrayList<EventItem> eventList = new EventItem().getRecyclerList();
mRecyclerView = (RecyclerView) findViewById(R.id.event_recycler_view);
mRecyclerView.setHasFixedSize(true);//increase performance of app if recyclerView does not increase in size
mLayoutManager = new LinearLayoutManager(this);
// mAdapter = new EventAdapter(eventList);
mAdapter = new EventAdapter(eventList);//context added for testing
// mAdapter = new EventAdapter(new ArrayList<EventItem>(0));
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
*/
/* public void showEventList(boolean b){
ArrayList<EventItem> eventList = new ArrayList<>();
for(int i =0; i< eventList.size(); i++){
eventList.get(i);
Log.d("tag","eventList from main " + eventList);
}
mAdapter = new EventAdapter(eventList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}*/
}//MainActivity
EventAdapter
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
private ArrayList<EventItem> mEventList;
Context context;
//constructor for EventAdapter
public EventAdapter(ArrayList<EventItem> eventList){
// context =c;
mEventList = eventList;
Log.d("tag","EventAdapter eventlist variable called from constructor " + eventList);
}
public static class EventViewHolder extends RecyclerView.ViewHolder{
public ImageView mPromoImage;
public TextView mTitle;
public TextView mStartDate;
public TextView mEndDate;
public TextView mLocation;
public TextView mFee;
public ImageView mFavourite;
//constructor for EventViewHolder class
public EventViewHolder(View itemView) {
super(itemView);
// mPromoImage = (ImageView) itemView.findViewById(R.id.event_promotional_image);
mTitle = (TextView) itemView.findViewById(R.id.event_title_textView);
mStartDate = (TextView) itemView.findViewById(R.id.event_start_textView);
mEndDate = (TextView) itemView.findViewById(R.id.event_end_textView);
mLocation = (TextView) itemView.findViewById(R.id.event_location_textView);
mFee = (TextView) itemView.findViewById(R.id.event_fee_textView);
// mFavourite = (ImageView) itemView.findViewById(R.id.event_favourite_image);
Log.d("tag", "EventViewHolder being called");
}
}//EventViewHolder class
#Override
public EventViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_event, parent, false);
//create view holder
EventViewHolder viewHolder = new EventViewHolder(v);
return viewHolder;
}
//pass values to inflated XML Views in item_event.xml
#Override
public void onBindViewHolder(EventViewHolder holder, int position) {
EventItem currentEvent = mEventList.get(position);
// holder.mPromoImage.setImageResource(currentEvent.getEventPromoImage());
holder.mTitle.setText(currentEvent.getEventTitle());
holder.mStartDate.setText(currentEvent.getEventStartDate());
holder.mEndDate.setText(currentEvent.getEventEndDate());
holder.mLocation.setText(currentEvent.getEventLocation());
holder.mFee.setText(String.valueOf(currentEvent.getEventFee()));//int value passed
// holder.mFavourite.setImageResource(currentEvent.getEventFavourite());
//Log.d("tag", "position" + position );
Log.d("tag","eventAdapter " + currentEvent.getEventTitle());
}
//how many items there will be
#Override
public int getItemCount() {
return mEventList.size();
}
}
EventItem
public class EventItem {
private int mEventPromoImage;
private int mId;
private String mEventTitle;
private String mEventStartDate;
private String mEventEndDate;
private String mEventLocation;
private int mEventFee;
private int mEventViews;
// public EventItem(){}
public EventItem(int id, String eventTitle, String eventStartDate,
String eventEndDate, String eventLocation, int eventFee, int eventViews){
// mEventPromoImage = eventPromoImage;
mId = id;
mEventTitle = eventTitle;
mEventStartDate = eventStartDate;
mEventEndDate = eventEndDate;
mEventLocation = eventLocation;
mEventFee = eventFee;
mEventViews = eventViews;
Log.d("tag","EVENTITEM title EventItem" + mEventTitle);
// Log.d("tag","EVENTITEM startDate EventItem" + mEventStartDate );
// Log.d("tag","EVENTITEM endDate EventItem" + mEventEndDate );
// Log.d("tag","EVENTITEM address EventItem" + mEventLocation);
// Log.d("tag","EVENTITEM fee EventItem" + mEventFee);
}
public int getEventPromoImage() {
return mEventPromoImage;
}
public void setEventPromoImage(int mEventPromoImage) {
this.mEventPromoImage = mEventPromoImage;
}
public int getEventId() {
return mId;
}
public void setEventId(int mId){
this.mId = mId;
}
public String getEventTitle() {
Log.d("tag","getEventTitle() " + mEventTitle);
return mEventTitle;
}
public void setEventTitle(String mEventTitle) {
this.mEventTitle = mEventTitle;
}
public String getEventStartDate() {
return mEventStartDate;
}
public void setEventStartDate(String mEventStartDate) {
this.mEventStartDate = mEventStartDate;
}
public String getEventEndDate(){
return mEventEndDate;
}
public void setEventEndDate(String mEventEndDate){
this.mEventEndDate = mEventEndDate;
}
public String getEventLocation() {
return mEventLocation;
}
public void setEventLocation(String mEventLocation) {
this.mEventLocation = mEventLocation;
}
public int getEventFee() {
return mEventFee;
}
public void setEventFee(int mEventFee) {
this.mEventFee = mEventFee;
}
public int getEventViews(){
return mEventViews;
}
public void getEventViews(int mEventViews) {
this.mEventViews = mEventViews;
}
public ArrayList<EventItem> getRecyclerList(){
ArrayList event = new ArrayList();
event.add(mEventTitle);
event.add(mEventStartDate);
event.add(mEventEndDate);
event.add(mEventLocation);
event.add(mEventFee);
event.add(mEventViews);
return event;
}
}
EventBackgroundWorker
public class EventBackgroundWorker extends AsyncTask<String, Void, String> {
Context context;
AlertDialog alert;
public static final String REQUEST_URL = "http://10.0.2.2/m/event/";
public EventBackgroundWorker(Context ctxt) {
context = ctxt;
}
//Invoked on UI thread before doInBackground is called
#Override
protected void onPreExecute() {
alert = new AlertDialog.Builder(context).create();
alert.setTitle("Result from server");
}
#Override
protected String doInBackground(String... params) {
String type = params[0];//eventList
//String login_url = "http://10.0.2.2/m/event/";
if(type.equals("event")){
try {
String user_name = params[1];
URL url = new URL(REQUEST_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.connect();//works without this connect Find out why
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("getEvents", "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
//read response
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line;
while((line = bufferedReader.readLine()) != null){
result += line;
}
//parse JSON event Array
// Create an empty ArrayList that we can start adding events to
ArrayList<EventItem> eventArray = new ArrayList<>();
JSONArray baseJsonResponse = new JSONArray(result);
for(int i =0; i < baseJsonResponse.length(); i++){
JSONObject event = baseJsonResponse.getJSONObject(i);
int id = event.getInt("id");
String title = event.getString("title");
String address = event.getString("address");
String startDate = event.getString("startDate");
String endDate = event.getString("endDate");
int fee = event.getInt("fee");
int views = event.getInt("views");
//Send data to eventItem Object
EventItem eventObject = new EventItem(id,title,address,startDate,endDate,fee,views);
eventArray.add(eventObject);
/* Log.d("tag", "JSON id " + id);
Log.d("tag", "JSON title " + title);
Log.d("tag", "JSON address " + address);
Log.d("tag", "JSON startDate " + startDate);
Log.d("tag", "JSON endDate " + endDate);
Log.d("tag", "JSON fee " + fee);
Log.d("tag", "JSON views " + views);*/
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (MalformedURLException e) {//added for URL object
e.printStackTrace();
} catch (IOException e) {
//HTPURLConnection
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
//results from doInBackground are passed here
#Override
protected void onPostExecute(String result) {
Log.d("tag", "onPostExecute called" + result);
alert.setMessage(result);
alert.show();
}
}
The AsyncTask creates eventArray but does nothing with it. doInBackground() should return the eventArray and onPostExecute() should set it as adapter content (by a Callback or by setting the Adapter instance at the AsyncTask object). Your Adapter should have a setter for the content which should call notifyDataSetChanged().

android recyclerview load more item upon scrolling using volley

Please help me out to load more data from the server upon scrolling my RecyclerView . Here I have successfully created RecyclerView by loading data from my Mysql server by using volley string request.
Here is my code.
private void populateRecycleView() {
if (Utility.checkNetworkConnection(this)) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Searching...");
progressDialog.setMessage("Searching for the blood donor. Please wait a moment.");
progressDialog.setCancelable(false);
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.POST, Constants.GET_DONORS_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONArray jsonArray = new JSONArray(response);
int count = 0;
while (count < jsonArray.length()) {
JSONObject jsonObject = jsonArray.getJSONObject(count);
String firstName = jsonObject.getString("fName");
String secondName = jsonObject.getString("sName");
String email = jsonObject.getString("emailid");
String password = jsonObject.getString("pass");
String mobile = jsonObject.getString("mobile");
String bloodRt = jsonObject.getString("blood");
String age = jsonObject.getString("age");
String gender = jsonObject.getString("gender");
String country = jsonObject.getString("country");
String location = jsonObject.getString("location");
String latitude = jsonObject.getString("latitude");
String longitude = jsonObject.getString("longitude");
String profilePicFIleName = jsonObject.getString("picname");
String profilePicURL = jsonObject.getString("pic");
Donor donor = new Donor(firstName, secondName, email, password, mobile, bloodRt, age, gender,
country, location, latitude, longitude, profilePicFIleName, profilePicURL);
donorsList.add(donor);
count++;
}
donorsAdapter = new DonorsAdapter(FindDonorResult.this, donorsList);
recyclerView = (RecyclerView) findViewById(R.id.rv_search_result_donor);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(FindDonorResult.this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(donorsAdapter);
donorsAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(FindDonorResult.this, "Active data network is not available.", Toast.LENGTH_LONG).show();
}
}
) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("bloodGroup", bloodGroup);
return params;
}
};
NetworkRequestSingleTon.getOurInstance(this).addToRequestQue(stringRequest);
} else {
Utility.checkNetworkConnectionFound(this);
}
}
And this is my RecyclerView adapter...
public class DonorsAdapter extends RecyclerView.Adapter<DonorsAdapter.CustomViewHolder> {
private Context context;
private ArrayList<Donor> donorList;
private String bloodGroup;
public DonorsAdapter(Context context, ArrayList<Donor> donorList) {
this.context = context;
this.donorList = donorList;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_blood_donors_result,
parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
final Donor donor = donorList.get(position);
String displayName = donor.getFirstName() + " " + donor.getSecondName();
holder.tvDisplayName.setText(displayName);
holder.tvEmailID.setText(donor.getEmail());
String userProfileURL = donor.getProfilePicURL();
if (!userProfileURL.equals("")) {
Picasso.with(context).load(userProfileURL).resize(80, 80).centerCrop().
into(holder.ivProfilePic);
} else {
holder.ivProfilePic.setImageResource(R.drawable.ic_person_white_24dp);
}
bloodGroup = donor.getBloodGroup();
if (bloodGroup.equals("A+"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.a_);
else if (bloodGroup.equals("A-"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.a_negative);
else if (bloodGroup.equals("B+"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.b_positive);
else if (bloodGroup.equals("B-"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.b_negative);
else if (bloodGroup.equals("O+"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.o_positive);
else if (bloodGroup.equals("O-"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.o_negative);
else if (bloodGroup.equals("AB+"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.ab_positive);
else if (bloodGroup.equals("AB-"))
holder.ivBloodTypeDisplay.setImageResource(R.drawable.ab_negative);
if(Utility.isNetworkEnabled){
holder.constraintLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, DisplayDonorDetails.class);
intent.putExtra("donor", donor);
context.startActivity(intent);
}
});
}else {
Toast.makeText(context, "Network not available.", Toast.LENGTH_SHORT).show();
}
}
#Override
public int getItemCount() {
if(donorList != null){
return donorList.size();
}else {
return 0;
}
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
ImageView ivProfilePic, ivBloodTypeDisplay, ivArrow;
TextView tvDisplayName;
TextView tvEmailID;
ConstraintLayout constraintLayout;
public CustomViewHolder(View itemView) {
super(itemView);
ivProfilePic = (ImageView) itemView.findViewById(R.id.civ_user_profile_picture);
ivBloodTypeDisplay = (ImageView) itemView.findViewById(R.id.civ_user_blood_type_display);
ivArrow = (ImageView) itemView.findViewById(R.id.civ_arrow);
tvDisplayName = (TextView) itemView.findViewById(R.id.tvUserNameOnRV);
tvEmailID = (TextView) itemView.findViewById(R.id.tvEmailDisplayOnRV);
constraintLayout = (ConstraintLayout) itemView.findViewById(R.id.recycle_view_item_container);
}
}
}
Populate your donorsAdapter only with the 50 first elements of your donorsList, create a function that save the position of the latest element displayed and add other 50 donors to your adapter starting from the latest position saved when you need it.
Hope it helps.
EDIT
First create an emptyList:
List<Donor> subElements = new ArrayList<>();
and pass it to your adapter:
donorsAdapter = new DonorsAdapter(FindDonorResult.this, subElements);
Now you can create a method like this (you can call in onClick event for example):
private int LAST_POSITION = 0;
private int DONORS_NUM_TOSHOW = 50;
public void showMoreDonors(){
if(donarsList.size() > Last_postion+50){
List<Donor> tempList = new ArrayList<Donor>(donorsList.subList(Last_postion,Last_postion+DONORS_NUM_TOSHOW));
for(Donor a : tempList){
subElements.add(a);
}
Last_postion += DONORS_NUM_TOSHOW;
donorsAdapter.notifyDataSetChanged();
}else{
List<Donor> tempList = new ArrayList<Donor>(donorsList.subList(Last_postion,donorsList.size()));
for(Donor a : tempList){
subElements.add(a);
}
donorsAdapter.notifyDataSetChanged();
}
}
Remember to check when donorsList is over.
I didn't test it, but i hope it is usefull to understand the idea.
Finally, I sort this out. I have got an awesome tutorial from this blog.
http://android-pratap.blogspot.in/2015/06/endless-recyclerview-with-progress-bar.html.
I made some changes to populate the list because my data is on a remote server and by using volley library I fetched the data into the list. Remaining things are same.

Getting error:No adapter attached; skipping layout in recyclerview

I tried to fetch the json values from url and shows in listview with adapter in recylerview. but the listview is empty and getting this error 'No adapter attached; skipping layout'. When I tried with the below code its working
for (int i = index; i < end; i++) {
User user = new User();
user.setName("Name " + i);
mUsers.add(user);
}
Here is my part of code, if needed I'll upload complete code
public class OtherNews extends AppCompatActivity {
JSONArray jsonarray;
private RecyclerView mRecyclerView;
private List<User> mUsers = new ArrayList<>();
private UserAdapter mUserAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mUserAdapter = new UserAdapter();
new DownloadJSON().execute();
mUserAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
Log.e("haint", "Load More");
mUsers.add(null);
mUserAdapter.notifyItemInserted(mUsers.size() - 1);
//Load more data for reyclerview
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Log.e("haint", "Load More 2");
//Remove loading item
mUsers.remove(mUsers.size() - 1);
mUserAdapter.notifyItemRemoved(mUsers.size());
//Load data
int index = mUsers.size();
int end = index + 20;
for (int i = index; i < end; i++) {
User user = new User();
user.setName("Name " + i);
user.setEmail("alibaba" + i + "#gmail.com");
mUsers.add(user);
}
mUserAdapter.notifyDataSetChanged();
mUserAdapter.setLoaded();
}
}, 5000);
}
});
}
// DownloadJSON AsyncTask
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
private static final String TAG = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// Create an array
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall("http://xxxxxxxxx.in/projects/falcon/getallnews.php?page=2");
if (jsonStr != null) {
try {
JSONObject jsonobject = new JSONObject(jsonStr);
jsonarray = jsonobject.getJSONArray("news");
// Getting JSON Array node
for (int i = 0; i < jsonarray.length(); i++) {
User user = new User();
String title = jsonobject.getString("title");
user.setName(title);
mUsers.add(user);
}
} catch (final JSONException e) {
}
} else {
Log.d(TAG, "someOther)");
}
return null;
}
#Override
protected void onPostExecute(Void args) {
mRecyclerView.setAdapter(mUserAdapter);
}
}
I get the value in this line of code, but couldn't set in list view.
String title = jsonobject.getString("title");
user.setName(title);
The issue is exactly like it sounds, an adapter is not being attached when it needs it. You don't attach it until onPostExecute. Just attach it right from the beginning:
mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mUserAdapter = new UserAdapter();
mRecyclerView.setAdapter(mUserAdapter);
As you modify the adapter in other parts of the code, your RecyclerView will update automatically, so long as you call notifyDataSetChanged() or some related method.

Show error when load more data in RecyclerView on Android

I want develop android application for one website. I read website posts from json and show its in RecyclerView every 10 posts and when user scrolling on RecyclerView show more 10 post and go to end! in this project i use okHTTP v3, Glide and RecyclerView!
Json link : JSON LINK
I can load first 10 posts, but when scrolling on RecyclerView and show other 10 posts, show me this error :
04-27 15:34:33.599 3249-3249/com.tellfa.colony E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tellfa.colony, PID: 3249
java.lang.IndexOutOfBoundsException: Invalid index 11, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.tellfa.colony.Activities.Main_page$1$1.run(Main_page.java:95)
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:5349)
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:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
MainActivity codes:
public class Main_page extends AppCompatActivity {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private RelativeLayout root;
private ImageView menu_image;
private RecyclerView main_recyclerView;
private MainAdapter2 mAdaper;
private List<MainDataModel> dataModels = new ArrayList<MainDataModel>();
private List<MainDataModel> dataModelsArray;
private Context context;
protected Handler handler;
private RelativeLayout loadLayout;
private LinearLayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
handler = new Handler();
context = getApplicationContext();
loadLayout = (RelativeLayout) findViewById(R.id.main_empty_layout);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
}
LoadData();
mLayoutManager = new LinearLayoutManager(this);
// Menu
root = (RelativeLayout) findViewById(R.id.main_root);
View guillotineMenu = LayoutInflater.from(this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
menu_image = (ImageView) toolbar.findViewById(R.id.toolbar_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), menu_image)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView and setData
main_recyclerView = (RecyclerView) findViewById(R.id.main_recycler);
main_recyclerView.setHasFixedSize(true);
main_recyclerView.setLayoutManager(mLayoutManager);
mAdaper = new MainAdapter2(this, main_recyclerView, dataModels);
main_recyclerView.setAdapter(mAdaper);
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
dataModelsArray = new ArrayList<MainDataModel>();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
int start = dataModels.size();
int end = start + 10;
for (int i = start + 1; i <= end; i++) {
dataModels.add(new MainDataModel(dataModelsArray.get(i).getId(),
dataModelsArray.get(i).getTitle(),
dataModelsArray.get(i).getContent(),
dataModelsArray.get(i).getThumbnail()));
mAdaper.notifyItemInserted(dataModels.size());
}
mAdaper.setLoaded();
}
}, 1000);
}
});
}
#Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
mAdaper.add(mainInfoModels);
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
private void LoadData() {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this);
}
}
AsyncTask codes:
public class MainDataInfo {
private Context mContext;
private String ServerAddress = ServerIP.getIP();
public void getMainDataInfo(Context context) {
mContext = context;
new getInfo().execute(ServerAddress + "page=1");
}
private class getInfo extends AsyncTask<String, Void, String> {
EventBus bus = EventBus.getDefault();
private String ou_response;
private List<MainDataModel> infoModels;
#Override
protected void onPreExecute() {
CustomProcessDialog.createAndShow(mContext);
infoModels = new ArrayList<>();
}
#Override
protected String doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(ServerAddress + "page=1")
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
Response response;
try {
response = client.newCall(request).execute();
ou_response = response.body().string();
response.body().close();
if (ou_response != null) {
try {
JSONObject postObj = new JSONObject(ou_response);
JSONArray postsArray = postObj.optJSONArray("posts");
infoModels = new ArrayList<>();
for (int i = 0; i <= infoModels.size(); i++) {
JSONObject postObject = (JSONObject) postsArray.get(i);
JSONObject images=postObject.optJSONObject("thumbnail_images");
JSONObject imagesPair=images.optJSONObject("medium");
int id = postObject.getInt("id");
String title = postObject.getString("title");
String content = postObject.getString("content");
String thumbnail = imagesPair.getString("url");
Log.d("Data", "Post id: " + id);
Log.d("Data", "Post title: " + title);
Log.d("Data", "Post title: " + thumbnail);
//Use the title and id as per your requirement
infoModels.add(new MainDataModel(id, title, content, thumbnail));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return ou_response;
}
#Override
protected void onPostExecute(String result) {
CustomProcessDialog.dissmis();
if (result != null) {
bus.post(infoModels);
}
}
}
}
for load more data i use Interface class : OnLoadMoreListener
Attention : Please don't give me negative points, help me and i really need you helps! thanks all <3 How can i fix it?
Change this code
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
dataModelsArray = new ArrayList<MainDataModel>();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
int start = dataModels.size();
int end = start + 10;
for (int i = start + 1; i <= end; i++) {
dataModels.add(new MainDataModel(dataModelsArray.get(i).getId(),
dataModelsArray.get(i).getTitle(),
dataModelsArray.get(i).getContent(),
dataModelsArray.get(i).getThumbnail()));
mAdaper.notifyItemInserted(dataModels.size());
}
mAdaper.setLoaded();
}
}, 1000);
}
});
to
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
LoadData(pageNumber);
}
});
and change this method:
#Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
mAdaper.add(mainInfoModels);
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
to:
int pageNumber = 1;
#Subscribe
public void onEvent(List mainInfoModels) {
if(dataModels.size()>0){
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
mAdaper.setLoaded();
}
mAdaper.add(mainInfoModels);
mAdapter.notifyDataSetChanged();
pageNumber++;
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
It is just overview as I understand: you are not doing anything with the dataModelsArray.
Check this out hope this helps. As you did not provided all the code
EDIT:
for your Second answer you are saying 10 post are repeatedly showing because you are not passing the page number:
Change this method:
public void getMainDataInfo(Context context) {
mContext = context;
new getInfo().execute(ServerAddress + "page=1");
}
to:
public void getMainDataInfo(Context context, int pageNumber) {
mContext = context;
new getInfo().execute(ServerAddress + "page="+pageNumber);
}
change this method to:
private void LoadData() {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this);
}
to
private void LoadData(int pageNumber) {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this, pageNumber);
}
Change LoadData() to LoadData(pageNumber)
make an integer in your activity class, increment it when you get response and pass incremented pageNumber to this method.
Thank hope it solve you issue. Accept it as answer as others can get idea.
Try This code :
And Delete Don't use your MainDataInfo class. I have implemented that in Main_Page.java itself.
Your Main_Page.java:
public class Main_page extends AppCompatActivity {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private RelativeLayout root;
private ImageView menu_image;
private RecyclerView main_recyclerView;
private MainAdapter2 mAdaper;
private List<MainDataModel> dataModels = new ArrayList<MainDataModel>();
protected Handler handler;
private RelativeLayout loadLayout;
private LinearLayoutManager mLayoutManager;
private int pageCount = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
handler = new Handler();
loadLayout = (RelativeLayout) findViewById(R.id.main_empty_layout);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
}
LoadData(pageCount);
mLayoutManager = new LinearLayoutManager(Main_page.this);
// Menu
root = (RelativeLayout) findViewById(R.id.main_root);
View guillotineMenu = LayoutInflater.from(Main_page.this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
menu_image = (ImageView) toolbar.findViewById(R.id.toolbar_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), menu_image)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView and setData
main_recyclerView = (RecyclerView) findViewById(R.id.main_recycler);
main_recyclerView.setHasFixedSize(true);
main_recyclerView.setLayoutManager(mLayoutManager);
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
LoadData(++pageCount);
}
}, 1000);
}
});
}
/*
#Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
mAdaper.add(mainInfoModels);
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}*/
private void LoadData(int pageNumber) {
new APIInfoAsyncTask().execute(ServerAddress + "page=" + pageNumber);
}
private class APIInfoAsyncTask extends AsyncTask<String, Void, List<MainDataModel>> {
private String ou_response;
#Override
protected void onPreExecute() {
CustomProcessDialog.createAndShow(Main_page.this);
}
#Override
protected List<MainDataModel> doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
List<MainDataModel> responseData = new ArrayList<>();
Request request = new Request.Builder()
.url(ServerAddress + "page=1")
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
Response response;
try {
response = client.newCall(request).execute();
ou_response = response.body().string();
response.body().close();
if (ou_response != null) {
try {
JSONObject postObj = new JSONObject(ou_response);
JSONArray postsArray = postObj.optJSONArray("posts");
infoModels = new ArrayList<>();
for (int i = 0; i <= infoModels.size(); i++) {
JSONObject postObject = (JSONObject) postsArray.get(i);
JSONObject images = postObject.optJSONObject("thumbnail_images");
JSONObject imagesPair = images.optJSONObject("medium");
int id = postObject.getInt("id");
String title = postObject.getString("title");
String content = postObject.getString("content");
String thumbnail = imagesPair.getString("url");
Log.d("Data", "Post id: " + id);
Log.d("Data", "Post title: " + title);
Log.d("Data", "Post title: " + thumbnail);
//Use the title and id as per your requirement
responseData.add(new MainDataModel(id, title, content, thumbnail));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return responseData;
}
#Override
protected void onPostExecute(List<MainDataModel> result) {
CustomProcessDialog.dissmis();
dataModels.addAll(result);
mAdaper = new MainAdapter2(Main_page.this, main_recyclerView, dataModels);
main_recyclerView.setAdapter(mAdaper);
}
}
}
Use your adapter class without any edit,And dont use EventBus.

How to load GridView images with AsyncTask?

I have, below the following fragment that populates a gridview with Bitmaps from URLs. The problem is that I know it's very 'heavy' work and done on the UI Thread so it's slowing the fragment down when loading the grid.
I've read that an AsyncTask is needed to carry out the 'heavy' work in the background but I can't find anything that seems to fit with what I want.
public class HomeFragment extends Fragment {
protected static final String TAG = null;
public HomeFragment(){}
GridView gridView;
private GridViewAdapter gridAdapter;
private SQLiteHandler db;
private SwipeRefreshLayout swipeLayout;
private ProgressDialog pDialog;
GPSTracker gps;
String uid;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
db = new SQLiteHandler(getActivity());
gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_item_layout, getData());
pDialog = new ProgressDialog(getActivity());
pDialog.setCancelable(true);
uid="1";
String email = db.getFromTable(getActivity(), "email", SQLiteHandler.TABLE_LOGIN, "WHERE _id="+uid);
String from_age = db.getFromTable(getActivity(), "from_age", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String to_age = db.getFromTable(getActivity(), "to_age", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String distance = db.getFromTable(getActivity(), "distance", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String unit = db.getFromTable(getActivity(), "unit", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String men = db.getFromTable(getActivity(), "men", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
String women = db.getFromTable(getActivity(), "women", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid);
fetchUsers(email, from_age, to_age, distance, unit, men, women);
final View rootView = inflater.inflate(R.layout.fragment_home, container, false);
//getActivity().getActionBar().setTitle(R.string.home);
gridView = (GridView) rootView.findViewById(R.id.gridView);
gridView.setAdapter(gridAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageItem item = (ImageItem) parent.getItemAtPosition(position);
ImageView imageView = (ImageView) v.findViewById(R.id.image);
//Create intent
Intent intent = new Intent(getActivity(), DetailsActivity.class);
int[] screenLocation = new int[2];
imageView.getLocationOnScreen(screenLocation);
intent.putExtra("left", screenLocation[0]).
putExtra("top", screenLocation[1]).
putExtra("width", imageView.getWidth()).
putExtra("height", imageView.getHeight()).
putExtra("uid", item.getUid());
startActivity(intent);
}
});
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
//my update process
Fragment currentFragment = getFragmentManager().findFragmentByTag("0");
FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
fragTransaction.detach(currentFragment);
fragTransaction.attach(currentFragment);
fragTransaction.commit();
}
});
return rootView;
}
// Prepare some dummy data for gridview
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
Cursor cursor = db.getAllRows("*", SQLiteHandler.TABLE_USERS, "");
//Query local DB to initialize settings screen
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
String uid = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_UID));
String name = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_NAME));
String dob = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_DOB));
//String gender = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_GENDER));
String photourl = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_PHOTOURL));
//String distance = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_DISTANCE));
String[] birthdayArr = dob.split("-");
int age = getAge(Integer.parseInt(birthdayArr[0]), Integer.parseInt(birthdayArr[1]), Integer.parseInt(birthdayArr[2]));
Bitmap bitmap = getBitmapFromURL(photourl);
imageItems.add(new ImageItem(bitmap, name+" - " + age, uid));
}
return imageItems;
}
public static Bitmap getBitmapFromURL(String src) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
// Log exception
return null;
}
}
public int getAge(int year, int month, int day) {
//int nowMonth = now.getMonth()+1;
int nowMonth = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
//int nowYear = now.getYear()+1900;
int nowYear = Calendar.getInstance().get(Calendar.YEAR);
int result = nowYear - year;
if (month > nowMonth) {
result--;
}
else if (month == nowMonth) {
int nowDay = Calendar.getInstance().get(Calendar.DATE);
if (day > nowDay) {
result--;
}
}
return result;
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
Log.i("hideDialog", "called");
if (pDialog.isShowing())
pDialog.dismiss();
}
public void fetchUsers(final String email, final String agefrom, final String ageto, final String distance, final String distanceUnit, final String interested_men, final String interested_wmen){
// Tag used to cancel the request
gps = new GPSTracker(getActivity());
String tag_string_req = "req_login";
pDialog.setMessage("Finding users ...");
showDialog();
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_LOGIN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Fetch Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
int success = jObj.getInt("success");
JSONArray users = jObj.getJSONArray("users");
// Check for error node in json
if (success == 1) {
//Log.i("success", users+"");
if (users.length() == 0) {
Toast.makeText(getActivity(), "No users found! \nPlease try again soon.", Toast.LENGTH_LONG).show();
db.emptyTable(SQLiteHandler.TABLE_USERS);
}else{
db.emptyTable(SQLiteHandler.TABLE_USERS);
for (int i = 0; i < users.length(); i++) {
JSONObject user = users.getJSONObject(i);
String uid = user.getString("uid");
String name = user.getString("name");
String dob = user.getString("dob");
String gender = user.getString("gender");
String photourl = user.getString("photoUrl");
String distance = user.getString("distance");
String[][] userValues = {
{ SQLiteHandler.KEY_UID, uid},
{ SQLiteHandler.KEY_NAME, name},
{ SQLiteHandler.KEY_DOB, dob},
{ SQLiteHandler.KEY_GENDER, gender},
{ SQLiteHandler.KEY_PHOTOURL, photourl},
{ SQLiteHandler.KEY_DISTANCE, distance}
};
db.insert(SQLiteHandler.TABLE_USERS, userValues);
}
}
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getActivity(),errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getActivity(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
//$lat, $lng, $email, $agefrom, $ageto, $distance, $distanceUnit, $interested_men, $interested_wmen
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "login");
params.put("lat", gps.getLatitude()+"");
params.put("lng", gps.getLongitude()+"");
params.put("email", email);
params.put("agefrom", agefrom);
params.put("ageto", ageto);
params.put("distance", distance);
params.put("distanceUnit", distanceUnit);
params.put("interested_men", interested_men+"");
params.put("interested_wmen", interested_wmen+"");
params.put("fetch", "y");
Log.i(TAG, params+"");
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
}
How to load GridView images with AsyncTask?
Downloading images as Bitmap in HomeFragment. Use NetworkImageView from Volley in layout of GridView item for loading images in GridView.
Instead of storing Bitmap, store image url in ImageItem.
See following tutorial for more help:
Using NetworkImageView
AsynTask class
public class GridDataAsyncTask extends AsyncTask<GridDataAsyncTask.GridCallback, Void, GridAdapter> {
public interface GridCallback {
void onAdapterReady(GridAdapter adapter);
}
private GridCallback mCallBack;
#Override
protected GridAdapter doInBackground(GridCallback... callbacks) {
mCallBack = callbacks[0];
// TODO get data and create grid adapter
return adapter;
}
#Override
protected void onPostExecute(GridAdapter gridAdapter) {
super.onPostExecute(gridAdapter);
mCallBack.onAdapterReady(gridAdapter);
}
}
Activity
public class GridActivity extends AppCompatActivity implements GridDataAsyncTask.GridCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new GridDataAsyncTask().execute(this);
}
#Override
public void onAdapterReady(GridAdapter adapter) {
// TODO set adapte to GridView
}
}
Best you can do is use http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html and make a lru cache and place the images in lru cache.
Example is given in android tutorials
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
As suggested by fractalwrench and Budius, Picasso was a very good and VERY easy solution to this. All I had to do was to pass the photo url instead of the entire BitMap through to my GridView adapter and use Picasso.with(context).load(item.getImage()).into(holder.image); to create the BitMap for the image view. This was so easy to implement and gives me exactly what I need. Thaks

Categories

Resources