You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView拖拽项被ImageView遮挡,如何使其显示在视图上方?

RecyclerView拖拽项被ImageView遮挡,无法悬浮在上方

我有一个RecyclerView和一个ImageView,需求是将RecyclerView列表中的项拖拽至ImageView上方(后续将实现放置功能)。但当前拖拽的项会被ImageView遮挡,显示在其下方。原本以为默认拖拽行为会让视图悬浮在所有元素上方,无法定位问题所在。

Activity代码片段

private void updateRecycler(RecyclerView myrecyclerview)
{
    RecyclerView r = myrecyclerview;

    itemsAdapter=new skutest_recyclerview_viewadapter(itmlist);

    runOnUiThread(() -> {
        if (r.getLayoutManager()==null)
        {
            r.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        }
        r.setAdapter(itemsAdapter);

        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelperCallback(itemsAdapter));
        itemTouchHelper.attachToRecyclerView(r);

    });
}

ItemTouchHelperAdapter接口

public interface ItemTouchHelperAdapter {

    void onItemMoved(int fromPosition, int toPosition);

    void onItemDropped(int position); // Optional for handling dropped items on image
}

RecyclerView Adapter代码

public class skutest_recyclerview_viewadapter extends RecyclerView.Adapter<skutest_recyclerview_viewadapter.ViewHolder> implements ItemTouchHelperAdapter
{
    RecyclerView mRecyclerView;
    List<cl_sku_info> skulist;

    public skutest_recyclerview_viewadapter(List<cl_sku_info> skulist)
    {
        this.skulist=skulist;

    }

    @NonNull
    @Override
    public skutest_recyclerview_viewadapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
    {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        ItemBinding b = ItemBinding.inflate(inflater, parent, false);
        return new ViewHolder(b);
    }

    @Override
    public void onBindViewHolder(@NonNull skutest_recyclerview_viewadapter.ViewHolder holder, int position)
    {
        holder.setData(skulist.get(position));

    }

    @Override
    public int getItemCount()
    {
        return skulist==null ? 0 : skulist.size();
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView)
    {
        super.onAttachedToRecyclerView(recyclerView);
        mRecyclerView = recyclerView;
    }

    @Override
    public void onItemMoved(int fromPosition, int toPosition)
    {

    }

    @Override
    public void onItemDropped(int position)
    {

    }


    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        private final ItemBinding binding;
        public ViewHolder(ItemBinding binding)
        {
            super(binding.getRoot());
            this.binding=binding;
        }

        public void setData(cl_sku_info clSkuInfo)
        {
            binding.label.setText("*****");//clSkuInfo.getSTOCK_NO());
            binding.image.setImageBitmap(images.getInstance().getimage(clSkuInfo.getSTOCK_NO(),100));
        }

    }

}

ItemTouchHelperCallback代码

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

public class ItemTouchHelperCallback extends ItemTouchHelper.Callback
{
    private final ItemTouchHelperAdapter adapter;

    public ItemTouchHelperCallback(ItemTouchHelperAdapter adapter)
    {
        this.adapter = adapter;
    }


    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder)
    {
        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT;
        final int swipeFlags = 0; // Disable swiping for now
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target)
    {
        adapter.onItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction)
    {

    }
}

布局文件代码

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:weightSum="2"
    android:hardwareAccelerated="false"
    tools:context=".activities.MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/myrecyclerview"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        tools:itemCount="20"
        android:layout_weight="1"
        tools:listitem="@layout/item" />


    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"

        android:background="@drawable/i1"
        android:scaleType="center" />
</LinearLayout>

解决方案

问题原因

ItemTouchHelper默认将拖拽视图添加在RecyclerView的内部层级中,而你的布局里ImageView和RecyclerView是LinearLayout的同级子View,且ImageView在RecyclerView之后声明。根据Android布局的绘制顺序,后声明的View层级更高,会遮挡前面View的内容,包括拖拽视图。

解决方法

方法1:调整布局顺序

将ImageView移到RecyclerView之前声明,这样RecyclerView的层级更高,拖拽视图就不会被遮挡:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:weightSum="2"
    android:hardwareAccelerated="false"
    tools:context=".activities.MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@drawable/i1"
        android:scaleType="center" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/myrecyclerview"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        tools:itemCount="20"
        android:layout_weight="1"
        tools:listitem="@layout/item" />
</LinearLayout>

方法2:设置RecyclerView的Z轴层级

通过给RecyclerView设置更高的translationZ,让它的内容(包括拖拽视图)悬浮在ImageView上方:

  • 在布局中添加属性:
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/myrecyclerview"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    tools:itemCount="20"
    android:layout_weight="1"
    android:translationZ="2dp"
    tools:listitem="@layout/item" />
  • 或者在代码中设置:
myrecyclerview.setTranslationZ(2f);

方法3:自定义拖拽视图层级(进阶)

重写ItemTouchHelperCallback的onChildDraw方法,手动提升拖拽视图的Z轴层级:

@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    // 给拖拽中的item设置更高的Z轴,确保悬浮
    viewHolder.itemView.setTranslationZ(10f);
}

@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
    super.clearView(recyclerView, viewHolder);
    // 拖拽结束后恢复Z轴
    viewHolder.itemView.setTranslationZ(0f);
}

后续放置功能提示

如果要实现拖拽到ImageView上的放置逻辑,需要监听拖拽的位置,通过getGlobalVisibleRect获取ImageView的屏幕坐标范围,判断拖拽视图的位置是否在该范围内,然后在onItemDropped或clearView中处理放置逻辑。


内容的提问来源于stack exchange,提问作者blm99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:06:03