Android 回收视图拖放和;快速拖动时通过itemTouchHelper拖放
我一直在遵循这个链接的指南,在某些情况下我遇到了一些问题 所以,我基本上做了他解释的所有事情+我在item中添加了一个TextView,它表示一个项目在RecyclerView中的位置,类似这样: 一切看起来都很好,除了当我快速开始“吊带射击”物品时,我有两个问题:Android 回收视图拖放和;快速拖动时通过itemTouchHelper拖放,android,drag-and-drop,android-recyclerview,Android,Drag And Drop,Android Recyclerview,我一直在遵循这个链接的指南,在某些情况下我遇到了一些问题 所以,我基本上做了他解释的所有事情+我在item中添加了一个TextView,它表示一个项目在RecyclerView中的位置,类似这样: 一切看起来都很好,除了当我快速开始“吊带射击”物品时,我有两个问题: 它恰好有一个数字的副本。 我所做的还包括在 onItemClear()方法-它以某种方式修复了它,但导致 非法状态异常,被捕获-将导致 索引自动边界异常 局部地,当刷得太快时,物品进入“背景”。只有当项目大小不同时,才能看到这一
onItemClear()
方法-它以某种方式修复了它,但导致
非法状态异常
,被捕获-将导致
索引自动边界
异常LayoutInflater inflater;
Context context;
AndroidEntityQuestionResult androidEntityQuestionResult;
ArrayList<AndroidEntityAnswer> list = new ArrayList<>();
ORDLayoutManagerQuestion ord;
ScreenDimensionsConstants sdc;
public OrderingRecycleAdapter(Context context, AndroidEntityQuestionResult androidEntityQuestionResult, ORDLayoutManagerQuestion ord) {
inflater = LayoutInflater.from(context);
this.context = context;
this.list = androidEntityQuestionResult.getAndroidEntityQuestion().getEntityAnswer();
this.androidEntityQuestionResult = androidEntityQuestionResult;
this.ord = ord;
sdc = new ScreenDimensionsConstants(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row_ordering_rv, parent, false);
final RecyclerView.ViewHolder holder = new OrderingViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof OrderingViewHolder) {
((OrderingViewHolder) holder).answerText.setText(list.get(position).getAnswer().getANSWER_TEXT());
int currentPosition = position + 1;
((OrderingViewHolder) holder).position.setText("#" + currentPosition);
}
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(list, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(list, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
return true;
}
@Override
public void onItemDismiss(int position) {
}
@Override
public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
ord.getItemTouchHelper().startDrag(viewHolder);
}
class OrderingViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
private TextView answerText;
private ImageView pin;
private TextView position;
public OrderingViewHolder(View itemView) {
super(itemView);
answerText = (TextView) itemView.findViewById(R.id.orderingAnswer);
answerText.setTextSize(TypedValue.COMPLEX_UNIT_PX, sdc.getHeight() / 40);
pin = (ImageView) itemView.findViewById(R.id.ordering_pin);
pin.getLayoutParams().width = sdc.getHeight() / 15;
pin.getLayoutParams().height = sdc.getHeight() / 15;
pin.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) ==
MotionEvent.ACTION_DOWN) {
OrderingRecycleAdapter.this.onStartDrag(OrderingViewHolder.this);
}
return false;
}
});
position = (TextView) itemView.findViewById(R.id.answer_position);
position.setTextSize(TypedValue.COMPLEX_UNIT_PX, sdc.getHeight() / 40);
}
@Override
public void onItemSelected() {
itemView.setBackgroundResource(R.drawable.menu_item_background_ice_blue);
}
@Override
public void onItemClear() {
itemView.setBackgroundResource(R.drawable.menu_item_background_white);
int currentPosition = getLayoutPosition() + 1;
position.setText("#" + currentPosition);
//notifyDataSetChanged();
}
}
充气机;
语境;
AndroidEntityQuestionResult AndroidEntityQuestionResult;
ArrayList=新建ArrayList();
OrdLayoutManager问题ord;
屏幕尺寸常数sdc;
public OrderingRecycleAdapter(上下文上下文、AndroidEntityQuestionResult和AndroidEntityQuestionResult、OrdLayoutManager问题ord){
充气器=充气器。从(上下文);
this.context=上下文;
this.list=androidEntityQuestionResult.getAndroidEntityQuestion().getEntityAnswer();
this.androidEntityQuestionResult=androidEntityQuestionResult;
这个.ord=ord;
sdc=新屏幕尺寸约束(上下文);
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
视图=充气机。充气(R.layout.custom\u row\u ordering\u rv,parent,false);
final RecyclerView.ViewHolder=新订单ViewHolder(视图);
报税表持有人;
}
@凌驾
BindViewHolder上的公共无效(RecyclerView.ViewHolder,int位置){
if(OrderingViewHolder的持有者实例){
((OrderingViewHolder)holder.answerText.setText(list.get(position.getAnswer().getAnswer_TEXT());
int currentPosition=位置+1;
((OrderingViewHolder)holder.position.setText(“#”+当前位置);
}
}
@凌驾
public int getItemCount(){
返回list.size();
}
@凌驾
公共布尔onItemMove(int-fromPosition,int-toPosition){
如果(从位置<位置){
for(inti=fromPosition;itoPosition;i--){
集合。交换(列表,i,i-1);
}
}
已移动的项目(从位置、位置);
通知项已更改(从位置);
返回true;
}
@凌驾
公共空间和公共空间(内部位置){
}
@凌驾
开始拖动时的公共无效(RecyclerView.ViewHolder ViewHolder){
ord.getItemTouchHelper().startDrag(viewHolder);
}
类OrderingViewHolder扩展了RecyclerView.ViewHolder实现ItemTouchHelperViewHolder{
私有文本查看应答文本;
私人图像查看pin;
私有文本视图位置;
public OrderingViewHolder(查看项目视图){
超级(项目视图);
answerText=(TextView)itemView.findViewById(R.id.orderingAnswer);
answerText.setTextSize(TypedValue.COMPLEX\u UNIT\u PX,sdc.getHeight()/40);
pin=(ImageView)itemView.findViewById(R.id.ordering\u pin);
pin.getLayoutParams().width=sdc.getHeight()/15;
pin.getLayoutParams().height=sdc.getHeight()/15;
pin.setOnTouchListener(新视图.OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
if(MotionEventCompat.getActionMasked(事件)==
MotionEvent.ACTION(下一步){
OrderingRecycleAdapter.this.onStartDrag(OrderingViewHolder.this);
}
返回false;
}
});
position=(TextView)itemView.findViewById(R.id.answer\u position);
position.setTextSize(TypedValue.COMPLEX\u UNIT\u PX,sdc.getHeight()/40);
}
@凌驾
已选定的公共文件(){
itemView.setBackgroundResource(R.drawable.menu\u item\u background\u ice\u blue);
}
@凌驾
公共许可证{
itemView.setBackgroundResource(R.drawable.menu\u item\u background\u white);
int currentPosition=getLayoutPosition()+1;
position.setText(“#”+当前位置);
//notifyDataSetChanged();
}
}
奖金问题
是否有任何关于在2个RecyclerViews之间拖放的教程或信息
我知道有一个问题,但没有答案,我在这里可能更幸运 在我看来,似乎您的onItemMove()并不能解释所有的更改。 当某物为多个项目移动时(比如在A和B之间),您正在两个项目之间交换所有项目。 但是,您只报告A&B的更改,而不报告中间的其余元素 我建议您编写一个报告所有更改的交换方法:
public boolean swapItems(int fromPosition, int toPosition){
Collections.swap(list, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
notifyItemMoved(toPosition, fromPosition);
// And maybe also notifyItemChanged() as the item changes due to the shift
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);
}
调用此函数而不是Collections.swap(),并删除其余的notify代码 更改您的ONIMMOVE方法
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(list, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(list, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
return true;
}
@覆盖
公共布尔onItemMove(int-fromPosition,int-toPosition){
如果(从位置<位置){
for(inti=fromPosition;itoPosition;i--){
集合。交换(列表,i,i-1);
}
}
已移动的项目(从位置、位置);
通知项已更改(从位置);
返回true;
}
致:
@覆盖
公共布尔onItemMove(int-fromPosition,int-toPosition){
如果(从位置<位置){
for(inti=fromPosition;i@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(list, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(list, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
notifyItemChanged(fromPosition);
notifyItemMoved(fromPosition, toPosition);
notifyItemRangeChanged(fromPosition,toPosition)