RecyclerView适配器连接到以前的片段

时间:2015-12-22 15:17:05

标签: android android-fragments android-recyclerview android-adapter android-context

我的Activity Fragment RecyclerView。单击其中一个RecyclerView项目时,会在原始项目的顶部添加新的Fragment并添加到后台堆栈。此新Fragment与之前的layout具有相同的Fragment,并使用相同Adapter的单独实例。按下后退按钮时会出现问题,从堆栈弹出第二个Fragment,再次单击第一个Fragment中的一个项目,应用程序崩溃NullPointerException

12-22 08:50:53.283 20747-20747/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.app, PID: 20747
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.app.ui.activity.MainActivity.revealFragment(android.support.v4.app.Fragment)' on a null object reference
        at com.example.app.ui.fragment.CampusFragment.onItemClickListener(SecondFragment.java:115)
        at com.example.app.ui.adapter.LauncherAdapter$ViewHolder.onClick(LauncherAdapter.java:68)
        at android.view.View.performClick(View.java:4780)
        at android.view.View$PerformClick.run(View.java:19866)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

但第二个onItemClickListener的{​​{1}}被调用,而不是第一个。第二个Fragment不再附加,因此Fragment中的getActivity()生成onItemClickListener,但第二个NullPointerException根本不会被调用。 Fragment个类都有一个Fragment,其设置方式相同:

RecyclerView

为每个人创建一个新的@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main, container, false); mAdapter = new LauncherAdapter(getContext(), mDataSet); mAdapter.setOnItemClickListener(this); GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2); ItemTouchHelper touchHelper = new ItemTouchHelper(onItemTouch()); RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(mAdapter); touchHelper.attachToRecyclerView(recyclerView); return view; }

LauncherAdapter

为什么要调用第二个public class LauncherAdapter extends RecyclerView.Adapter<LauncherAdapter.ViewHolder> implements ItemTouchHelperAdapter { public interface OnItemClickListener { void onItemClickListener(@StringRes int title); } private static OnItemClickListener sListener; private Context mContext; private List<LauncherCard> mDataset; public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private int mId; public ImageView iconView; public TextView titleView; public ViewHolder(View itemView) { super(itemView); iconView = (ImageView) itemView.findViewById(R.id.icon); titleView = (TextView) itemView.findViewById(R.id.title); itemView.setOnClickListener(this); } public void setId(@StringRes int id) { mId = id; } @Override public void onClick(View view) { sListener.onItemClickListener(mId); } } public LauncherAdapter(Context context, List<LauncherCard> dataset) { mContext = context; mDataset = dataset; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.view_card_launcher, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.iconView.setImageResource(mDataset.get(position).getDrawable()); holder.titleView.setText(mDataset.get(position).getId()); holder.setId(mDataset.get(position).getId()); } @Override public int getItemCount() { return mDataset.size(); } @Override public void onItemMove(int fromPosition, int toPosition, String saveLocation) { if (fromPosition < toPosition) { Collections.rotate(mDataset.subList(fromPosition, toPosition + 1), -1); } else { Collections.rotate(mDataset.subList(toPosition, fromPosition + 1), + 1); } notifyItemMoved(fromPosition, toPosition); SharedPreferences.Editor editor = mContext.getSharedPreferences("recycler_positions", Context.MODE_PRIVATE).edit(); editor.putString(saveLocation, new Gson().toJson(mDataset)).apply(); } @Override public void onItemDismiss(int position) { // Not utilized } public void setOnItemClickListener(OnItemClickListener listener) { sListener = listener; } } 的{​​{1}}而不是第一个?{1}}?第二个onItemClickListener的{​​{1}}是否也以某种方式附加到第一个Fragment的{​​{1}}?你能不能在一个LauncherAdapter中有两个相同Fragment的实例?

1 个答案:

答案 0 :(得分:1)

不要将您的侦听器声明为静态。变化

private static OnItemClickListener sListener;

private OnItemClickListener mListener;

您可以通过ViewHolder访问静态。要克服它,请将其传递给构造函数AdapterViewHolder

public LauncherAdapter(Context context, List<LauncherCard> dataset,  OnItemClickListener listener) {
    mContext = context;
    mDataset = dataset;
    mListener = listener;
}

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    private int mId;

    public ImageView iconView;
    public TextView titleView;
    private OnItemClickListener mListener;
    public ViewHolder(View itemView, OnItemClickListener listener) {
        super(itemView)
        mListener = listener; 
    }

并在mListener

中使用onClick