如何向 recyclerview 添加分隔符、间隔符或带有文本的标题

问题描述 投票:0回答:4

我有一个显示数据列表的 RecylerView。我需要添加分隔符或间隔符,我还需要添加两个分隔符或间隔符,我可以添加文本,如下图所示(带有文本“默认”或“其他”)。

*注意 下图中的标头带有文本“DEFAULT”,另一个标有“OTHER”。

显示的 CC 是拖放项目,但我不希望将“空格或标题”标记为默认值并移动其他内容。

我已经开始添加分隔线,如下面的代码所示,但我不知道如何添加文本。

    @Override
   public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
       super.onViewCreated(view, savedInstanceState);

       ButterKnife.bind(this, view);

       LinearLayoutManager mAdapterLayoutManager = new LinearLayoutManager(context);
       recyclerView.setLayoutManager(mAdapterLayoutManager);
       billingMethodRecyclerViewAdapter = new BillingMethodRecyclerViewAdapter(context, billingMethods, paymentService, ListPaymentMethods.this );
       billingMethodRecyclerViewAdapter.setMasterpassService(masterpassService);
       billingMethodRecyclerViewAdapter.setChoosePaymentMode(choosePaymentMode);
       DividerItemDecoration itemDecor = new DividerItemDecoration(context, mAdapterLayoutManager.getOrientation());

       recyclerView.addItemDecoration(itemDecor);
       recyclerView.setAdapter(billingMethodRecyclerViewAdapter);
       billingMethodRecyclerViewAdapter.clear();

       if (!choosePaymentMode) {
           setupSwipeListener(billingMethodRecyclerViewAdapter);
       }

       if (!BuildConfig.SHOW_AVAILABILITY_INRIX) {
           parkmobileProAd.setVisibility(View.GONE);
       }

       if (getArguments() != null) {
           isAddPaymentZoneDetails = getArguments().getBoolean(AddPaymentActivity.ADD_PAYMENT_FROM_ZONE_DETAIL);
       }
   }

以及 recyclerview 的 xml

<androidx.recyclerview.widget.RecyclerView
           android:id="@+id/recycler_view"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"/>

编辑

适配器:

public class BillingMethodRecyclerViewAdapter extends RecyclerView.Adapter<BillingMethodHolder> {

                private static final int PENDING_REMOVAL_TIMEOUT = 3000; // in milliseconds

                private ArrayList<BillingMethod> billingMethods;
                private Handler handler = new Handler(); // handler for running delayed runnables
                private HashMap<BillingMethod, Runnable> pendingRunnables = new HashMap<>(); // map of items to pending runnables, so we can cancel a removal if need be

                private BillingMethodHolder.BillingMethodListener billingMethodListener;
                private PaymentService paymentService;
                private MasterpassService masterpassService;

                private boolean choosePaymentMode = false;
                private Context mContext;

                private int maxPaymentMethods = 6;

                public BillingMethodRecyclerViewAdapter(Context context, ArrayList<BillingMethod> objects, PaymentService paymentService, BillingMethodHolder.BillingMethodListener billingMethodListener) {
                    this.billingMethods = objects;
                    this.billingMethodListener = billingMethodListener;
                    this.mContext = context.getApplicationContext();
                    this.paymentService = paymentService;
                }

                public int getMaxPaymentMethods() {
                    return maxPaymentMethods;
                }

                public void setMaxPaymentMethods(int maxPaymentMethods) {
                    this.maxPaymentMethods = maxPaymentMethods;
                }

                public void setMasterpassService(MasterpassService masterpassService) {
                    this.masterpassService = masterpassService;
                }

                public boolean onItemMove(int fromPosition, int toPosition) {
                    if (fromPosition < toPosition) {
                        for (int i = fromPosition; i < toPosition; i++) {
                            Collections.swap(billingMethods, i, i + 1);
                        }
                    } else {
                        for (int i = fromPosition; i > toPosition; i--) {
                            Collections.swap(billingMethods, i, i - 1);
                        }
                    }
                    notifyItemMoved(fromPosition, toPosition);
                    return true;
                }


                public List<BillingMethod> getBillingMethods() {
                    return billingMethods;
                }

                public void setChoosePaymentMode(boolean choosePaymentMode) {
                    this.choosePaymentMode = choosePaymentMode;
                }

                @NonNull
                @Override
                public BillingMethodHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

                    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_payment_methods, parent, false);
                    return new BillingMethodHolder(v);
                }

                @Override
                public void onBindViewHolder(@NonNull BillingMethodHolder holder, final int position) {
                    holder.bind(getBillingMethods().get(position), billingMethodListener, choosePaymentMode);
                }


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

            public void pendingRemoval(int position) {

                final BillingMethod billingMethod = billingMethods.get(position);
                    billingMethod.setPendingDeletion(true);
                    this.notifyItemChanged(position); // redraw row in "undo" state

                    Runnable pendingRemovalRunnable = () -> {
                        deleteBillingMethod(position);
                    };
                    handler.postDelayed(pendingRemovalRunnable, PENDING_REMOVAL_TIMEOUT);
                    pendingRunnables.put(billingMethod, pendingRemovalRunnable);

            }

            public void savePaymentOrder() {

                List<BillingMethod> newOrder = new ArrayList<>();
                int order = 0;

                for (BillingMethod method : billingMethods) {
                    if (order == 0) {
                        method.setPreferred(true);
                        LocalyticsUtil.getInstance(mContext).setPrimaryPaymentMethod(method);
                    } else {
                        method.setPreferred(false);
                    }
                    method.setSortOrder(order);
                    newOrder.add(method);
                    order++;
                }

                paymentService.setPaymentMethodsOrder(newOrder, new PaymentService.GenericListener() {
                    @Override
                    public void onSuccess() {
                        Log.d("TAG", "Saved");
                    }

                    @Override
                    public void onError(String errorMessage) {
                        Log.d("TAG", "Saved");
                    }
                });
            }

            private void deleteBillingMethod(int position) {

                BillingMethod method = billingMethods.get(position);

                if (method.getBillingType() == BillingType.CREDIT_CARD) {
                    paymentService.deleteCreditCard(method.getCreditCard().getCardStatus(), new PaymentService.GenericListener() {
                        @Override
                        public void onSuccess() {
                            billingMethods.remove(position);
                            notifyItemRemoved(position);
                        }

                        @Override
                        public void onError(String errorMessage) {
                        }
                    });
                } else if (method.getBillingType() == BillingType.PREPAID) {
                    paymentService.deleteWallet(new PaymentService.GenericListener() {
                        @Override
                        public void onSuccess() {
                            billingMethods.remove(position);
                            notifyItemRemoved(position);

                        }

                        @Override
                        public void onError(String errorMessage) {
                        }
                    });
                } else if (method.getBillingType() == BillingType.PAYPAL) {
                    paymentService.deletePaypal(new PaymentService.GenericListener() {
                        @Override
                        public void onSuccess() {
                            billingMethods.remove(position);
                            notifyItemRemoved(position);
                        }

                        @Override
                        public void onError(String errorMessage) {

                        }
                    });

                } else if (method.getBillingType() == BillingType.CHASEPAY) {
                    paymentService.deleteChasepay(new PaymentService.GenericListener() {
                        @Override
                        public void onSuccess() {
                            billingMethods.remove(position);
                            notifyItemRemoved(position);
                        }

                        @Override
                        public void onError(String errorMessage) {
                        }
                    });
                } else if (method.getBillingType() == BillingType.MASTERPASSV7) {
                    masterpassService.deleteMasterpassV7(String.valueOf(method.getBillingMethodId()), new MasterpassService.GenericListener() {
                        @Override
                        public void onSuccess() {
                            billingMethods.remove(position);
                            notifyItemRemoved(position);
                        }

                        @Override
                        public void onError(String errorMessage) {

                        }
                    });

                } else {
                        notifyDataSetChanged();
                }

            }

            public void clear() {
                billingMethods.clear();
                notifyDataSetChanged();
            }

            public void stopRemoval(BillingMethod billingMethod) {
                Runnable pendingRemovalRunnable = pendingRunnables.get(billingMethod);
                pendingRunnables.remove(billingMethod);
                if (pendingRemovalRunnable != null) {
                    handler.removeCallbacks(pendingRemovalRunnable);
                }
                billingMethod.setPendingDeletion(false);
                this.notifyItemChanged(billingMethods.indexOf(billingMethod));
            }
        }
android android-recyclerview divider
4个回答
3
投票

我花了一些时间,但我能够做到。

这是输出

1)MainActivity.java

public class MainActivity extends AppCompatActivity implements OnStartDragListener{

RecyclerView recyclerView;
private ItemTouchHelper mItemTouchHelper;
private List<Item> itemList = new ArrayList<>();
private RecyclerViewAdapter mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    mAdapter = new RecyclerViewAdapter(itemList, MainActivity.this);
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.addItemDecoration(new SeparationDecorator());
    recyclerView.setAdapter(mAdapter);
    ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mAdapter);
    mItemTouchHelper = new ItemTouchHelper(callback);
    mItemTouchHelper.attachToRecyclerView(recyclerView);
    prepareItemData();
}

private void prepareItemData() {
    Item item = new Item("Apple Pay");
    itemList.add(item);
    item = new Item("1706-XXXX-XXXX-1112");
    itemList.add(item);
    item = new Item("Google pay");
    itemList.add(item);
    mAdapter.notifyDataSetChanged();
}

@Override
public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
    mItemTouchHelper.startDrag(viewHolder);
}
}

2)OnStartDragListener.java

public interface OnStartDragListener {
   void onStartDrag(RecyclerView.ViewHolder viewHolder);
}

3)SimpleItemTouchHelperCallback.java

public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {

private final ItemTouchHelperAdapter mAdapter;

public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
    mAdapter = adapter;
}

@Override
public boolean isLongPressDragEnabled() {
    return true;
}

@Override
public boolean isItemViewSwipeEnabled() {
    return false; // make this true to enable swipe to delete
}

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
    int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
    return makeMovementFlags(dragFlags, swipeFlags);
}

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

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}

}

4) ItemTouchHelperAdapter.java

public interface ItemTouchHelperAdapter {
    void onItemMove(int fromPosition, int toPosition);
    void onItemDismiss(int position);
}

5)SeparationDecorator.java

public class SeparationDecorator extends RecyclerView.ItemDecoration {
private int textSize = 50;
private int groupSpacing = 100;

private Paint paint = new Paint();
{
    paint.setTextSize(textSize);
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    for (int i = 0; i < parent.getChildCount(); i++) {
        View view = parent.getChildAt(i);
        int position = parent.getChildAdapterPosition(view);
        if (position == 0) {
            c.drawText("DEFAULT", view.getLeft(),
                    view.getTop() - groupSpacing / 2 + textSize / 3, paint);
        } else if(position == 1) {
            c.drawText("OTHER", view.getLeft(),
                    view.getTop() - groupSpacing / 2 + textSize / 3, paint);
        }
    }
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    if (parent.getChildAdapterPosition(view) == 0 || parent.getChildAdapterPosition(view) == 1) {
        outRect.set(0, groupSpacing, 0, 0);
    }
}
}

6) RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> implements ItemTouchHelperAdapter{

private List<Item> itemList;
private Context context;

@Override
public void onItemMove(int fromPosition, int toPosition) {
    Item prev = itemList.remove(fromPosition);
    itemList.add(toPosition > fromPosition ? toPosition - 1 : toPosition, prev);
    notifyItemMoved(fromPosition, toPosition);
}

@Override
public void onItemDismiss(int position) {
    itemList.remove(position);
    notifyItemRemoved(position);
}


public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView title;

    public MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.title);
    }
}


public RecyclerViewAdapter(List<Item> itemList, Context context) {
    this.itemList = itemList;
    this.context = context;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.view_item, parent, false);

    return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    Item movie = itemList.get(position);
    holder.title.setText(movie.getTitle());
}

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

7) 项目.java

public class Item {
private String title;

public Item(String title) {
    this.title  = title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getTitle() {
    return title;
}
}

就是这样。这能够解决您的问题。

我无法向您解释完整的代码,我将来肯定会花一些时间来解释它。


0
投票
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {

// other methods..

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    // initialize your other views

    if (your condition){
        // display header
    }else{
        // hide header
    }
  }
}

您可以通过向项目添加标题视图并显示所需的集合并使其消失以显示不需要的项目来执行类似的操作。


0
投票

简单地实现您需要的内容,只需添加一个带有

layout_height="1dp"
background="#bcbcbc"
的空视图,例如:

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#bcbcbc"/>

它会为您绘制一条线,将其用作分隔线,而要进行格式差异,只需更改文本的文本大小。 希望对你有帮助。


0
投票

@Karthik,如何修改代码来设置元素的状态并根据其状态将它们分类为“默认”和“其他”,而不是手动在两个分区之间拖动它们?

这是我为适配器创建的类:

public class DataModel {
    String name;
    int stat;

    public DataModel() {
    }

    public DataModel(String name, int stat) {
         this.name = name;
         this.stat = stat;
    }
}

我希望每个部门中的元素根据其状态动态变化。

© www.soinside.com 2019 - 2024. All rights reserved.