【问题标题】:Pass Object from one fragment to another fragment when recyclerView item is clicked单击 recyclerView 项时将对象从一个片段传递到另一个片段
【发布时间】:2018-12-26 03:36:01
【问题描述】:

我的 MainActivity 包含 4 个片段。所有片段都是回收者视图,但 3 有一个细节片段。我有下面的类来实现回收器视图点击监听器。

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);    
        public void onLongItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && mListener != null) {
                    mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
                }
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
            return true;
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {}

    @Override
    public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}

在我的系列片段中,我是这样实现的

recyclerView.addOnItemTouchListener(
    new RecyclerItemClickListener(getContext(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            mListener.onSeriesSelected(series, position);
            Series series = seriesList.get(position);
            Toast.makeText(getContext(), series.getTitle() + " " + series.getId() + " is selected!", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onLongItemClick(View view, int position) {}
}));

现在,我想在单击 recyclerView 时打开一个 SeriesDetail 片段,并将该回收器视图的 Series 对象传递给 SeriesDetail 片段。

我了解到,Series 模型必须实现 Parcelable,这是我在 IntelliJ 插件的帮助下完成的,并且我需要在 Series 片段中实现一个接口。

public interface onSeriesSelectedListener {
    void onSeriesSelected(Series series, int position);
}

并覆盖我喜欢的片段中的 onAttach 方法

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    // This makes sure that the container activity has implemented
    // the listener interface. If not, it throws an exception
    if (context instanceof onSeriesSelectedListener) {
        mListener = (onSeriesSelectedListener) context;
    } else {
        throw new ClassCastException(context.toString()
 + " must implement onSeriesSelectedListener");
    }
}

最后,覆盖我喜欢的 MainActivity 中的界面

@Override
public void onSeriesSelected(Series series, int position) {
    Fragment fragment = new SeriesDetailFragment();
    Bundle bundle = new Bundle();
    fragment.setArguments(bundle);
    bundle.putParcelable("seriesDetail", series);
    fragment.setArguments(bundle);
    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.fragment_container, fragment)
        .addToBackStack(null)
        .commit();
}

现在在 SeriesDetail 片段的 onCreate 方法中,我应该像这样访问 Parcelable 对象

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle bundle = this.getArguments();
    if (bundle != null) {
        Series series = bundle.getParcelable("seriesDetail");
        if (series != null) {
            Toast.makeText(getContext(), series.getTitle() + " is selected!", Toast.LENGTH_LONG).show();
            Log.e("Series", "Title:" + series.getTitle());
        }
    }
}

然而,此时我没有得到对象。我做错了什么?请帮我!!!我已经在这几个小时了。谢谢

【问题讨论】:

  • 在你的代码中加入一些Log,看看你的命令链能走多远。是否到达onSeriesSelected?顺便说一句,在该方法中,您调用 setArguments 两次 - 一次在它获取数据之前和一次之后。不过,这不是您的问题的原因。
  • 我认为使用Bundle 进行活动片段通信有点过头了(尽管您的代码来自developer.android.com)。由于您的活动具有对片段的引用并且您的片段具有context,因此您可以直接调用。但是,我可以确认您的方法有效。因此,问题是您的 touchListeners 或您的 parcelization 是否有问题。使用我第一条评论中的Log 方法来找出答案。

标签: android android-fragments parcelable


【解决方案1】:
    recyclerView.addOnItemTouchListener (new RecyclerItemClickListener(getContext(), 
     recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        Series series = seriesList.get(position);  
        mListener.onSeriesSelected(series, position);                      
    }

    @Override
    public void onLongItemClick(View view, int position) {}
    }));

侦听器在获取系列位置之前触发,从而使 MainActivity 中的系列为空。感谢您的帮助。

【讨论】:

    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 2016-06-12
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多