简体   繁体   中英

Relative layout cannot be cast to RecyclerView

I am passing through a RelativeLayout from a RecyclerViewAdapter into the main activity and change its layout parameters. The user drags an item from RecyclerView and then drops it anywhere on the screen.

Now the drag and drop work if I set the item to a bitmap image object and then move that object because it just copies the layout and turns it into the bitmap and it is part of the same view.

But then I have to create multiple images for every item etc and this is not a good idea. So I want to let the user drag from RV to another layout in the same activity.

But the problem is, when I pass through the layout from the adapter and try to set its parameters, I can the following error message:

android.widget.RelativeLayout$LayoutParams cannot be cast to android.support.v7.widget.RecyclerView$LayoutParams

When I rang the debugger, I can't see the RV being passed, it does say it is passing through the relative layout. But checking the error message I did see the following:

              at android.support.v7.widget.RecyclerView.getChildViewHolderInt(RecyclerView.java:4375)
              at android.support.v7.widget.RecyclerView.findMinMaxChildLayoutPositions(RecyclerView.java:3868)
              at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3604)
              at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3408)

Within the debugger, I checked the passed layout and its parent is the RecyclerView.

I am trying to pass through the layout, as its own relative layout without its parent RV.

Here is the code:

public FootballPitchMainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.player_name_and_top_scheme,
                parent,false);
        FootballPitchMainAdapter.ViewHolder vh = new FootballPitchMainAdapter.ViewHolder(v);
        return vh;

   holder.linearLayoutFull.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                if (event.getAction() == DragEvent.ACTION_DRAG_STARTED){
                    FootballPitchMain.passHolder(holder.linearLayoutFull);
                } else if (event.getAction() ==   DragEvent.ACTION_DRAG_ENDED)
                    v.setVisibility(View.VISIBLE);

                return true;
            }
        });


   public static void passHolder(RelativeLayout mViewHolder){
            viewHolder =  mViewHolder;
}



        @Override
        public boolean onDrag(View v, DragEvent event) {
            if (event.getAction() ==   DragEvent.ACTION_DROP){

                int x_cord = (int) event.getX();
                int  y_cord = (int) event.getY();
                layoutParams.leftMargin = x_cord;
                layoutParams.topMargin = y_cord;
                RelativeLayout.LayoutParams rLay = new RelativeLayout.LayoutParams(viewHolder.getWidth(),viewHolder.getHeight());
                rLay.leftMargin = x_cord;
                rLay.topMargin = y_cord;
                viewHolder.setLayoutParams(rLay);
            }
            return true;
        }

@viewHolder.setLayoutParams(rLay) is where it breaks.

If I am reading your code correctly, the view that you are moving has RecyclerView as a parent. If that is so, the layout parameters for the view would be layout parameters for RecyclerView even though the view may be RelativeLayout .

In any case, even if you work this issue out, I think you may find that there are other issues with stealing a view from the RecyclerView .

I suggest that when the view is dropped that you create a new view that is a clone of the view that you are dropping and add that view to the new ViewGroup that is receiving the view. You will have to remove the item from the RecyclerView and clean up the visuals, but I think that this will be your best approach.

btw, I have noticed some general interest on Stack Overflow regarding this topic of dragging views outside of a RecyclerView . When you get it working, it may be worth posting the solution back here.

The way I had to fix this, was to create a bitmap image when the drag started in the adapter. Pass the bitmap to where ever you want, create a new ImageView once passed through, set the Bitmap to the ImageView and then have the dragListener set to the layout where you intend to have a drop. So I have not been able to pass through the layout without having to convert it into something else first.

The answer isn't the best IMO but to be honest it is a quick fix for this issue.

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