简体   繁体   中英

How to remove desired item from recyclerview adapter without Clicked ? or from List

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

手机视图

Edit 1:

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.


Original answer

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM