在RecyclerView项目中替换片段

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在RecyclerView项目中替换片段相关的知识,希望对你有一定的参考价值。

在我的RecyclerView中,我需要将部分项目替换为我的片段。但只替换回收站视图中的第一项。我在做什么是错的?

我的容器(在回收商视图项目中):

...
<FrameLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/container" />
...

我在RecyclerView适配器中的更新代码:

...
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

...

MyFragment fragment = MyFragment.newInstance("fragment1");
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();

...

}
...
答案

我终于找到了解决方案问题是我设置了一个普通的容器ID。但是在recyclerview中需要为每个项目设置唯一的容器ID。

所以,我的代码现在这样:

MyFragment fragment = MyFragment.newInstance("fragment1");
fragmentManager.beginTransaction().replace(unique_id_here, fragment).commit();

如果有人会有用,这是我的完整代码(recyclerview中的实现片段):

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) 
{

...

// Delete old fragment
int containerId = holder.mediaContainer.getId();// Get container id
Fragment oldFragment = fragmentManager.findFragmentById(containerId);
if(oldFragment != null) {
    fragmentManager.beginTransaction().remove(oldFragment).commit();
}

int newContainerId = GetUniqueID();// My method
holder.mediaContainer.setId(newContainerId);// Set container id

// Add new fragment
MyFragment fragment = MyFragment.newInstance("fragment1");
fragmentManager.beginTransaction().replace(newContainerId, fragment).commit();

...

}
另一答案

感谢Mikhali,我能够为您提供一个完整的运行示例。特别注意onBindViewHolder()中的注释

    public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewLedgerAdapter.ViewHolder>{
        private final String TAG = RecyclerViewAdapter.class.getSimpleName();

        private final float FINAL_OPACITY = 0.3f;
        private final float START_OPACITY = 1f;

        private final int ANIMATION_TIME = 500;
        private final int TYPE_ITEM = 0;
        private final int TYPE_DATE = 1;
        private final int TYPE_TRANSACTION = 2;
        private final int TYPE_PENDING = 3;

        private HashMap<Integer, Integer> mElementTypes;
        private List<Operation> mObjects;
        private Context mContext;
        private Utils.CURRENCIES mCurrencySelected; // Which currency is already selected
        private boolean mCurrencyFilter; // Defines if a currency is already selected to apply filter
        private Animation mAnimationUp;
        private Animation mAnimationDown;

        public RecyclerViewLedgerAdapter(List<Operation> objects, Context context) {
            mElementTypes = new HashMap<Integer, Integer>();
            mObjects = objects;
            mContext = context;
            mCurrencyFilter = false;
            mCurrencySelected = null;
            mAnimationUp = AnimationUtils.loadAnimation(context, R.anim.slide_up);
            mAnimationDown = AnimationUtils.loadAnimation(context, R.anim.slide_down);
        }

        ...
        ...
            Not needed methods
        ...
        ...

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_element_ledger, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            Operation operation = mObjects.get(position);
            holder.setAppUserActivity(userActivityOperation);

            // Remember that RecyclerView does not have onClickListener, you should implement it
            holder.getView().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Hide details
                    // iDetailsContainer object could be checked on inner class ViewHolder
                    if(holder.iDetailsContainer.isShown()){
                        holder.iDetailsContainer.setVisibility(View.GONE);
                    }else{
                        // Show details
                        // Get fragment manager inside our fragment
                        FragmentManager fragmentManager = ((UserActivity)mContext).getSupportFragmentManager();

                        // Delete previous added fragment
                        int currentContainerId = holder.iDetailsContainer.getId();
                        // Get the current fragment
                        Fragment oldFragment = fragmentManager.findFragmentById(currentContainerId);
                        if(oldFragment != null) {
                            // Delete fragmet from ui, do not forget commit() otherwise no action
                            // is going to be observed
                            ragmentManager.beginTransaction().remove(oldFragment).commit();
                        }

                        // In order to be able of replacing a fragment on a recycler view
                        // the target container should always have a different id ALWAYS
                        int newContainerId = getUniqueId();
                        // Set the new Id to our know fragment container
                        holder.iDetailsContainer.setId(newContainerId);

                        // Just for Testing we are going to create a new fragment according
                        // if the view position is pair one fragment type is created, if not
                        // a different one is used
                        Fragment f;
                        if(position%2 == 0) {
                            f = new FragmentCard();
                        }else{
                            f=new FragmentChat();
                        }

                        // Then just replace the recycler view fragment as usually
                        manager.beginTransaction().replace(newContainerId, f).commit();

                        // Once all fragment replacement is done we can show the hidden container
                        holder.iDetailsContainer.setVisibility(View.VISIBLE);
                    }
                }

                // Method that could us an unique id
                public int getUniqueId(){
                    return (int)SystemClock.currentThreadTimeMillis();
                }
            });
        }


        public class ViewHolder extends RecyclerView.ViewHolder{
            private View iView;
            private LinearLayout iContainer;
            public LinearLayout iDetailsContainer;
            private ImageView iOperationIcon;
            private ImageView iOperationActionImage;
            private TextView iOperation;
            private TextView iAmount;
            private TextView iTimestamp;
            private TextView iStatus;

            private UserActivityOperation mUserActivityOperation;

            public ViewHolder(View itemView) {
                super(itemView);
                iView = itemView;
                iContainer = (LinearLayout) iView.findViewById(R.id.operation_container);
                iDetailsContainer = (LinearLayout) iView.findViewById(R.id.details_container);
                iOperationIcon = (ImageView) iView.findViewById(R.id.ledgerOperationIcon);
                iOperationActionImage = (ImageView) iView.findViewById(R.id.ledgerAction);
                iOperation = (TextView) iView.findViewById(R.id.ledgerOperationDescription);
                iAmount = (TextView) iView.findViewById(R.id.ledgerOperationCurrencyAmount);
                iTimestamp = (TextView) iView.findViewById(R.id.ledgerOperationTimestamp);
                iStatus = (TextView) iView.findViewById(R.id.ledgerOperationStatus);

                // This linear layout status is GONE in order to avoid the view to use space
                // even when it is not seen, when any element selected the Adapter will manage the
                // behavior for showing the layout - container
                iDetailsContainer.setVisibility(View.GONE);
            }

            ...
            ...
                Not needed methods
            ...
            ...
        }
    }

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/operation_container_maximum"
    android:layout_width="match_parent"

以上是关于在RecyclerView项目中替换片段的主要内容,如果未能解决你的问题,请参考以下文章

从片段类中的对话框添加项目到recyclerview。

如何在recyclerview不同的项目点击上打开几个不同的片段?

如何在单击 RecyclerView 项目时从一个片段移动到另一个片段

如何在recyclerview中获取所选项目,何时在片段内?

从其他片段添加新的 RecyclerView 项

从片段中获取意图值后,我如何在 recyclerview 项目中实现单击