【问题标题】:RecyclerView long tap drag to reorder wobble effectRecyclerView 长按拖动以重新排序摆动效果
【发布时间】:2018-02-14 15:24:47
【问题描述】:

当使用 GridLayoutManager 长按 RecyclerView 中的项目并拖动以重新排序时,如何实现类似this 的摆动效果,效果很好。并且当丢弃该项目时,效果应该停止。

这是我的适配器类

public class ClassGridAdapter extends RecyclerView.Adapter<ClusterGridAdapter.ViewHolder> implements ItemTouchHelperCluster {
private ArrayList<Class> mClassList = new ArrayList<>();
private Context mContext;

public ClassGridAdapter(Context context, ArrayList<Class> mClusters) {
    this.mClassList = mClusters;
    this.mContext = context;
}

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

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.mClusterName.setText(mClassList.get(position).getName());
    holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            mDragStartListener.onStartDrag(holder);
            return true;
        }
    });
}

@Override
public int getItemCount() {
    return mClusters.size();
}

@Override
public boolean onItemMove(int fromPosition, int toPosition) {
    Collections.swap(mClassList, fromPosition, toPosition);
    notifyItemMoved(fromPosition, toPosition);
    return true;
}

class ViewHolder extends RecyclerView.ViewHolder {
    TextView mClusterName;
    public ViewHolder(View itemView) {
        super(itemView);
        mClusterName = (TextView) itemView.findViewById(R.id.tv_cluster);
    }
}

}

【问题讨论】:

    标签: android animation android-recyclerview drag-and-drop android-animation


    【解决方案1】:

    在@Cheticamp 的帮助下通过以下代码设法修复它。

    ClassGridAdapter.java

    public class ClassGridAdapter extends RecyclerView.Adapter<ClusterGridAdapter.ViewHolder> implements ItemTouchHelperCluster {
    private ArrayList<Class> mClassList = new ArrayList<>();
    private Context mContext;
    boolean isAnimate = false;
    Animation animation;
    
    public ClassGridAdapter(Context context, ArrayList<Class> mClusters) {
        this.mClassList = mClusters;
        this.mContext = context;
        animation = AnimationUtils.loadAnimation(mContext, R.anim.wobble);
        setHasStableIds(true);
    }
    
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.grid_item, parent, false);
        return new ViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.mClusterName.setText(mClassList.get(position).getName());
        if (isAnimate)
            holder.itemView.startAnimation(animation);
        else
            holder.itemView.clearAnimation();
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                mDragStartListener.onStartDrag(holder);
                isAnimate = true;
                notifyDataSetChanged();
                return true;
            }
        });
    }
    
    @Override
    public int getItemCount() {
        return mClusters.size();
    }
    
    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        Collections.swap(mClassList, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }
    
    @Override
    public void onItemRelease() {
        isAnimate = false;
        notifyDataSetChanged();
    }
    
    class ViewHolder extends RecyclerView.ViewHolder {
        TextView mClusterName;
        public ViewHolder(View itemView) {
            super(itemView);
            mClusterName = (TextView) itemView.findViewById(R.id.tv_cluster);
        }
    }
    

    }

    wobble.xml

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fromDegrees="-5"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toDegrees="5" />
    

    SimpleItemTouchHelperCallback.java

    public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
    
    public static final float ALPHA_FULL = 1.0f;
    
    private final ItemTouchHelperCluster mAdapter;
    
    public SimpleItemTouchHelperCallback(ItemTouchHelperCluster adapter) {
        mAdapter = adapter;
    }
    
    @Override
    public boolean isLongPressDragEnabled() {
        return false;
    }
    
    @Override
    public boolean isItemViewSwipeEnabled() {
        return false;
    }
    
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        // Set movement flags based on the layout manager
        if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
            final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            final int swipeFlags = 0;
            return makeMovementFlags(dragFlags, swipeFlags);
        } else {
            final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
            return makeMovementFlags(dragFlags, swipeFlags);
        }
    }
    
    @Override
    public boolean onMove(RecyclerView recyclerView, 
     RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
        System.out.println("SimpleItemTouchHelperCallback.onMove");
        if (source.getItemViewType() != target.getItemViewType()) {
            return false;
        }
    
        // Notify the adapter of the move
        mAdapter.onItemMove(source.getAdapterPosition(), 
    target.getAdapterPosition());
        return true;
    }
    
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
        System.out.println("SimpleItemTouchHelperCallback.onSwiped");
        // Notify the adapter of the dismissal
        //        mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
    }
    
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            // Fade out the view as it is swiped out of the parent's bounds
            final float alpha = ALPHA_FULL - Math.abs(dX) / (float) v . 
     iewHolder.itemView.getWidth();
            viewHolder.itemView.setAlpha(alpha);
            viewHolder.itemView.setTranslationX(dX);
        } else {
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, 
     actionState, isCurrentlyActive);
        }
    }
    
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int 
    actionState) {
        // We only want the active item to change
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            if (viewHolder instanceof ItemTouchHelperViewHolder) {
                // Let the view holder know that this item is being moved 
     or dragged
                ItemTouchHelperViewHolder itemViewHolder = 
     (ItemTouchHelperViewHolder) viewHolder;
                itemViewHolder.onItemSelected();
            }
        }
    
        super.onSelectedChanged(viewHolder, actionState);
    }
    
    @Override
    public void clearView(RecyclerView recyclerView, 
    RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        System.out.println("SimpleItemTouchHelperCallback.clearView");
        viewHolder.itemView.setAlpha(ALPHA_FULL);
        mAdapter.onItemRelease();
        if (viewHolder instanceof ItemTouchHelperViewHolder) {
            // Tell the view holder it's time to restore the idle state
            ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
            itemViewHolder.onItemClear();
        }
    }
    }
    

    【讨论】:

    • 什么是ItemTouchHelperCluster?无处可见
    【解决方案2】:

    从this answer 借用动画到 Stack Overflow 上的一个类似问题,这是如何使包含四个图像视图的画廊摆动,如本视频所示:

    此解决方案使用View Animation。

    对于演示,图像视图会根据此动画文件振动:

    wobble.xml

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="100"
        android:fromDegrees="-5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toDegrees="5" />
    

    这里是主要活动。摇晃立即开始,五秒钟后停止。您停止的触发器将是视图的删除。

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.wobble_gallery);
            final int[] ids = new int[]{R.id.imageView1, R.id.imageView2, R.id.imageView3, R.id.imageView4};
    
            Animation animation = AnimationUtils.loadAnimation(this, R.anim.wobble);
            for (int id : ids) {
                ImageView imageView = (ImageView) findViewById(id);
                imageView.startAnimation(animation);
            }
            findViewById(R.id.imageView1).postDelayed(new Runnable() {
                @Override
                public void run() {
                    for (int id : ids) {
                        ImageView imageView = (ImageView) findViewById(id);
                        imageView.clearAnimation();
                    }
                }
            }, 5000);
        }
    }
    

    最后是布局文件。

    wobble_gallery.xml

    <GridLayout 
        android:layout_width="match_parent"
        android:layout_gravity="center"
        android:layout_height="match_parent"
        android:columnCount="2">
    
        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="75dp"
            android:layout_height="75dp"
            android:layout_margin="16dp"
            app:srcCompat="@android:drawable/btn_star_big_on" />
    
        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="75dp"
            android:layout_height="75dp"
            android:layout_margin="16dp"
            app:srcCompat="@drawable/linear_gradient" />
    
        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="75dp"
            android:layout_height="75dp"
            android:layout_margin="16dp"
            app:srcCompat="@mipmap/ic_launcher_round" />
    
        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="75dp"
            android:layout_height="75dp"
            android:layout_margin="16dp"
            app:srcCompat="@drawable/dog_image" />
    </GridLayout>
    

    【讨论】:

    • 在recyclerview中怎么样
    • 那不在recyclerview中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多