简体   繁体   中英

Getting error index out of bound exception in my recyclerview

I'm trying to get favourite items in favourite list from main list.When i click on favourite icon in mainlist, favouritelist get updating but when i remove any favourite from favouritelist and trying to add more favourites from mainlist i get error index out of bound exception

MainActivity

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity implements RecyclerViewClickListener{
    RecyclerView simpleListView;
    static Context ctx;
    String diseaseList[];

    SharedPreference sharedPreference;

    DiseaseAdapter da;
    List<String> newDiseaseList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ctx=this;

        sharedPreference = new SharedPreference();

        diseaseList= new String[]{"Abscess",
                "Allergies",
                "Amnesia",
                "Anemia",
                "Andropause",
                "Angina",
                "Weight Loss"};


        Arrays.sort(diseaseList);





        newDiseaseList = Arrays.asList(diseaseList);

        simpleListView= (RecyclerView)findViewById(R.id.simpleListView);
        LinearLayoutManager lm=new LinearLayoutManager(MainActivity.this);
        simpleListView.setLayoutManager(lm);
       /* DividerItemDecoration di=new DividerItemDecoration(MainActivity.this,lm.getOrientation());
        simpleListView.addItemDecoration(di);*/

        da=new DiseaseAdapter(newDiseaseList,ctx,this);
        simpleListView.setAdapter(da);
        simpleListView.setHasFixedSize(true);



    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_favorites:
                Intent i=new Intent(this,Favourite.class);
           this.startActivity(i);

                return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    protected void onResume() {
        super.onResume();
        da.notifyDataSetChanged();
    }

    @Override
    public void recyclerViewListClicked(View view, int position) {


        ImageView button = (ImageView) view.findViewById(R.id.imgbtn_favorite);

        String tag = button.getTag().toString();
        if (tag.equalsIgnoreCase("grey")) {
            sharedPreference.addFavorite(ctx, newDiseaseList.get(position));
            Toast.makeText(ctx,
                    "add to favourites",
                    Toast.LENGTH_SHORT).show();

            button.setTag("red");
            button.setImageResource(R.drawable.star_colour);
        } else {
            sharedPreference.removeFavorite(ctx, newDiseaseList.get(position));
            button.setTag("grey");
            button.setImageResource(R.drawable.ic_action_name);
            Toast.makeText(ctx,
                    "removed from favourites",
                    Toast.LENGTH_SHORT).show();
        }

    }
}

Favourite.java

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.Collections;
import java.util.List;

public class Favourite extends AppCompatActivity implements RecyclerViewClickListener {
    RecyclerView favoriteList;
    SharedPreference sharedPreference;
    List<String> favorites;
    DiseaseAdapter diseaseAdapter;

   static Context ctx;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_favourite);
        ctx=this;
        sharedPreference = new SharedPreference();
        favorites = sharedPreference.getFavorites(ctx);

        Collections.sort(favorites);
        favoriteList = (RecyclerView)findViewById(R.id.favListView);
        LinearLayoutManager lm=new LinearLayoutManager(ctx);
        favoriteList.setLayoutManager(lm);
        favoriteList.setHasFixedSize(true);

        if (favorites == null) {
            showAlert(getResources().getString(R.string.no_favorites_items),
                    getResources().getString(R.string.no_favorites_msg));
        } else {

            if (favorites.size() == 0) {
                showAlert(
                        getResources().getString(R.string.no_favorites_items),
                        getResources().getString(R.string.no_favorites_msg));
            }


            if (favorites != null) {

                diseaseAdapter = new DiseaseAdapter(favorites,ctx,this);

                favoriteList.setAdapter(diseaseAdapter);



            }
        }

    }

    public void showAlert(String title, String message) {
        if (ctx != null) {
            AlertDialog alertDialog = new AlertDialog.Builder(ctx)
                    .create();
            alertDialog.setTitle(title);
            alertDialog.setMessage(message);
            alertDialog.setCancelable(false);

            // setting OK Button
            alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK",
                    new DialogInterface.OnClickListener() {

                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            // activity.finish();
                            getFragmentManager().popBackStackImmediate();
                        }
                    });
            alertDialog.show();
        }
    }

    @Override
    public void recyclerViewListClicked(View view, int position) {
            ImageView button = (ImageView) view
                    .findViewById(R.id.imgbtn_favorite);

            String tag = button.getTag().toString();
            if (tag.equalsIgnoreCase("grey")) {
                sharedPreference.addFavorite(ctx,
                        favorites.get(position));
                Toast.makeText(
                        ctx,
                        ctx.getResources().getString(
                                R.string.add_favr),
                        Toast.LENGTH_SHORT).show();

                button.setTag("red");
                button.setImageResource(R.drawable.star_colour);
            } else {
                sharedPreference.removeFavorite(ctx,
                        favorites.get(position));
                button.setTag("grey");
                button.setImageResource(R.drawable.ic_action_name);
                                 /*   diseaseAdapter.remove(favorites
                                            .get(position));*/
                diseaseAdapter.remove(position);

                Toast.makeText(
                        ctx,
                        ctx.getResources().getString(
                                R.string.remove_favr),
                        Toast.LENGTH_SHORT).show();
            }


        }
    }

Adapter

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by admin on 12/4/2017.
 */

public class DiseaseAdapter extends RecyclerView.Adapter<DiseaseAdapter.DiseaseAdapterViewHolder> {
    List <String> data;
    Context ctx;
    private static RecyclerViewClickListener itemListener;


    SharedPreference sharedPreference;

    DiseaseAdapter(List <String> data, Context ctx, RecyclerViewClickListener itemListener){
        this.data=data;
        this.ctx=ctx;
        sharedPreference = new SharedPreference();
        this.itemListener = itemListener;
        notifyDataSetChanged();

    }


    @Override
    public DiseaseAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater=LayoutInflater.from(parent.getContext());
        View view= inflater.inflate(R.layout.activity_listview,parent,false);

        return new DiseaseAdapterViewHolder(view);
    }

    @Override
    public void onBindViewHolder(DiseaseAdapterViewHolder holder, int position) {
        final String title=data.get(position);
        holder.textView1.setText(title);

        if (checkFavoriteItem(title)) {

            holder.imageButton.setImageResource(R.drawable.star_colour);
            holder.imageButton.setTag("red");
        } else {

            holder.imageButton.setImageResource(R.drawable.ic_action_name);
            holder.imageButton.setTag("grey");
        }

    }


    @Override
    public int getItemCount() {
        return data.size();
    }


    class  DiseaseAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        TextView textView1;
        ImageView imageButton;

        public  DiseaseAdapterViewHolder(View itemView) {
            super(itemView);

            textView1=(TextView) itemView.findViewById(R.id.textView);
            imageButton=(ImageView)itemView.findViewById(R.id.imgbtn_favorite);
            imageButton.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {
            notifyDataSetChanged();
            itemListener.recyclerViewListClicked(v, this.getLayoutPosition());
        }
    }

    /*Checks whether a particular product exists in SharedPreferences*/
    public boolean checkFavoriteItem(String checkProduct) {
        boolean check = false;
        List<String> favorites = sharedPreference.getFavorites(ctx);
        if (favorites != null) {
            for (String product : favorites) {
                if (product.equals(checkProduct)) {
                    check = true;
                    break;
                }
            }
        }
        return check;
    }


    public void add(String product) {

        data.add(product);
        notifyDataSetChanged();
    }


    public void remove(int  position) {

        data.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, data.size());
        notifyDataSetChanged();
    }

}

SharedPreference

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

import com.google.gson.Gson;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class SharedPreference {

    public static final String PREFS_NAME = "PRODUCT_APP";
    public static final String FAVORITES = "Product_Favorite";

    public SharedPreference() {
        super();
    }

    // This four methods are used for maintaining favorites.
    public void saveFavorites(Context context, List<String> favorites) {
        SharedPreferences settings;
        Editor editor;

        settings = context.getSharedPreferences(PREFS_NAME,
                Context.MODE_PRIVATE);
        editor = settings.edit();

        Gson gson = new Gson();
        String jsonFavorites = gson.toJson(favorites);

        editor.putString(FAVORITES, jsonFavorites);

        editor.commit();
    }

    public void addFavorite(Context context, String product) {
        List<String> favorites = getFavorites(context);
        if (favorites == null)
            favorites = new ArrayList<String>();
        favorites.add(product);
        saveFavorites(context, favorites);
    }

    public void removeFavorite(Context context, String product) {
        List<String> favorites = getFavorites(context);
        if (favorites != null) {
            favorites.remove(product);
            saveFavorites(context, favorites);
        }
    }

    public ArrayList<String> getFavorites(Context context) {
        SharedPreferences settings;
        List<String> favorites ;

        settings = context.getSharedPreferences(PREFS_NAME,
                Context.MODE_PRIVATE);

        if (settings.contains(FAVORITES)) {
            String jsonFavorites = settings.getString(FAVORITES, null);
            Gson gson = new Gson();
            String [] favoriteItems = (gson.fromJson(jsonFavorites,String [].class));

            favorites = Arrays.asList(favoriteItems);
            favorites = new ArrayList<String>(favorites);
        } else
            return null;

        return (ArrayList<String>) favorites;
    }
}

This is an error that i'm getting

FATAL EXCEPTION: main
 Process: com.example.admin.fav, PID: 10974
java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.example.admin.fav.Favourite.recyclerViewListClicked(Favourite.java:145)
at com.example.admin.fav.DiseaseAdapter$DiseaseAdapterViewHolder.onClick(DiseaseAdapter.java:90)
at android.view.View.performClick(View.java:5207)
at android.view.View$PerformClick.run(View.java:21168)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

Problem in your listener. You are using same adapter class for both MainActivity recylerview & Favourite activity recylerview. After you go back from favourite activity to Mainactivity still your listener read from Favourite activity. Thats the issue.

Solution

Create Static field to hold listener value here am created in SharedPreference Class:

public class SharedPreference {

public static final String PREFS_NAME = "PRODUCT_APP";
public static final String FAVORITES = "Product_Favorite";
/*Added*/
private static RecyclerViewClickListener listener;

public RecyclerViewClickListener getListener() {
    return listener;
}

public void setListener(RecyclerViewClickListener listener) {
    SharedPreference.listener = listener;
}

/*Added*/
...
}

Add this code to MainActivity & Favourite Activity 'OnCreate' method

sharedPreference.setListener(this);

public class MainActivity extends AppCompatActivity implements RecyclerViewClickListener{
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sharedPreference.setListener(this);
    ....
 }


public class Favourite extends AppCompatActivity implements RecyclerViewClickListener{
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_favourite);
    sharedPreference.setListener(this);
    ....
 }

Change Adapter 'OnClick method' to

@Override
public void onClick(View v) {
    notifyDataSetChanged();
    itemListener = sharedPreference.getListener();
    itemListener.recyclerViewListClicked(v, this.getLayoutPosition());
}

And Finally change in MainActivity 'resume' method

@Override
protected void onResume() {
    super.onResume();
    sharedPreference.setListener(this);
    da.notifyDataSetChanged();

}

Hope it helps.!

In your DiseaseAdapterViewHolder change the onclick methode to,

@Override
public void onClick(View v) {
    itemListener.recyclerViewListClicked(v, this.getLayoutPosition());
    notifyDataSetChanged();
}

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