在我的recyclerview中获取错误索引超出绑定的异常

时间:2017-12-25 14:14:11

标签: java android android-recyclerview indexoutofboundsexception recycler-adapter

我试图从主列表中获取收藏列表中最喜欢的项目。当我点击主列表中的收藏夹图标时,收藏家会更新,但是当我从favouritelel中移除任何收藏并尝试从主列表中添加更多收藏夹时我得到错误索引超出绑定异常

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();
            }


        }
    }

适配器

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;
    }
}

这是我遇到的错误

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)

2 个答案:

答案 0 :(得分:2)

听众的问题。您正在为MainActivity recylerview&amp; amp;最喜欢的活动recylerview。从最喜欢的活动回到Mainactivity后,您的听众仍然会从收藏的活动中读取。 这就是问题。

<强>解决方案

在SharedPreference类中创建静态字段以保存侦听器值:

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*/
...
}

将此代码添加到MainActivity&amp;最喜欢的活动&#39; OnCreate&#39;方法

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);
    ....
 }

更改适配器&#39; OnClick方法&#39;到

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

最后改变MainActivity&#39; resume&#39;方法

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

}

希望它有所帮助。!

答案 1 :(得分:0)

DiseaseAdapterViewHolder中将onclick方法更改为

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