dri*_*noo 6 android multipleselection android-actionmode android-recyclerview
我目前正在尝试recyclerview-selection从Android支持库28.0.0-alpha1 实现新的API,并且遇到了一些问题.我的目标是拥有一个RecyclerView能够选择多行,显示上下文操作栏并对其执行操作的功能,例如"删除"或"共享"
我会尝试提供足够的代码来充分了解正在发生的事情,但如果有必要,我总能回复更多.
在我Fragment包含RecyclerView我关注的内容中,我正在启动一个SelectionTracker,并将其设置在我的上面RecyclerView.Adapter,就像这样:
private void buildRecyclerView() {
sheetsAdapter = new SheetsAdapter(getContext(), this, sheets);
gridManager = new GridLayoutManager(getContext(), getResources().getInteger(R.integer.grid_span_count));
ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getContext(), R.dimen.item_offset);
sheetsRecycler.addItemDecoration(itemDecoration);
sheetsRecycler.setLayoutManager(gridManager);
sheetsRecycler.setAdapter(sheetsAdapter);
sheetsRecycler.setHasFixedSize(true);
SelectionTracker selectionTracker = new SelectionTracker.Builder<>("sheet_selection",
sheetsRecycler,
new StableIdKeyProvider(sheetsRecycler),
new SheetDetailsLookup(sheetsRecycler),
StorageStrategy.createLongStorage())
.withOnContextClickListener(this)
.build();
sheetsAdapter.setSelectionTracker(selectionTracker);
}
Run Code Online (Sandbox Code Playgroud)
这Fragment也是implements OnContextClickListener为了收听我在我的项目中的长按RecyclerView:
@Override
public boolean onContextClick(@NonNull MotionEvent e) {
if (actionMode != null) {
return false;
}
// Start the CAB using the ActionMode.Callback defined below
if (getActivity() != null) {
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
它应该显示我的CAB,像这样:
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.sheets_cab_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
Toast.makeText(getContext(), R.string.sheets_delete, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};
Run Code Online (Sandbox Code Playgroud)
我SheetDetailsLookup看起来像这样:
public class SheetDetailsLookup extends ItemDetailsLookup<Long> {
private RecyclerView recyclerView;
SheetDetailsLookup(RecyclerView recyclerView) {
super();
this.recyclerView = recyclerView;
}
@Nullable
@Override
public ItemDetails<Long> getItemDetails(@NonNull MotionEvent e) {
View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
if (holder instanceof SheetsAdapter.SheetViewHolder) {
return ((SheetsAdapter.SheetViewHolder) holder).getItemDetails();
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的SheetViewHolder,我更新视图,以表明它已被选中:
if (selectionTracker.isSelected(sheet.uid)) {
layout.setBackgroundResource(R.color.md_grey_700);
} else {
layout.setBackgroundResource(android.R.color.transparent);
}
Run Code Online (Sandbox Code Playgroud)
以及:
public SheetItemDetails getItemDetails() {
return new SheetItemDetails(getAdapterPosition(), mSheets.get(getAdapterPosition()).uid);
}
Run Code Online (Sandbox Code Playgroud)
其中SheetItemDetails无非是:
public class SheetItemDetails extends ItemDetailsLookup.ItemDetails<Long> {
private int position;
private Long key;
SheetItemDetails(int position, Long key) {
this.position = position;
this.key = key;
}
@Override
public int getPosition() {
return position;
}
@Nullable
@Override
public Long getSelectionKey() {
return key;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经实现了API规范中提到的所有内容,但现在遇到了麻烦.当我选择一个项目时,我的CAB不会显示...而且应用程序通常会崩溃.每当我尝试"退出"选择时出现崩溃,然后长按以启动另一个选择,使用此堆栈跟踪:
java.lang.IllegalStateException
at android.support.v4.util.Preconditions.checkState(Preconditions.java:130)
at android.support.v4.util.Preconditions.checkState(Preconditions.java:142)
at androidx.recyclerview.selection.GestureSelectionHelper.start(GestureSelectionHelper.java:76)
at androidx.recyclerview.selection.SelectionTracker$Builder$4.run(SelectionTracker.java:742)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:136)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:95)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:779)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Run Code Online (Sandbox Code Playgroud)
此外,我现在已经失去了"短按"我的一个项目的能力,以启动详细视图......到目前为止我工作得很好.
我做错了什么?
我最近开始查看此库,并遇到了相同的异常。当SelectionTracker尝试从您的自定义RecyclerView.Adapter子类中获取ID 时,会发生此问题。要解决此问题,请先调用setHasStableIds(true)其构造函数。然后覆盖getItemId()以返回给定位置参数的ID。
| 归档时间: |
|
| 查看次数: |
8884 次 |
| 最近记录: |