Swiperefresh listview, updates but not how you would expect - android

I have a Listview that is using the swipefresh feature, and I've encountered a weird problem. When I swipe down, I see the animation and my information (updates behind the scenes.) However, I can't see the updated information, UNTIL I physically scroll down and back up again. The moment I scroll back up towards the top the old data is replaced with the new data.
swipe//
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_green_light);
final TextView rndNum = (TextView) findViewById(R.id.timeStamp);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.i("Refreshing", " onRefresh called from SwipeRefreshLayout");
initiateRefresh();
}
});
Asynctask//
private void initiateRefresh() {
Log.i("iRefreshing", "initiateRefresh");
/**
* Execute the background task, which uses {#link android.os.AsyncTask} to load the data.
*/
new bgRefresh().execute();
}
private class bgRefresh extends AsyncTask<Void, Void, Boolean> {
static final int TASK_DURATION = 3 * 1000; // 3 seconds
#Override
protected Boolean doInBackground(Void... params) {
// Sleep for a small amount of time to simulate a background-task
try {
Thread.sleep(TASK_DURATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
ArrayList<String> blah = new ArrayList<>();
try {
// Simulate network access
Calendar cal = Calendar.getInstance();
SimpleDateFormat month_date = new SimpleDateFormat("M");
String monthName = month_date.format(cal.getTime());
int lastDayOfMonth =(cal.getActualMaximum(Calendar.DAY_OF_MONTH));
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int year = Calendar.getInstance().get(Calendar.YEAR); ;
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH,1);
monthName = month_date.format(cal.getTime());
//String test = cal.getTime();
//start_date_monthly_statements=5/1/15&end_date_monthly_statements=5/27/15&activity_detail_type=all&reg_captcha=&display=
String startDateRecentActivity = monthName + "/1/" + currentYear;
String enddateRecentyActivity = monthName + "/" + lastDayOfMonth + "/" + currentYear;
///second calendar
Calendar cal2 = Calendar.getInstance();
cal2 = Calendar.getInstance();
// cal.add(Calendar.DAY_OF_MONTH, -5); //Go back to the previous month
webCreate web = new webCreate();
try {
//Clear and go.
Fields.clear();
Values.clear();
Fields.add("data1");
Values.add(datav1");
cal = Calendar.getInstance();
month_date = new SimpleDateFormat("MM-dd-yyyy hh:mma");
String date = month_date.format(cal.getTime());
date = date.replace("-", "/");
date = date.replace(" ", "\n");
refreshTS = (TextView) findViewById(R.id.timeStamp);
refreshTS.setText(date);
mMainListAdapter = new CustomListViewAdapter(getApplicationContext(), Fields, Values);
mAdapter.n
} catch (Exception e) {
e.printStackTrace();
return false;
}
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
mAdapter.notifyDataSetChanged();
// Tell the Fragment that the refresh has completed
onRefreshComplete(result);
}
}
private void onRefreshComplete(Boolean result) {
Log.i("LOG_TAG", "onRefreshComplete");
// Remove all items from the ListAdapter, and then replace them with the new items
//mListAdapter.clear();
//for (String cheese : result) {
// mListAdapter.add(cheese);
//}
// Stop the refreshing indicator
swipeLayout.setRefreshing(false);
}
What would or could cause this?

Looks like from my view of the code you have two adapters? mMainListAdapter and mAdapter? Since the data only appears when you scroll back, this means that you aren't properly notifying the adapter that you have updated the data. Call the notifyDatasetChanged() on the other adapter, since mMainListAdapter appears to be the main adapter.

You have to notify the adapter about the update with notifyDataSetChanged, or create a new adapter. This is on the method SwipeRefreshLayout.setOnRefreshListener. Follow this example:
https://www.bignerdranch.com/blog/implementing-swipe-to-refresh/
Edit
Since your last update I can see that mMainListAdapter is your adapter. Then in your onPostExecute set the adapter to the ListView.
myListView.setAdapter(mMainListAdapter);
Repleace myListView with your ListView

Related

duplicate list is adding to gridview in android

Hi in the below I am displaying calendarview.In calendarview I am selecting date and passing that date to GetAppointmentDate(selecteddate) if selecteddate and my date matches I am displaying gridview layout.but it is give multiple list with below .
Can any one help y duplicate list is displaying evrytime.
CalendarViewActivity.java:
public class CalendarViewActivity extends Activity implements DatetimeAdapter.MyItemClickListener{
private CalendarView mCalendarView;
private ProgressDialog progressDialog = null;
private ArrayList<GetData> getDataArrayList;
private ArrayList<GetSlots> getSlotsArrayList;
private GridView gridLayout;
private GetData getData2;
private GetSlots getSlots2;
private String Id,StartTime,SlotBooked,SlotDate,EndTime,SloteTime;
private DatetimeAdapter datetimeAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar_view);
gridLayout=findViewById(R.id.gridlayout);
getDataArrayList=new ArrayList<>();
getSlotsArrayList=new ArrayList<>();
mCalendarView = (CalendarView) findViewById(R.id.calendarView);
mCalendarView.setMinDate(System.currentTimeMillis() - 1000);
datetimeAdapter = new DatetimeAdapter(getApplicationContext(), getSlotsArrayList,this);
mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
Calendar calendar = Calendar.getInstance();
int year1 = calendar.get(Calendar.YEAR);
int month1 = calendar.get(Calendar.MONTH);
int dayOfMonth1 = calendar.get(Calendar.DAY_OF_MONTH);
#Override
public void onSelectedDayChange(CalendarView CalendarView, int year1, int month1, int dayOfMonth1) {
String date = new SimpleDateFormat("MM", Locale.getDefault()).format(new Date());
SimpleDateFormat sdf = new SimpleDateFormat(date);
String selecteddate = (sdf.format(month1 + 1)) + "/" + dayOfMonth1 + "/" + year1;
GetAppointmentDate(selecteddate);
Toast.makeText(getApplicationContext(),selecteddate,Toast.LENGTH_LONG).show();
}
});
}
private void GetAppointmentDate(String outputcurrentdate) {
// progressDialog = new ProgressDialog(getApplicationContext());
// progressDialog.setIndeterminate(true);
// progressDialog.setMessage("Loading...");
// progressDialog.setCanceledOnTouchOutside(false);
// progressDialog.setCancelable(false);
// progressDialog.show();
String doctor_ids="13";
String HospitalId="PH:193";
final APIService service = RetroClass.getRetrofitInstance().create(APIService.class);
Call<GetAppointmentDateModel> call = service.GetAppointmentDate(doctor_ids,HospitalId);
Log.wtf("URL Called", call.request().url() + "");
call.enqueue(new Callback<GetAppointmentDateModel>() {
#Override
public void onResponse(Call<GetAppointmentDateModel> call, Response<GetAppointmentDateModel> response) {
Log.e("response", new Gson().toJson(response.body()));
if (response.isSuccessful()) {
Log.e("response", new Gson().toJson(response.body()));
GetAppointmentDateModel getAppointmentDateModel = response.body();
ArrayList<GetData> getData = getAppointmentDateModel.getGetAppointmentList();
for (GetData getData1 : getData) {
String date1 = getData1.getDate();
String id=getData1.getId();
DateFormat inputFormatter = new SimpleDateFormat("dd MMM yyyy HH:mm-HH:mm");
Date date = null;
try {
date = inputFormatter.parse(date1);
DateFormat outputFormatter = new SimpleDateFormat("MM/dd/yyyy");
String output = outputFormatter.format(date);
getData2=new GetData(id,output);
getDataArrayList.add(getData2);
Log.d("dateString",output);
ArrayList<GetSlots> getSlots = getData1.getData();
for (GetSlots getSlots1 : getSlots) {
Id=getSlots1.getId();
SlotDate=getSlots1.getDate();
StartTime=getSlots1.getStartTime();
EndTime=getSlots1.getEndTime();
SloteTime=getSlots1.getSlotTime();
SlotBooked=getSlots1.getSlotBooked();
getSlots2=new GetSlots(Id,SlotDate,StartTime,EndTime,SlotBooked,SloteTime);
getSlotsArrayList.add(getSlots2);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
String current_date=getData2.getDate();
if(current_date.equals(outputcurrentdate)) {
gridLayout.setAdapter(datetimeAdapter);
datetimeAdapter.notifyDataSetChanged();
}
}
// progressDialog.dismiss();
}
#Override
public void onFailure(Call<GetAppointmentDateModel> call, Throwable t) {
Log.d("error", t.getMessage());
// progressDialog.dismiss();
}
});
}
#Override
public void myItemClick(int position) {
}
}
Your list - getSlotsArrayList is addding new values each time and it is not clearing anywhere. This is the same list that is passed to the adapter. so it is displaying multiple values.
Call clear method before this
getSlotsArrayList.clear();
GetAppointmentDate(selecteddate);

Validate URL in android over network call

I am making an app where i have a url with date.I need to check if the url has data and if it had data then add date to list.I have made a method which i have posted below and it is being call on main thread.But the problem is it takes few seconds to start the app.I need to optimise the app.Is there any other way to "REDUCE THE LOADING TIME".
Code
private List<String> getDateList(int counter, String date) {
String urlth = "https://www.example.com/json/" + date.trim().replaceAll("/", "") + "-12.json";
if (validateUrl.exists(urlth)) {
dateList.add(date);
} else {
date = givePreviousDate(date);
return getDateList(counter, date);
}
if (dateList.size() == 7) {
return dateList;
} else {
date = givePreviousDate(date); //gives previous date
return getDateList(++counter, (date));
}
}
You can use a handler to call your method in background, something like this
Handler handler = new Handler();
ListView<String> myList = new ArrayList<>();
handler.post(new Runnable() {
#Override
public void run() {
//call your method here
myList = getDateList(2, "date"); //with int and date data
}
});
Hope this will help!

Android datepicker setmindate

I have two datepickers in my activity.
I want startdate of datePickerB dialog to be updated automatically based on date selected in datePickerA dialog.
I use setMinDate for datePickerB. setMinDate works fine for the very first time. But couldn't update or reset the mindate of datePickerB for consecutive updates in datePickerA. Kindly help.
Searched for all possible solutions but of no use. Kindly help
Below is my code. The code used in oncreate gets executed , but further setMinDate function called in HandleResponse ( this is the function that gets called once datepickerA is set )
//On OnCreate
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, 1);
Date tomorrow = calendar.getTime();
long t = tomorrow.getTime();
fromDatePicker.getDatePicker().setMinDate(t);
//
toDatePicker.getDatePicker().setMinDate(t);
public void HandleResponse(Response response)
{
String sqlRes = "";
try {
String sResJson = response.body().string();
JSONObject jReader = new JSONObject(sResJson);
JSONObject jRes = jReader.getJSONObject("Result");
sqlRes = jRes.getString("res");
final int sqlMilkQty = jRes.getInt("qty");
String enddate = jRes.getString("date");
Date d = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
d = sdf.parse(enddate);
} catch (ParseException e) {
e.printStackTrace();
}
if (d != null && fromDate!= null) {
long t = d.getTime();
long t1 = fromDate.getTime();
toDatePicker.getDatePicker().setMinDate(t1);
toDatePicker.getDatePicker().setMaxDate(t);
}
Handler mainHandler = new Handler(Looper.getMainLooper());
if (sqlRes.equals("PASS"))
{
mainHandler.post(new Runnable() {
#Override
public void run() {
milkQuantity = sqlMilkQty;
txtMilkQuantity.setText(String.valueOf(milkQuantity));
}
});
}
else {
}
} catch (IOException e) {
DisplayError();
}
catch (JSONException e) {
DisplayError();
}
}

how to make the asynctask run in background even the activity destroyed?

i'm making some asynctask method, but i'm not really sure how to make it keep running on the background when the app was closed. Some said it could be used with Service or put the code in doinbackground but i'm not sure how to implement it. Btw, Here's my code:
private class DataBinatangOperation extends AsyncTask<String, Void, String> {
MainMenuAdapter adapter = new MainMenuAdapter(MainMenu.this,
listBinatang);
#Override
protected String doInBackground(String... params) {
JSONArray json;
try {
result = JSONParser.getPage(url);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String result) {
//updateList();
tv.setVisibility(View.GONE);
//mSwipeRefreshLayout.setRefreshing(false);
try {
System.out.print("result = " + result);
json = new JSONObject(result);
progress.dismiss();
JSONArray objek = json.getJSONArray("data_vaksinasi_menu");
for (int i = 0; i < objek.length(); i++) {
JSONObject jo = objek.getJSONObject(i);
ID_USER = jo.getString(id_user);
ID_BINATANG = jo.getString(id_binatang);
NAMA_BINATANG = jo.getString(nama_binatang);
JENIS_BINATANG = jo.getString(jenis_binatang);
FOTO_BINATANG = jo.getString(foto_binatang);
TANGGAL_VAKSIN = jo.getString(tanggal_vaksin);
NAMA_VAKSIN = jo.getString(nama_vaksin);
RAS_BINATANG = jo.getString(ras_binatang);
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
Calendar waktuSekarang = Calendar.getInstance();
Date date1 = waktuSekarang.getTime();
Date date2 = new Date();
date2 = formatter.parse(TANGGAL_VAKSIN);
/*waktuVaksin.setTime(date2);
DateMidnight start = new DateMidnight(tanggalSkrg);
DateMidnight vaksin = new DateMidnight(TANGGAL_VAKSIN);*/
if (pref.getPreferences("ID").equals(ID_USER)) {
if (date2.after(date1)) {
int days = Days.daysBetween(new DateTime(date1), new DateTime(date2)).getDays();
if (days > 7 && days <= 30) {
int weeks = days / 7;
sisaWaktu = String.valueOf(weeks) + " minggu";
} else if (days > 30 && days <= 365) {
int months = days / 30;
sisaWaktu = String.valueOf(months) + " bulan";
} else if (days > 365) {
int years = days / 365;
sisaWaktu = String.valueOf(years) + " tahun";
} else {
sisaWaktu = String.valueOf(days) + " hari";
if (days <= 5) {
NH.createSimpleNotification(getActivity(), NAMA_BINATANG, sisaWaktu, ID_BINATANG);
}
}
} else if (date2.before(date1)) {
int days = Days.daysBetween(new DateTime(date2), new DateTime(date1)).getDays();
sisaWaktu = "lewat " + String.valueOf(days) + " hari";
NH.createButtonNotification(getActivity(), NAMA_BINATANG, sisaWaktu, ID_BINATANG);
} else if (date2.equals(date1)) {
sisaWaktu = "sekarang";
NH.createButtonNotification(getActivity(), NAMA_BINATANG, sisaWaktu, ID_BINATANG);
}
}
HashMap<String, String> map = new HashMap<String, String>();
map.put(id_binatang, ID_BINATANG);
map.put(nama_binatang, NAMA_BINATANG);
map.put(jenis_binatang, JENIS_BINATANG);
map.put(foto_binatang, urlgambar+FOTO_BINATANG);
map.put(ras_binatang, RAS_BINATANG);
map.put(tanggal_vaksin, sisaWaktu);
map.put(nama_vaksin, NAMA_VAKSIN);
if (pref.getPreferences("ID").equals(ID_USER)) {
listBinatang.add(map);
}
}
System.out.println("hasil list : " + String.valueOf(listBinatang));
System.out.println("adapter : " + String.valueOf(adapter));
list.setAdapter(adapter);
/*list.setVisibility(View.VISIBLE);*/
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long idx) {
HashMap<String, String> ambilid = new HashMap<String, String>();
ambilid = listBinatang.get(position);
Toast.makeText(getActivity(), "pindah halaman", Toast.LENGTH_SHORT).show();
Intent a = new Intent(getActivity(), MainPetInformation.class);
pref.savePreferences("IDB", ambilid.get(MainMenu.id_binatang));
pref.savePreferences("NAMAB", ambilid.get(MainMenu.nama_binatang));
pref.savePreferences("FOTOB", ambilid.get(MainMenu.foto_binatang));
pref.savePreferences("JENISB", ambilid.get(MainMenu.jenis_binatang));
pref.savePreferences("RASB", ambilid.get(MainMenu.ras_binatang));
startActivity(a);
}
});
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
}
#Override
protected void onPreExecute() {
listBinatang.clear();
adapter.notifyDataSetChanged();
progress = ProgressDialog.show(getActivity(), "Please Wait",
"Loading Data", true);
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
protected abstract Object doInBackground(Object... params)
Is the method from the AsyncTask that performs operations in the background of the main thread (also known as UI thread), which is used to do actions that either are required to be performed off the main thread (networking) or you want to do without preventing a negative user experience (such as a task that would prevent the user from using the app any further until the task has completed).
Here is a succinct and nice tutorial for Services, which is indeed what you are looking for: http://www.vogella.com/tutorials/AndroidServices/article.html. A service can perform operations in the background like an AsyncTask's doInBackground method does, but can do it when the app is in the background as you said, and in intervals if you need it to.
I could go into more depth on this, but that tutorial has all the information you need and I suspect it is what you are looking for.

Run CountDownTimer on array of dates

I have the array of objects that look like this:
public class Time {
public String start_time;
public String finish_time;
public Time(String start_time, String finish_time) {
this.start_time = start_time;
this.finish_time = finish_time;
}
}
I need to implement a timer in my Fragment in the following way:
it should start counting down from the first element in array in a way that on one single Time element it should first start counting down to the time left to reach start_time, then when the timer reaches start_time, it should start counting down to finish_time and, eventually, when it reaches finish_time it should do the same previous actions for the next element in the array. And when the whole array is finished, it should display 00:00:00.
PS: start_time and finish_time are formatted like this: HH:mm however the timer should be HH:mm:ss
Can anybody help with implementing that or at least give an idea?
Finally, found the appropriate answer. Thanks a lot to the guy who helped me with it:
class Clazz {
private Timer dateTimer;
private Timer remainderTimer;
private Date nextDate;
private boolean remainderTimerStarted;
private static final long REMINDER_UPDATE_INTERVAL = 1000;
private static final String[] DATES = { "12.04.2015 22:21", "12.04.2015 22:22", "12.04.2015 22:23" };
private int currentIndex;
public Clazz() {
dateTimer = new Timer();
}
public static void main(String[] args) {
Clazz instance = new Clazz();
instance.run();
}
private void run() {
nextDate = parseDate(DATES[currentIndex]);
schedule();
}
public void schedule() {
runSecondsCounter();
dateTimer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Current date is:" + new Date());
currentIndex++;
if (currentIndex < DATES.length) {
nextDate = parseDate(DATES[currentIndex]);
System.out.println("Next date is:" + nextDate);
schedule();
} else {
remainderTimer.cancel();
}
}
}, nextDate);
}
private Date parseDate(String nextDate) {
Date date = null;
DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm",
Locale.ENGLISH);
try {
date = format.parse(nextDate);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
private void runSecondsCounter() {
if (remainderTimerStarted) {
remainderTimer.cancel();
}
remainderTimer = new Timer();
remainderTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
remainderTimerStarted = true;
long remains = nextDate.getTime() - new Date().getTime();
System.out.println("Remains: " + (remains / 1000) + " seconds");
}
}, REMINDER_UPDATE_INTERVAL, REMINDER_UPDATE_INTERVAL);
}
}

Categories

Resources