I need to add my Items one by one to my RcyclerView for example add first item to recyclerView and show then add another item....
I have a volley that connect to a service then get me some data, in this volley I call a method :
private void makeJsonArryReq(String uri) {
userPointList = new ArrayList<>();
orginal = new ArrayList<>();
final JsonArrayRequest req = new JsonArrayRequest(uri,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
orginal = MarketingPoints_JSONParser.FeedOriginal(response.toString(), mUser_Code, ReportActivity.this);
userPointList = MarketingPoints_JSONParser.parseFeed(response.toString(), mUser_Code, ReportActivity.this);
FillList();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Custom Log Error", "Error: " + error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(req, tag_json_arry);
}
when I call this method FillList(); it fill and show first item on RecyclerView,How can I listen to adapter for finalized and call FillList(); again for next item .
My FillList():
public void FillList() {
Geocoder geocoder = new Geocoder(activity, Locale.getDefault());
List<Address> addresses;
StepModel stp = null;
List<StepModel> Step = new ArrayList<>();
if (check < userPointList.size()) {
try {
addresses = geocoder.getFromLocation(userPointList.get(check).getLat(), userPointList.get(check).getLng(), 1);
stp = new StepModel();
stp.setsCity(addresses.get(0).getAdminArea());
stp.setsStreet(addresses.get(0).getThoroughfare());
stp.setSlat(userPointList.get(check).getLat());
stp.setSlng(userPointList.get(check).getLng());
stp.setSdate(userPointList.get(check).getDate());
stp.setStime(userPointList.get(check).getTime());
stp.setsCounts(userPointList.get(check).getCounts());
stp.setSprofilePhoto(userPointList.get(check).getProfilePhoto());
stp.setsUserCode(userPointList.get(check).getUserCode());
Step.add(stp);
} catch (IOException e) {
e.printStackTrace();
}
pointAdapter = new PointsList_Adapter(Step, ReportActivity.this,this, city, street);
Points_Recycler.setAdapter(pointAdapter);
pointAdapter.notifyDataSetChanged();
check++;
}else {
return;
}
}
Explain :
I connect to a service then I get a json then I convert it and store in a List.In my json I have two specific data (Lat and lng) that I should get name country and name street(For example 100 lat lng) then show on recyclerView but it get long time because I should fill recyclerView on by one.
My adapter :
public class PointsList_Adapter extends RecyclerView.Adapter<PointsList_Adapter.ViewHolder> {
int count = 0;
private List<StepModel> mpList;
public static Activity activity;
public static boolean flagItem = true;
public static boolean flagToast = true;
private mstep Mstep;
public PointsList_Adapter(List<StepModel> userCodeList, Activity activity) {
this.mpList = userCodeList;
this.activity = activity;
}
#Override
public PointsList_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.listpoints_cardview, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(PointsList_Adapter.ViewHolder viewHolder, final int position) {
String dateValue = mpList.get(position).getDate();
final String countValue = String.valueOf(mpList.get(position).getCounts());
final Double lat = mpList.get(position).getLat();
final Double lng = mpList.get(position).getLng();
final String userCode = mpList.get(position).getUserCode();
final String time = mpList.get(position).getTime();
final int counts = mpList.get(position).getCounts();
final String city = mpList.get(position).getCity();
final String street = mpList.get(position).getStreet();
viewHolder.txtDate.setText(dateValue);
viewHolder.txtPoints.setText(lat + " , " + lng);
viewHolder.txtTime.setText(time);
viewHolder.txtAddress.setText(city + " , " + street);
viewHolder.txtCount.setText(countValue);
}
#Override
public int getItemCount() {
return mpList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtDate, txtPoints, txtTime, txtAddress, txtCount;
public LinearLayout lLstPoints;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtDate = (TextView) itemLayoutView.findViewById(R.id.txtDate);
txtPoints = (TextView) itemLayoutView.findViewById(R.id.txtPoints);
txtTime = (TextView) itemLayoutView.findViewById(R.id.txtTime);
txtAddress = (TextView) itemLayoutView.findViewById(R.id.txtAddress);
txtCount = (TextView) itemLayoutView.findViewById(R.id.txtCount);
lLstPoints = (LinearLayout) itemLayoutView.findViewById(R.id.lLstPoints);
}
}
}
Please add below method in your adapter:
public reloadList(ArrayList<String> mpList) {
this.mpList.addAll(mpList);
}
When you want to update list or want to add one more item in your listview, use below code:
public void FillList() {
Geocoder geocoder = new Geocoder(activity, Locale.getDefault());
List<Address> addresses;
StepModel stp = null;
List<StepModel> Step = new ArrayList<>();
if (check < userPointList.size()) {
try {
addresses = geocoder.getFromLocation(userPointList.get(check).getLat(), userPointList.get(check).getLng(), 1);
stp = new StepModel();
stp.setsCity(addresses.get(0).getAdminArea());
stp.setsStreet(addresses.get(0).getThoroughfare());
stp.setSlat(userPointList.get(check).getLat());
stp.setSlng(userPointList.get(check).getLng());
stp.setSdate(userPointList.get(check).getDate());
stp.setStime(userPointList.get(check).getTime());
stp.setsCounts(userPointList.get(check).getCounts());
stp.setSprofilePhoto(userPointList.get(check).getProfilePhoto());
stp.setsUserCode(userPointList.get(check).getUserCode());
Step.add(stp);
} catch (IOException e) {
e.printStackTrace();
}
// Just update your list and call notifyDataSetChanged()
pointAdapter .reloadList(Step);
pointAdapter .notifyDataSetChanged();
check++;
}else {
return;
}
}
Initialize your adapter as below:
ArrayList<StepModel> userCodeList = new ArrayList<StepModel>();
pointAdapter = new PointsList_Adapter(userCodeList , activity) ;
Thank You.
After retrieving all data from server at once, inside Filllist() method you should use for, while or do..while loops to iterate your code.You have used if conditional loop that will run only once.
Else, you can create a method inside adapter to add item to your list and then call notifydatasetchanged() method there.
public void add(Object obj){
mArraylist.add(obj);
notifyDataSetChanged();
}
Related
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().
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.
I am creating an application with a list that list cards based on the value from the server.
I created a StudentCardArrayAdapter to achieve this and everything works fine. All the data has been populated in card list. also I able to get the values on button click in each card separately.
What I need is on clicking the button it will call a method requestion server for data asynchronously and get a value from the server and according to that value, i need to change the button text in that particular card.
My StudentCardArrayAdapter code:
public class StudentCardArrayAdapter extends ArrayAdapter<StudentCard> {
private static final String TAG = "CardArrayAdapter";
private List<StudentCard> cardList = new ArrayList<StudentCard>();
private Context mContext;
String selected = "0";
PreferenceHelper prefs;
CardViewHolder viewHolder;
View row;
ProgressDialog pd;
static class CardViewHolder {
TextView studentname;
TextView stop;
Button selectbutton;
CircleImageView imageId;
}
public StudentCardArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.mContext = context;
prefs = new PreferenceHelper(this.mContext);
pd = new ProgressDialog(this.mContext);
}
#Override
public void add(StudentCard object) {
cardList.add(object);
super.add(object);
}
#Override
public int getCount() {
return this.cardList.size();
}
#Override
public StudentCard getItem(int index) {
return this.cardList.get(index);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.student_card, parent, false);
viewHolder = new CardViewHolder();
viewHolder.studentname = (TextView) row.findViewById(R.id.studentname);
viewHolder.stop = (TextView) row.findViewById(R.id.stop);
viewHolder.selectbutton = (Button) row.findViewById(R.id.selectbutton);
viewHolder.imageId = (CircleImageView) row.findViewById(R.id.imageId);
row.setTag(viewHolder);
} else {
viewHolder = (CardViewHolder)row.getTag();
}
StudentCard card = getItem(position);
viewHolder.studentname.setText(card.getStudName());
viewHolder.studentname.setTextColor(Color.parseColor("#000000"));
viewHolder.stop.setText(card.getStudStop());
viewHolder.stop.setTextColor(Color.parseColor("#000000"));
if(card.getSelected().equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
else{
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.select));
viewHolder.selectbutton.setEnabled(true);
}
final String studid = card.getStudId();
final String busname = prefs.getString("busname", "0");
final String schoolid = prefs.getString("schoolid", "");
viewHolder.selectbutton.setOnClickListener(new View.OnClickListener()
{
String updatedvalue = "0";
#Override
public void onClick(View v)
{
Log.e("studid",studid);
Log.e("busname",busname);
Log.e("schoolid",schoolid);
selectstudent(v, studid, busname, schoolid,mContext);
//Toast.makeText(v.getContext(), amountinfo, Toast.LENGTH_SHORT).show();
/*SnackbarManager.show(Snackbar.with(this) // context
.text(amountinfo));*/
}
});
Picasso.with(mContext).load(card.getImageUrl()).fit().error(R.mipmap.ic_launcher).into(viewHolder.imageId);
return row;
}
public void selectstudent(final View v, String studid, String busname, String schoolid, final Context mContext) {
String returnedselected = "0";
Log.e("BASE_URL_STUDENT_UPDATE", Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid);
RestClientHelper.getInstance().get(Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid, new RestClientHelper.RestClientListener() {
#Override
public void onSuccess(String response) {
Log.e("RESULT", response);
try {
JSONObject result = new JSONObject(response);
JSONArray posts = result.optJSONArray("status");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
String status = post.optString("status");
if (status.equals("true")) {
selected = post.optString("selected");
} else {
selected = post.optString("selected");
String error = post.optString("error");
SnackbarManager.show(Snackbar.with(getContext()) // context
.text(error));
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
} finally {
if(selected.equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
}
}
#Override
public void onError(String error) {
Log.e("error", error);
selected = "0";
}
});
}
}
I used the below code but nothing works.. No error also.. and not change in button text.I get value of selected as 1 from server.
if(selected.equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
I am new to android.. and is stuck here. Please help me out.
FINALLY IT WORKED
As changes mention by Krish, I updated the code suggested by him.
And added this changes in onClick it worked
if(card.getSelected().equals("1")){
viewHolder.selectbutton.setText(mContext.getResources().getString(R.string.selected));
viewHolder.selectbutton.setEnabled(false);
}
Change the code like this,
public void selectstudent(StudentCard card, String studid, String busname, String schoolid, final Context mContext) {
String returnedselected = "0";
Log.e("BASE_URL_STUDENT_UPDATE", Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid);
RestClientHelper.getInstance().get(Constants.BASE_URL_STUDENT_UPDATE + "?studid=" + studid+"&busname="+busname+"&schoolid="+schoolid, new RestClientHelper.RestClientListener() {
#Override
public void onSuccess(String response) {
Log.e("RESULT", response);
try {
JSONObject result = new JSONObject(response);
JSONArray posts = result.optJSONArray("status");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
String status = post.optString("status");
if (status.equals("true")) {
selected = post.optString("selected");
} else {
selected = post.optString("selected");
String error = post.optString("error");
SnackbarManager.show(Snackbar.with(getContext()) // context
.text(error));
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
} finally {
if(selected.equals("1")){
card.setSelected("1");
notifyDataSetChanged();
}
}
}
#Override
public void onError(String error) {
Log.e("error", error);
selected = "0";
}
});
}
and change this line like this ,
final StudentCard card = getItem(position);
and call method inside onclick.
selectstudent(card, studid, busname, schoolid,mContext);
I'm implementing an endless data loading for a RecyclerView. When software detects that last item is going to be shown, it downloads new items and call to the loadMoreData() function but new dataset is not showing.
When I called notifyDataSetChanged() so nothing to be happened.
I have only one solution that is refresh the view is to set again the adapter but problem is that the recyclerview returns to the first position then again recyclerview scrolled up from the first position to last position.
RecyclerViewActivity.java
RecyclerView rv;
DatabaseHelpr databaseHelpr;
RVAdapter adapter;
LocationFinder locationfinder;
Location currentLocation;
ArrayList<ServiceModel> childList, list;
private int MainService_ID, city_id;
String url2;
ActionBar actionBar;
JSONArray items = null;
Utility utility;
Double lat, longi;
LinearLayoutManager llm;
int counter=0;
ProgressBar progressBar;
private static final String TAG_ITEMS = "items";
private static final String TAG_LOCALITY = "Locality";
private static final String TAG_BUSINESS_ID = "Business_Id";
private static final String TAG_LONGITUDE = "Longitude";
private static final String TAG_BUSINESS_NAME = "Business_Name";
private static final String TAG_LATITUDE = "Latitude";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recyclerview_activity);
list = new ArrayList<>();
utility = new Utility(this);
llm = new LinearLayoutManager(this);
Bundle bundle=getIntent().getExtras();
MainService_ID=bundle.getInt("service_id");
String mainService_Name = bundle.getString("service_name");
city_id = bundle.getInt("city_id");
lat= bundle.getDouble("lat");
longi=bundle.getDouble("longi");
rv=(RecyclerView)findViewById(R.id.rv);
rv.setLayoutManager(llm);
actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(mainService_Name);
//Here city_id = 8, lat = 18.552954, longi = 73.897200, counter=0, MainService_ID = 5
String url="https://servicedata2-dot-indiacomapi.appspot.com/_ah/api/servicedata/v1/ServiceData?city_id=";
url2 =url+city_id+"&lat="+lat+"&lng="+longi+"&roll="+counter+"&service_id="+MainService_ID;
AsyncHttpClient client = new AsyncHttpClient();
progressBar=(ProgressBar) findViewById(R.id.progressBar1);
progressBar.setVisibility(View.VISIBLE);
client.get(url2, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
String s = new String(response);
try {
JSONObject jsonObj = new JSONObject(s);
// Getting JSON Array node
items = jsonObj.getJSONArray(TAG_ITEMS);
// looping through All Contacts
for (int i = 0; i < items.length(); i++) {
JSONObject c = items.getJSONObject(i);
String locality = c.getString(TAG_LOCALITY);
String business_Id = c.getString(TAG_BUSINESS_ID);
String longitude = c.getString(TAG_LONGITUDE);
String latitude = c.getString(TAG_LATITUDE);
String business_Name = c.getString(TAG_BUSINESS_NAME);
locationfinder = new LocationFinder(RecyclerViewActivity.this);
// check if GPS enabled
if (locationfinder.canGetLocation()) {
double lat = locationfinder.getLatitude();
double longi = locationfinder.getLongitude();
currentLocation = new Location("");
currentLocation.setLatitude(lat);
currentLocation.setLongitude(longi);
} else {
locationfinder.showSettingsAlert();
}
Location savedLocation = new Location("databaseLocation");
savedLocation.setLatitude(Double.parseDouble(latitude));
savedLocation.setLongitude(Double.parseDouble(longitude));
Double difference = currentLocation.distanceTo(savedLocation) * (0.001);
difference = Double.parseDouble(new DecimalFormat("##.##").format(difference));
String newDifference = String.valueOf(difference) + " km";
ServiceModel serviceModel = new ServiceModel(business_Id, business_Name, newDifference, locality);
list.add(serviceModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
progressBar.setVisibility(View.GONE);
adapter = new RVAdapter(RecyclerViewActivity.this, list);
rv.setAdapter(adapter);
rv.addOnScrollListener(new EndlessRecyclerOnScrollListener(llm) {
#Override
public void onLoadMore(int current_page) {
// counter= counter+1;
loadMoreData();
}
});
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
//Toast.makeText(getApplicationContext(),""+statusCode,Toast.LENGTH_LONG).show();
}
});
}
private void loadMoreData() {
counter= counter+1;
//Here city_id = 8, lat = 18.552954, longi = 73.897200, counter=1, MainService_ID = 5
String url="https://servicedata2-dot-indiacomapi.appspot.com/_ah/api/servicedata/v1/ServiceData?city_id=";
url2 =url+city_id+"&lat="+lat+"&lng="+longi+"&roll="+counter+"&service_id="+MainService_ID;
AsyncHttpClient client = new AsyncHttpClient();
progressBar=(ProgressBar) findViewById(R.id.progressBar1);
progressBar.setVisibility(View.VISIBLE);
client.get(url2, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
String s = new String(response);
try {
JSONObject jsonObj = new JSONObject(s);
// Getting JSON Array node
items = jsonObj.getJSONArray(TAG_ITEMS);
// looping through All Contacts
for (int i = 0; i < items.length(); i++) {
JSONObject c = items.getJSONObject(i);
String locality = c.getString(TAG_LOCALITY);
String business_Id = c.getString(TAG_BUSINESS_ID);
String longitude = c.getString(TAG_LONGITUDE);
String latitude = c.getString(TAG_LATITUDE);
String business_Name = c.getString(TAG_BUSINESS_NAME);
locationfinder = new LocationFinder(RecyclerViewActivity.this);
// check if GPS enabled
if (locationfinder.canGetLocation()) {
double lat = locationfinder.getLatitude();
double longi = locationfinder.getLongitude();
currentLocation = new Location("");
currentLocation.setLatitude(lat);
currentLocation.setLongitude(longi);
} else {
locationfinder.showSettingsAlert();
}
Location savedLocation = new Location("databaseLocation");
savedLocation.setLatitude(Double.parseDouble(latitude));
savedLocation.setLongitude(Double.parseDouble(longitude));
Double difference = currentLocation.distanceTo(savedLocation) * (0.001);
difference = Double.parseDouble(new DecimalFormat("##.##").format(difference));
String newDifference = String.valueOf(difference) + " km";
ServiceModel serviceModel = new ServiceModel(business_Id, business_Name, newDifference, locality);
list.add(serviceModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
progressBar.setVisibility(View.GONE);
//adapter = new RVAdapter(RecyclerViewActivity.this, list);
//rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
}
});
Toast.makeText(this, "Net is present", Toast.LENGTH_SHORT).show();
}
}
RVAdapter.java
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{
private final LayoutInflater mInflater;
List<ServiceModel> persons ;
private Context mContext;
public RVAdapter(Context context,List<ServiceModel> persons){
this.mInflater = LayoutInflater.from(context);
this.persons = new ArrayList<>(persons);
this.mContext = context;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
PersonViewHolder pvh = new PersonViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
ServiceModel person = persons.get(i);
personViewHolder.businessName.setOnClickListener(clickListener);
personViewHolder.image_url.setOnClickListener(clickListenerImage);
personViewHolder.businessName.setTag(personViewHolder);
personViewHolder.difference.setTag(personViewHolder);
personViewHolder.business_id.setTag(personViewHolder);
personViewHolder.image_url.setTag(personViewHolder);
personViewHolder.locality.setTag(personViewHolder);
personViewHolder.businessName.setText(Html.fromHtml(person.getBusinessname()));
String firstLetter = String.valueOf(person.getBusinessname().charAt(0));
ColorGenerators generator = ColorGenerators.MATERIAL; // or use DEFAULT
int color = generator.getColor(person.getBusinessname());
TextDrawable drawable = TextDrawable.builder().buildRound(firstLetter, color); // radius in px
personViewHolder.image_url.setImageDrawable(drawable);
personViewHolder.difference.setText(Html.fromHtml(person.getNewDiffer()));
personViewHolder.locality.setText(Html.fromHtml(person.getLocality()));
personViewHolder.bind(person);
}
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
PersonViewHolder holder = (PersonViewHolder) view.getTag();
int position = holder.getPosition();
ServiceModel person = persons.get(position);
String businessids = person.getBusinessid();
Intent intent = new Intent(mContext, BusinessInfoActivity.class);
intent.putExtra("businessids", businessids);
mContext.startActivity(intent);
}
};
View.OnClickListener clickListenerImage = new View.OnClickListener() {
#Override
public void onClick(View view) {
PersonViewHolder holder = (PersonViewHolder) view.getTag();
int position = holder.getPosition();
ServiceModel person = persons.get(position);
String businessids = person.getBusinessid();
Intent intent = new Intent(mContext, BusinessInfoActivity.class);
intent.putExtra("businessids", businessids);
mContext.startActivity(intent);
}
};
#Override
public int getItemCount() {
return persons.size();
}
public void animateTo(List<ServiceModel> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(List<ServiceModel> newModels) {
for (int i = persons.size() - 1; i >= 0; i--) {
final ServiceModel model = persons.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<ServiceModel> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final ServiceModel model = newModels.get(i);
if (!persons.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<ServiceModel> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final ServiceModel model = newModels.get(toPosition);
final int fromPosition = persons.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public ServiceModel removeItem(int position) {
final ServiceModel model = persons.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, ServiceModel model) {
persons.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final ServiceModel model = persons.remove(fromPosition);
persons.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
public static class PersonViewHolder extends RecyclerView.ViewHolder {
protected CardView cv;
protected TextView businessName, difference, business_id, locality;
protected ImageView image_url;
public PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
businessName = (TextView)itemView.findViewById(R.id.business_name);
difference = (TextView)itemView.findViewById(R.id.txtDifferenece);
business_id = (TextView)itemView.findViewById(R.id.business_id);
image_url = (ImageView)itemView.findViewById(R.id.thumbnail);
locality= (TextView)itemView.findViewById(R.id.txtLocality);
}
public void bind(ServiceModel model) {
businessName.setText(model.getBusinessname());
}
}
}
Please help me, How to set notifyDataSetChanged() to the adapter. it is not working in my code. I already checked all answers which is posted on the stackoverflow.
you are setting the new list to the RecyclerView Adapter , set the list in the Adapter:
make a method setItems(list) in adapter and call it before notifyDataSetChanged() and in adapter do
this.persons = new ArrayList<>(persons);
in setItems
add this method in adapter:
public void setItems(List<ServiceModel> persons) {
this.persons = persons;
}
and call it before notifyDataSetChanged() like this:
adapter.setItems(list);
adapter.notifyDataSetChanged();
Issue is in these lines..
adapter = new RVAdapter(RecyclerViewActivity.this, list);
rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
You are initialising your adapter every time. No need to reinitialize it.
Just update your arraylist and invoking to adapter.notifyDataSetChanged(); will make it work.
Like #Beena mentioned, you are creating and setting new adapter ever time, in your success response.
One approach would be to create an adapter and set it to the recycler view only for the first time, and then onSuceess() of your api callback, call a method of your adapter.
In, them adapter method, just add that new data in your main arraylist and do notifyItemInserted() instead of notifyDataSetChanged, in this way you will also see the default adding animation of recyclerView.
Every time you fill your list call the method below:
if (adapter != null) // it works second time and later
adapter.notifyDataSetChanged();
else { // it works first time
adapter = new AdapterClass(context,list);
listView.setAdapter(adapter);
}
I solved this with added method in RVAdapter that call notifyDataSetChanged().
Simply in RVAdapter:
public void refreshList(){
notifyDataSetChanged();
}
and call this method in MainActivity when need:
rVAdapter.refreshList();
I have an array that is filled with API data, and I have an expandablelistview to show the items of that array, now what I'm trying to do is when the user clicks on an item it saves th ID of that item into an array, so if the user select 2 items I want 2 Ids in my array, what is happening now is this: no matter if I select only one of the items it gets all of them and save it inside my array.
public class MainActivity extends Fragment {
private ExpandListAdapter ExpAdapter;
private ExpandableListView ExpandList;
private Button notificar;
private Context context;
MainActivity mContext;
private Button footer;
private double RaioEscola;
private CircleOptions mCircle;
GPSTracker tracker;
private Location location;
private Integer IdEscola;
public MainActivity() {
}
public MainActivity(Context context) {
this.context = context;
}
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.expand, container, false);
ExpandList = (ExpandableListView) rootView.findViewById(R.id.exp_list);
notificar = (Button) rootView.findViewById(R.id.btnGetMoreResults);
new asyncTask(MainActivity.this).execute();
return rootView;
}
private class asyncTask extends AsyncTask<String, Void, Void> {
private ProgressDialog pd;
public asyncTask(MainActivity context) {
mContext = context;
pd = new ProgressDialog(getActivity());
pd.setTitle("Por Favor Espere ...");
pd.setMessage("Enviando ...");
if (!pd.isShowing()) {
pd.show();
}
}
#Override
protected Void doInBackground(final String... params) {
try {
String[] resposta = new WebService().get("filhos");
if (resposta[0].equals("200")) {
JSONObject mJSONObject = new JSONObject(resposta[1]);
JSONArray dados = mJSONObject.getJSONArray("data");
/* cria o array que vai receber os dados da api */
final ArrayList<Escolas> mArrayList = new ArrayList<Escolas>();
/* percorre o array, adicionando cada linha encontrada em um ArrayList */
for (int i = 0; i < dados.length(); i++) {
JSONObject item = dados.getJSONObject(i);
Escolas mEscolas = new Escolas();
mEscolas.setId_escola(item.optInt("id_escola"));
mEscolas.setCnpj(item.getString("cnpj"));
mEscolas.setRazao_social(item.getString("razao_social"));
mEscolas.setNome_fantasia(item.getString("nome_fantasia"));
mEscolas.setDistancia(Float.valueOf(item.getString("distancia")));
mEscolas.setLogradouro(item.optString("logradouro"));
mEscolas.setNumero(item.optString("numero"));
mEscolas.setBairro(item.getString("bairro"));
mEscolas.setComplemento(item.getString("complemento"));
mEscolas.setCep(item.getString("cep"));
mEscolas.setCidade(item.getString("cidade"));
mEscolas.setEstado(item.getString("estado"));
mEscolas.setLatitude(Float.parseFloat(item.getString("latitude")));
mEscolas.setLongitude(Float.parseFloat(item.getString("longitude")));
RaioEscola = Double.parseDouble(String.valueOf(mEscolas.getDistancia()));
IdEscola = mEscolas.getId_escola();
JSONObject alunos = item.optJSONObject("alunos");
JSONArray data = alunos.getJSONArray("data");
if (data != null) {
ArrayList<Filhos> arrayalunos = new ArrayList<Filhos>();
for (int a = 0; a < data.length(); a++) {
Filhos mFilhos = new Filhos();
JSONObject clientes = data.getJSONObject(a);
mFilhos.setId_aluno(clientes.optInt("id_aluno"));
mFilhos.setNome(clientes.optString("nome"));
mFilhos.setSobrenome(clientes.optString("sobrenome"));
mFilhos.setFoto(clientes.optString("foto"));
mFilhos.setModalidade_de_ensino(clientes.optString("modalidade_de_ensino"));
mFilhos.setObservacoes(clientes.optString("observacoes"));
arrayalunos.add(mFilhos);
}
mEscolas.setalunos(arrayalunos);
}
/* popula o array de viagens */
mArrayList.add(mEscolas);
ExpAdapter = new ExpandListAdapter(getActivity(), mArrayList);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
ExpandList.setAdapter(ExpAdapter);
ExpAdapter.notifyDataSetChanged();
ExpAdapter.setChoiceMode(ExpandListAdapter.CHOICE_MODE_MULTIPLE);
ExpandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(final ExpandableListView parent, View v, final int groupPosition, final int childPosition, final long id) {
ExpAdapter.setClicked(groupPosition, childPosition);
final int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
parent.setItemChecked(index, true);
parent.setSelectedChild(groupPosition, childPosition, true);
parent.getChildAt(index);
notificar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
class update extends TimerTask {
public void run() {
try {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
final float latitude = mArrayList.get(groupPosition).getLatitude();
final float longitude = mArrayList.get(groupPosition).getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
drawMarkerWithCircle(latLng);
GPSTracker gps = new GPSTracker(getActivity());
double latitudegps = gps.getLatitude();
double longitudegps = gps.getLongitude();
float[] distance = new float[2];
Location.distanceBetween(mCircle.getCenter().latitude, mCircle.getCenter().longitude, latitudegps, longitudegps, distance);
if (distance[0] > mCircle.getRadius()) {
Toast.makeText(getActivity(), "Outside", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getActivity(), "Inside", Toast.LENGTH_LONG).show();
AlertRest mAlertRest = new AlertRest();
try {
List<Integer> myIdList = new ArrayList<Integer>();
for (int i = 0; i < mArrayList.get(groupPosition).getalunos().size(); i++) {
Integer Idalunos = mArrayList.get(groupPosition).getalunos().get(i).getId_aluno();
myIdList.add(Idalunos);
}
mAlertRest.getNotificacao(1, mArrayList.get(groupPosition).getId_escola(), String.valueOf(myIdList), latitudegps, longitudegps);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Timer timer = new Timer();
timer.schedule(new update(), 0, 15000);
}
private void drawMarkerWithCircle(LatLng position) {
mCircle = new CircleOptions().center(position).radius(RaioEscola);
}
});
return false;
}
});
}
});
}
/* retorna um array de objetos */
}
else {
throw new Exception("[" + resposta[0] + "] ERRO: " + resposta[1]);
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void cursor) {
if (pd.isShowing()) {
pd.dismiss();
}
}
}
}
AlertRest:
public class AlertRest extends WebService {
private String recurso = "notificacoes";
private String[] resposta;
private AlertModelo mAlertModelo;
public AlertModelo getNotificacao(Integer id_usuario, String token, Integer id_escola, String ids_aluno, Double latitude, Double longitude) throws Exception {
/* dispara a requisição para a API retornar os dados do "recurso" necessário */
resposta = new WebService().postToken(recurso, token, "{\"id_usuario\":" + id_usuario + "," + "\"id_escola\":" + id_escola + "," + "\"ids_aluno\":\"" + ids_aluno + "\"," + "\"latitude\":" + latitude + "," + "\"longitude\":" + longitude + "}");
JSONObject mJSONObject = new JSONObject(resposta[1]);
if (resposta[1].equals("201")) {
mAlertModelo = new AlertModelo();
mAlertModelo.setId_usuario(mJSONObject.getInt(String.valueOf(id_usuario)));
mAlertModelo.setId_escola(mJSONObject.getInt(String.valueOf(id_escola)));
mAlertModelo.setIds_aluno(mJSONObject.getInt(String.valueOf(ids_aluno)));
mAlertModelo.setLatitude(mJSONObject.getDouble(String.valueOf(latitude)));
mAlertModelo.setLongitude(mJSONObject.getDouble(String.valueOf(longitude)));
}
return mAlertModelo;
}
}
The code is difficult to follow due to few nested loops and running tasks.
Anyway, I suspect the code below is causing your app to save all (unselected) items in the list:
for (int i = 0; i < mArrayList.get(groupPosition).getalunos().size(); i++) {
Integer Idalunos = mArrayList.get(groupPosition).getalunos().get(i).getId_aluno();
myIdList.add(Idalunos);
}
Note: Iterating through the entire list is a suspect. It should pick a certain item or items in the list.
So...another set of relevant codes can help us determine the code fix. I am not certain if there is a bug here also.
parent.setItemChecked(index, true);
parent.setSelectedChild(groupPosition, childPosition, true);
parent.getChildAt(index);
Note: These codes may be fine. The key code, I think, is the index. I am not too familiar with ExpandableListView.
Finally, suggested code fix:
Integer Idalunos = mArrayList.get(groupPosition).getalunos().get(index).getId_aluno();
...
myIdList.add(Idalunos);
Notice the variable index is used to get the correct item, Idalunos.
You are using mArrayList variable for initializing adapter and for filling myIdList at the same time. Of course myIdList would contain full list of your adapter.
UPDATE
It would be better to define myIdList as field of your MainActivity class and initialize it in onCreateView method.
On click not just add the value - you should check if this value is allready in list:
if(myIdList.contains(Idalunos)) {
myIdList.remove(Idalunos);
} else {
myIdList.add(Idalunos);
}