I have a weather api. I have set JSON objects for list items.Everything is working.And I remove the items from recycleradapter when it's clicked.
public class ForecastAdapters extends RecyclerView.Adapter<ForecastAdapters.ForecastHolder> {
private Context mContext;
private List<OpenWeatherMapDaysTo> openWeatherMapDaysTos = new ArrayList<>();
private OpenWeatherMapDaysTo mOpenWeatherMapDaysTo = new OpenWeatherMapDaysTo();
private Toast mToast;
private ForecastAdapters mForecastAdapters;
public ForecastAdapters(Context context, List<OpenWeatherMapDaysTo> op) {
mContext = context;
openWeatherMapDaysTos = op;
}
public class ForecastHolder extends RecyclerView.ViewHolder {
private TextView mTextName, mMornigText, mNightText,mClock;
private ImageView mImage;
public ForecastHolder(View view) {
super(view);
mTextName = (TextView) view.findViewById(R.id.fr_days_txt);
mMornigText = (TextView) view.findViewById(R.id.fr_morning);
mNightText = (TextView) view.findViewById(R.id.fr_night);
mClock =(TextView)view.findViewById(R.id.fr_clock);
mImage = (ImageView) view.findViewById(R.id.fr_imageView);
}
public void bindData(OpenWeatherMapDaysTo opData) {
mTextName.setText(VolleyURL.getJustAllDate(opData.getList().get(getAdapterPosition()).getDt_txt()));
mMornigText.setText(String.format("%d°C", Math.round(opData.getList().get(getAdapterPosition()).getMain().getTemp_max() - 273.15)));
mNightText.setText(String.format("%d°C", Math.round(opData.getList().get(getAdapterPosition()).getMain().getTemp_min() - 273.15)));
mClock.setText(String.format(VolleyURL.unixTimeStampToDateTime(opData.getList().get(getAdapterPosition()).getDt())));
Picasso.with(mContext).load(VolleyURL.getImage(opData.getList().get(getAdapterPosition()).getWeather().get(0).getIcon())).into(mImage);
}
}
@Override
public ForecastAdapters.ForecastHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_fragment, parent, false);
return new ForecastHolder(view);
}
@Override
public void onBindViewHolder(final ForecastAdapters.ForecastHolder holder, final int position) {
OpenWeatherMapDaysTo op = openWeatherMapDaysTos.get(position);
holder.bindData(op);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(mContext, holder.getAdapterPosition()+ " Clicked", Toast.LENGTH_SHORT);
mToast.show();
/* removeAt(holder.getAdapterPosition());*/
}
});
}
@Override
public int getItemCount() {
return openWeatherMapDaysTos.size();
}
public void removeAt(int position) {
openWeatherMapDaysTos.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, openWeatherMapDaysTos.size());
}
}
And method is this
public void removeAt(int position) {
openWeatherMapDaysTos.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, openWeatherMapDaysTos.size());
}
I want to remove JSON objects that I desire when Adapter will not create.OR Adapter will create.Then I will remove the items that I desired without clickable.The adapter will be renewed and will be shown. How can do that? or any ideas for that.
For example, the json includes Mon, Tue, Wed, Thurs, Friday etc.Also, They are duplicated.Because 5-day forecast includes weather data every 3 hours. I could not remove three Monday.
Finally, this is my method in main activity and I have used Volley and gson.
UPDATE-1 METHOD: (I changed the method that was separated by two For loop.)
//get5daysForecast
public void getFiveDays() {
mProg.setVisibility(View.VISIBLE);
StringRequest mStringRequest = new StringRequest(Request.Method.POST, VolleyURL.API_GET_FORECAST, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Gson gson = new Gson();
Type mType = new TypeToken<OpenWeatherMapDays>() {
}.getRawType();
Type mTypeto = new TypeToken<OpenWeatherMapDaysTo>() {
}.getType();
openWeatherMapDays = gson.fromJson(response, mType);
openWeatherMapDaysTo = gson.fromJson(response, mTypeto);
for (int i = 0; i < openWeatherMapDays.getList().size(); i++) {
String as = openWeatherMapDays.getList().get(i).getDt_txt();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar c = Calendar.getInstance(TimeZone.getTimeZone(as));
c.add(Calendar.DAY_OF_YEAR, 2);
String mTomorrow = sdf.format(c.getTime());
Date dt = null;
Date dtTomorrow = null;
try {
dt = sdf.parse(as);
dtTomorrow = sdf.parse(mTomorrow);
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String finalDate = dateFormat.format(dt);
String tomorrow = dateFormat.format(dtTomorrow);
if (finalDate.equals(tomorrow)) {
openWeatherMapDays.getList().get(i);
mOpenWeatherMapList.add(openWeatherMapDays);
mProg.setVisibility(View.INVISIBLE);
mCardUpView.setVisibility(View.VISIBLE);
mListUPview.setVisibility(View.VISIBLE);
mCardForecastAdapters.notifyDataSetChanged();
}
}
for (int j = 0; j < openWeatherMapDaysTo.getList().size(); j++) {
String as = openWeatherMapDaysTo.getList().get(j).getDt_txt();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar c = Calendar.getInstance(TimeZone.getTimeZone(as));
c.add(Calendar.DAY_OF_YEAR, 2);
String mTomorrow = sdf.format(c.getTime());
Date dt = null;
Date dtTomorrow = null;
try {
dt = sdf.parse(as);
dtTomorrow = sdf.parse(mTomorrow);
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String finalDate = dateFormat.format(dt);
String tomorrow = dateFormat.format(dtTomorrow);
Log.d(TAG, "FinalDatewitVolley---------;> : " + finalDate.compareTo(VolleyURL.getDateNumber()));
Log.d(TAG, "VolleyURL:-----------------------> " + VolleyURL.getDateNumber());
Log.d(TAG, "FinalDate ----------------------->: " + finalDate);
if ((finalDate.compareTo(VolleyURL.getDateNumber())!=0)) {
Log.d(TAG, "===TRUE====: ");
openWeatherMapDaysTo.getList().get(j);
getmOpenWeatherMapListto.add(openWeatherMapDaysTo);
Log.d(TAG, "openWeatherDaysTo SIZE ===> " + getmOpenWeatherMapListto.size());
mForecastAdapters = new ForecastAdapters(getApplicationContext(), getmOpenWeatherMapListto);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mForecastAdapters);
mForecastAdapters.notifyDataSetChanged();
}else {
Log.d(TAG, "===FALSE====: ");
}
}
}
}, new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error) {
}
})
{
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
int mStatusCode = response.statusCode;
Log.d(TAG, "mStatusCode - FORECAST: " + mStatusCode);
return super.parseNetworkResponse(response);
}
};
mStringRequest.setRetryPolicy(new
DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleyController.getmInstance().
addToRequestQueue(mStringRequest);
}
Second adapter mCardForecastAdapter is working! the issue is in the "else" condition for mForecastAdapters and I have tried if(finalDate.compareTo(VolleyURL.getDateNumber())>0)
but it didn't work.
And I take these output.
as you can see that Not included in the list when compareTo() returns zero.However, RecyclerView shows it.
in addition: When I used this condition:
if((finalDate.equals(VolleyURL.getDateNumber()))){
openWeatherMapDaysTo.getList().get(i);
getmOpenWeatherMapListto.add(openWeatherMapDaysTo);
Log.d(TAG, "openWeatherDaysTo SIZE (2) ===> " + getmOpenWeatherMapListto.size());}
RecyclerAdapter shows first 5 items and all other elements is not showing.But I don't want to showed first 5 elements.I want to showed after the first 5 elements.
Edit-1: this is my Model class and objects
public class OpenWeatherMapDaysTo {
private String cod;
private double message;
private int cnt;
private List<Lists2> list;
private City city;
private Main main;
public OpenWeatherMapDaysTo(){
}
public OpenWeatherMapDaysTo(String cod, double message, int cnt, List<Lists2> list, City city, Main main) {
this.cod = cod;
this.message = message;
this.cnt = cnt;
this.list = list;
this.city = city;
this.main = main;
}
public String getCod() {
return cod;
}
public void setCod(String cod) {
this.cod = cod;
}
public double getMessage() {
return message;
}
public void setMessage(double message) {
this.message = message;
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public List<Lists2> getList() {
return list;
}
public void setList(List<Lists2> list) {
this.list = list;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
}
my lists2 class:
public class Lists2 {
private int dt;
private Main main;
private List<Weather> weather;
private Clouds clouds;
private Wind wind;
private Sys sys;
private String dt_txt;
public Lists2(int dt, Main main, List<Weather> weather, Clouds clouds, Wind wind, Sys sys, String dt_txt) {
this.dt = dt;
this.main = main;
this.weather = weather;
this.clouds = clouds;
this.wind = wind;
this.sys = sys;
this.dt_txt = dt_txt;
}
public int getDt() {
return dt;
}
public void setDt(int dt) {
this.dt = dt;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public String getDt_txt() {
return dt_txt;
}
public void setDt_txt(String dt_txt) {
this.dt_txt = dt_txt;
}
}
and another Model classes
Finally: My problem is
From what I can tell you are sending the whole list of forecasts ( List<Lists2>
) to your ForecastAdapters
when you only want to show one Lists2
object (per RecyclerView
item).
Your for loop
is iterating through the Lists2
objects, which as far as I can tell is the forecast for a specific time during the day. As such, you should create an ArrayList
( ArrayList<Lists2> singleDays = new ArrayList<>();
) and add every first instance of a date to singleDays
. In every iteration of your for loop
, check if the openWeatherMapDaysTo.getList().get(j)
object already exists in singleDays
. If it does not exist, then add it to singleDays
.
In order to make this code cleaner, you should override the equals method of your Lists2
class. In the overridden equals
method you check that the date is the same but not the time of day. You can do that by using a SimpleDateFormat
that only includes the yyyy-MM-dd
and do not include the HH:mm:ss
.
public class Lists2 {
...
@Override
boolean equals(Object object) {
if (object == null || !(object instanceof Lists2)) return false;
Lists2 toCheck = (Lists2) object;
String thisDateString = getDt_txt();
String toCheckDateString = toCheck.getDt_txt();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date thisDate = sdf.parse(thisDateString);
Date toCheckDate = sdf.parse(toCheckDateString);
return thisDate.compareTo(toCheckDate) == 0;
}
}
After your for loop
has finished iterating over your data set, then you can create your ForecastAdapters
and assign it to your RecyclerView
.
Change your getFiveDays()
method's second for loop
to this
ArrayList<Lists2> singleDays = new ArrayList<>();
for (int j = 0; j < openWeatherMapDaysTo.getList().size(); j++) {
if (!singleDays.contains(openWeatherMapDaysTo.getList().get(j))) {
singleDays.add(openWeatherMapDaysTo.getList().get(j));
}
}
mForecastAdapters = new ForecastAdapters(getApplicationContext(), singleDays);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mForecastAdapters);
Also, there is no need to call mForecastAdapters.notifyDataSetChanged();
directly after creating the adapter.
You will also need to edit your ForecastsAdapter
to use Lists2
instead of OpenWeatherMapDaysTo
. Where you are binding your data, you are getting the list of Lists2
anyway to populate your views, so you are already actually only using the Lists2
object, but you are going through the list of all the forecasts to get it.
This is all based on the assumptions I have made without seeing the classes called OpenWeatherMapDays
and OpenWeatherMapDaysTo
Have a look at the code in your if
statement.
Log.d(TAG, "===TRUE====: ");
openWeatherMapDaysTo.getList().get(j); // line 1
getmOpenWeatherMapListto.add(openWeatherMapDaysTo); // line 2
On line 1 you are calling get(j)
but not assigning it to anything. I assume that this is the item you want displayed in the RecyclerView
.
On line 2 you are adding the whole openWeatherMapDaysTo
object (which contains the list of days you do not want) to your getmOpenWeatherMapListto
ArrayList
(I assume it is an ArrayList
). So what I think is happening is that even though you are excluding those previous items (based on the compareTo
check), they are being added in with the whole openWeatherMapDaysTo
object.
I think what you want to do is,
getmOpenWeatherMapListto.add(openWeatherMapDaysTo.getList().get(j));
add the single day based on the j
counter (in your example "24 October 2017").
Check the if
statement in your first for loop
as well. You call get(i)
, but do not assign it to anything.
You might also want to add break;
to exit out of the for loop
after the TRUE
code block has executed to prevent your ForecastAdapters
being recreated and set again.
Here is what I think your if
statement in your second for loop
should look like (if I understand what your code and you are trying to accomplish):
if ((finalDate.compareTo(VolleyURL.getDateNumber())!=0)) {
Log.d(TAG, "===TRUE====: ");
getmOpenWeatherMapListto.add(openWeatherMapDaysTo.getList().get(j));
Log.d(TAG, "openWeatherDaysTo SIZE ===> " + getmOpenWeatherMapListto.size());
mForecastAdapters = new ForecastAdapters(getApplicationContext(), getmOpenWeatherMapListto);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mForecastAdapters);
mForecastAdapters.notifyDataSetChanged();
// break out of the for loop here otherwise your adapter will be created
// again and set to your recyclerview
break;
}
I wrote this code in Volley Request and this problem is solved.
for (int j = 0; j < openWeatherMapDaysTo.getList().size(); j++) {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, 0);
String mNowDay = sdf.format(c.getTime());
Date dtNow = null;
Calendar cT = Calendar.getInstance();
cT.add(Calendar.DAY_OF_YEAR, 1);
String mTomorrow = sdf.format(cT.getTime());
Date dtTomorrow = null;
try {
dtNow = sdf.parse(mNowDay);
dtTomorrow = sdf.parse(mTomorrow);
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String finalDate = dateFormat.format(dtNow);
String finalTomorrow = dateFormat.format(dtTomorrow);
Log.d(TAG, "JSON ----------------------->: " + VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()));
Log.d(TAG, "VolleyURL.getDateNumber----------------------->: " + VolleyURL.getDateNumber());
Log.d(TAG, "FINALDATE ---------> : " + finalDate);
Log.d(TAG, "IF IC ---------> : " + VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()));
if (VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()).equals(finalDate + " 12:00")) {
Log.d(TAG, " \n ===TRUE====: ");
openWeatherMapDaysTo.getList().remove(j);
j--;
} else if (VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()).equals(finalDate + " 15:00")) {
Log.d(TAG, " \n ===TRUE====: ");
openWeatherMapDaysTo.getList().remove(j);
j--;
} else if (VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()).equals(finalDate + " 18:00")) {
Log.d(TAG, " \n ===TRUE====: ");
openWeatherMapDaysTo.getList().remove(j);
j--;
} else if (VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()).equals(finalDate + " 21:00")) {
Log.d(TAG, " \n ===TRUE====: ");
openWeatherMapDaysTo.getList().remove(j);
j--;
} else if (VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()).equals(finalTomorrow + " 00:00")) {
Log.d(TAG, " \n ===TRUE====: ");
openWeatherMapDaysTo.getList().remove(j);
j--;
} else if (VolleyURL.unixTimeStampToDateTime(openWeatherMapDaysTo.getList().get(j).getDt()).equals(finalTomorrow + " 03:00")) {
Log.d(TAG, " \n ===TRUE====: ");
openWeatherMapDaysTo.getList().remove(j);
j--;
} else {
Log.d(TAG, " \n ===FALSE====: ");
getmOpenWeatherMapListto.add(openWeatherMapDaysTo);
}
I could not turn the else-if statement to switch-case statement.But it's perfectly working now. If you have a suggestion related to this problem (relevant to the transformation of the statement), I will happy to hear it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.