Java 项目经理助理;ActionMode:如何将多种选择与;重新安排项目

Java 项目经理助理;ActionMode:如何将多种选择与;重新安排项目,java,android,android-recyclerview,multipleselection,itemtouchhelper,Java,Android,Android Recyclerview,Multipleselection,Itemtouchhelper,我正在尝试构建一个具有与f.ex相同功能的recyclerview。神童。 LongClick应在选中长时间单击的项目的情况下激活操作模式,并通过在操作模式下正常单击将更多项目添加到选择中 但是我还希望能够使用ItemTouchHelper重新排列项目。 所以我想象的过程是这样的: 长时间单击项目:将长时间单击的项目添加到选择并输入 动作模式 如果物品未移动就被释放:保持动作模式并进一步添加 正常单击的项目将被选中 但如果项目被移动(ItemTouchHelper):完成操作模式&清除选择,

我正在尝试构建一个具有与f.ex相同功能的recyclerview。神童。 LongClick应在选中长时间单击的项目的情况下激活操作模式,并通过在操作模式下正常单击将更多项目添加到选择中

但是我还希望能够使用ItemTouchHelper重新排列项目。 所以我想象的过程是这样的:

  • 长时间单击项目:将长时间单击的项目添加到选择并输入 动作模式

  • 如果物品未移动就被释放:保持动作模式并进一步添加 正常单击的项目将被选中

  • 但如果项目被移动(ItemTouchHelper):完成操作模式&清除选择,重新排列 相应地列出notifyAdapterItemMoved()

  • 当我在长时间点击注册后立即移动项目时,我所做的似乎有效。但一瞬间,它停止拖动项目,并留下我在行动模式

    如何保持多选功能,直到所选项目拖过(移过)其最近的邻居之一

    谢谢你的帮助

    PersonListFragment:包含列表的片段

    
        public class PersonListFragment extends Fragment implements
                PersonAdapter.OnItemClickListener, androidx.appcompat.view.ActionMode.Callback {
        
            // variables omitted from brevity
        
            public PersonListFragment() { }
        
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState) {
                View view = inflater.inflate(R.layout.fragment_person_list, container, false);
                return view;
            }
        
            @Override
            public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
                super.onViewCreated(view, savedInstanceState);
                recyclerView = getActivity().findViewById(R.id.recycler_view_people);
                buttonAddPerson = getActivity().findViewById(R.id.button_add_person);
                navController = Navigation.findNavController(getActivity(), R.id.nav_host);
        
                adapter = new PersonAdapter(this);
                viewModel = new ViewModelProvider(this).get(PersonViewModel.class);
        
                handleButtons();
            }
        
            @Override
            public void onActivityCreated(@Nullable Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
        
                // Should be in activity created. Otherwise list is recreated every time this fragment opens,
                // which causes visual lag.
                viewModel.getAllPeopleWithPets().observe(getActivity(), new Observer<List<PersonWithPets>>() {
                    @Override
                    public void onChanged(@Nullable List<PersonWithPets> allPeopleWithPets) {
                        people = allPeopleWithPets;
                        adapter.setPeople(people);
                    }
                });
        
                initRecyclerView();
        
                new ItemTouchHelper(new ItemTouchHelper.Callback() {
                    @Override
                    public boolean isLongPressDragEnabled() {
                        return true;
                    }
        
                    @Override
                    public boolean isItemViewSwipeEnabled() {
                        return true;
                    }
        
                    @Override
                    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
                        super.onSelectedChanged(viewHolder, actionState);
                        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
                            multiSelect = false;
                            viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
                        }
                    }
        
                    @Override
                    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
                        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                        final int swipeFlags = ItemTouchHelper.END;
                        return makeMovementFlags(dragFlags, swipeFlags);
                    }
        
                    @Override
                    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                        multiSelect = false;
                        if (actionMode != null) {
                            actionMode.finish();
                        }
                        int fromPosition = viewHolder.getAdapterPosition();
                        int toPosition = target.getAdapterPosition();
                        PersonWithPets fromPerson = people.get(fromPosition);
                        people.remove(fromPerson);
                        people.add(toPosition, fromPerson);
                        adapter.notifyItemMoved(fromPosition, toPosition);
                        return true;
                    }
        
                    @Override
                    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
                        viewHolder.itemView.setBackgroundColor(Color.WHITE);
                    }
        
                    @Override
                    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                        Toast.makeText(getActivity(), "Swiped", Toast.LENGTH_SHORT).show();
                    }
                }).attachToRecyclerView(recyclerView);
            }
        
            private void initRecyclerView() {
                recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
                recyclerView.setHasFixedSize(true);
                adapter.setOnItemClickListener(this);
                recyclerView.setAdapter(adapter);
            }
        
            // CLICK
            @Override
            public void onItemClick(int position) {
                if (!multiSelect) {
                    Person clickedPerson = people.get(position).getPerson();
                    Bundle bundle = new Bundle();
                    bundle.putInt("id", clickedPerson.getId());
                    bundle.putString("name", clickedPerson.getName());
                    bundle.putString("time", clickedPerson.getTime());
                    bundle.putString("howto", clickedPerson.getHowto());
                    navController.navigate(R.id.action_homeTabs_to_personTabs, bundle);
                    Toast.makeText(getActivity(), "Clicked.", Toast.LENGTH_SHORT).show();
                } else {
                    multiSelect(position);
                }
            }
            // LONG CLICK
            @Override
            public void onItemLongClick(int position) {
                if (!multiSelect) {
                    multiSelect = true;
                    selected = new ArrayList<>();
                }
                if (actionMode == null) {
                    actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(PersonListFragment.this);
                }
                multiSelect(position);
            }
            // FAV CLICK
            @Override
            public void onFavClick(int position) {
                if (!multiSelect) {
                    Person person = people.get(position).getPerson();
                    if (!person.getSelected()) {
                        person.setSelected(true);
                    } else {
                        person.setSelected(false);
                    }
                    viewModel.update(person);
                    adapter.notifyItemChanged(position);
                }
            }
        
            // MULTI SELECT
            private void multiSelect(int position) {
                Person person = adapter.getItem(position).getPerson();
                if (person != null) {
                    if (selected.contains(person.getId())) {
                        selected.remove(person.getId());
                    } else {
                        selected.add(person.getId());
                    }
                    if (selected.size() > 0) {
                        actionMode.setTitle(selected.size() + " items selected.");
                    } else {
                        multiSelect = false;
                        selected = new ArrayList<>();
                        actionMode.setTitle("");
                        actionMode.finish();
                    }
                    adapter.setSelected(selected);
                }
            }
        
            // BUTTONS
            private void handleButtons() {
                buttonAddPerson.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        navController.navigate(R.id.personTabs);
                        Toast.makeText(getActivity(), "That tickles.", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        
            @Override
            public boolean onCreateActionMode(androidx.appcompat.view.ActionMode mode, Menu menu) {
                Log.d(TAG, "onCreateActionMode: CREATED ACTION MODE");
                actionMode = mode;
                MenuInflater inflater = actionMode.getMenuInflater();
                inflater.inflate(R.menu.action_menu, menu);
                return true;
            }
        
            @Override
            public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode mode, Menu menu) {
                return false;
            }
        
            @Override
            public boolean onActionItemClicked(androidx.appcompat.view.ActionMode mode, MenuItem item) {
                Log.d(TAG, "onActionItemClicked: ACTION ITEM CLICKED");
                switch (item.getItemId()) {
                    case R.id.button_delete:
                        viewModel.deletePeopleById(selected);
                        Toast.makeText(getActivity(), selected.size() + " people deleted.", Toast.LENGTH_SHORT).show();
                        mode.finish();
                        return true;
                    case R.id.button_favorite:
                        for (PersonWithPets personWithPets : people) {
                            Person person = personWithPets.getPerson();
                            if (selected.contains(person.getId())) {
                                person.setSelected(true);
                                viewModel.update(person);
                                Log.d(TAG, "onActionItemClicked: FAVORITE " + person.getName() + " updated.");
                            }
                        }
                        Toast.makeText(getActivity(), "<3", Toast.LENGTH_SHORT).show();
                        mode.finish();
                        return true;
                }
                return false;
            }
        
            @Override
            public void onDestroyActionMode(androidx.appcompat.view.ActionMode mode) {
                multiSelect = false;
                selected.clear();
                adapter.notifyDataSetChanged();
                actionMode = null;
                Log.d(TAG, "onDestroyActionMode: ACTION MODE DESTROYED");
            }
        }
    
    
    
    公共类PersonListFragment扩展了片段实现
    PersonalAdapter.OnItemClickListener,androidx.appcompat.view.ActionMode.Callback{
    //因简洁而省略的变量
    公共PersonListFragment(){}
    @凌驾
    创建视图上的公共视图(布局、充气机、视图组容器、,
    Bundle savedInstanceState){
    视图=充气机。充气(R.layout.fragment\u person\u list,container,false);
    返回视图;
    }
    @凌驾
    已创建公用void onview(@NonNull视图,@Nullable Bundle savedInstanceState){
    super.onViewCreated(视图,savedInstanceState);
    recyclerView=getActivity().findViewById(R.id.recycler\u view\u people);
    buttonAddPerson=getActivity().findViewById(R.id.button\u add\u person);
    navController=Navigation.findNavController(getActivity(),R.id.nav_host);
    适配器=新角色适配器(此);
    viewModel=newviewmodelprovider(this.get)(PersonViewModel.class);
    把手扣();
    }
    @凌驾
    ActivityCreated上的公共无效(@Nullable Bundle savedinStateCState){
    super.onActivityCreated(savedInstanceState);
    //应在创建的活动中。否则,每次打开此片段时都会重新创建列表,
    //这会导致视觉滞后。
    viewModel.getAllPeopleWithPets().observe(getActivity(),new Observator()){
    @凌驾
    更改后的公共无效(@Nullable List allPeopleWithPets){
    人=所有有宠物的人;
    adapter.setPeople(人);
    }
    });
    initRecyclerView();
    新建ItemTouchHelper(新建ItemTouchHelper.Callback()){
    @凌驾
    公共布尔值isLongPressDragEnabled(){
    返回true;
    }
    @凌驾
    公共布尔值IsItemViewSwipEnabled(){
    返回true;
    }
    @凌驾
    选定的公共无效已更改(@Nullable RecyclerView.ViewHolder ViewHolder,int actionState){
    super.onSelectedChanged(视图持有者、动作状态);
    如果(actionState==ItemTouchHelper.ACTION\u STATE\u DRAG){
    多选=假;
    viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
    }
    }
    @凌驾
    public int getMovementFlags(@NonNull RecyclerView RecyclerView,@NonNull RecyclerView.ViewHolder ViewHolder){
    final int dragFlags=ItemTouchHelper.UP | ItemTouchHelper.DOWN;
    final int swipeFlags=ItemTouchHelper.END;
    返回makeMovementFlags(dragFlags、swipeFlags);
    }
    @凌驾
    公共布尔onMove(@NonNull RecyclerView RecyclerView,@NonNull RecyclerView.ViewHolder ViewHolder,@NonNull RecyclerView.ViewHolder target){
    多选=假;
    if(actionMode!=null){
    actionMode.finish();
    }
    int fromPosition=viewHolder.getAdapterPosition();
    int-toPosition=target.getAdapterPosition();
    PersonWithPets fromPerson=people.get(fromPosition);
    人。移除(从人身上);
    people.add(位置,fromPerson);
    适配器。notifyItemMoved(从位置、位置);
    返回true;
    }
    @凌驾
    公共无效clearView(@NonNull RecyclerView RecyclerView,@NonNull RecyclerView.ViewHolder ViewHolder){
    viewHolder.itemView.setBackgroundColor(Color.WHITE);
    }
    @凌驾
    公共void onsweed(@NonNull RecyclerView.ViewHolder ViewHolder,int-direction){
    Toast.makeText(getActivity(),“Swiped”,Toast.LENGTH_SHORT.show();
    }
    }).attachToRecyclerView(recyclerView);
    }
    私有void initRecyclerView(){
    setLayoutManager(新的LinearLayoutManager(this.getActivity());
    recyclerView.setHasFixedSize(true);
    adapter.setOnItemClickListener(此);
    recyclerView.setAdapter(适配器);
    }
    //点击
    @凌驾
    公共空间单击(内部位置){
    如果(!multiSelect)
    
        public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.PersonHolder> {
            private static final String TAG = "PersonAdapter";
            private List<PersonWithPets> people = new ArrayList<>();
            private List<Integer> selected = new ArrayList<>();
            private OnItemClickListener listener;
            private View clickedView;
            private boolean multiSelect;
            Context context;
            private ItemTouchHelper itemTouchHelper;
            
            public void setOnItemClickListener(OnItemClickListener listener) {
                this.listener = listener;
            }
        
        
            public interface OnItemClickListener {
                void onItemClick(int position);
                void onItemLongClick(int position);
                void onFavClick(int position);
            }
        
            public PersonAdapter(OnItemClickListener onItemClickListener) {
                this.listener = onItemClickListener;
            }
        
            @NonNull
            @Override
            public PersonHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.person_item, parent, false);
                return new PersonHolder(itemView, listener);
            }
        
            @Override
            public void onBindViewHolder(@NonNull PersonHolder holder, int position) {
                PersonWithPets currentPerson = people.get(position);
                int id = currentPerson.getPerson().getId();
                boolean fav = currentPerson.getPerson().getSelected();
                holder.textViewName.setText(        currentPerson.getPerson().getName());
                holder.textViewHowTo.setText(       currentPerson.getPerson().getHowto());
                holder.textViewTime.setText(        currentPerson.getPerson().getTime());
                holder.textViewPetAmount.setText(   currentPerson.getPets().size() + " Pets");
        
                // Multi select
                if (selected.contains(id)){
                    holder.rootView.setBackgroundColor(Color.CYAN);
                } else {
                    holder.rootView.setBackgroundColor(Color.WHITE);
                }
                
                // Favorited?
                if (fav) {
                    holder.imageViewFav.setBackgroundColor(Color.CYAN);
                    holder.imageViewFav.animate();
                } else {
                    holder.imageViewFav.setBackgroundColor(Color.TRANSPARENT);
                    holder.imageViewFav.animate();
                }
            }
        
            @Override
            public int getItemCount() {
                return people.size();
            }
            
            // VIEWHOLDER
            public class PersonHolder extends RecyclerView.ViewHolder
            {
                private CardView rootView;
                private TextView textViewName, textViewHowTo, textViewPetAmount, textViewTime;
                private ImageView imageViewFav, imageViewPerson;
        
                OnItemClickListener listener;
        
                public PersonHolder(View itemView, OnItemClickListener onItemClickListener){
                    super(itemView);
                    rootView = itemView.findViewById(R.id.person_item);
                    textViewName = itemView.findViewById(R.id.text_view_person_name);
                    textViewPetAmount = itemView.findViewById(R.id.text_view_pet_amount);
                    textViewTime = itemView.findViewById(R.id.text_view_prep_time);
                    imageViewFav = itemView.findViewById(R.id.image_view_fav);
                    imageViewPerson = itemView.findViewById(R.id.image_view_person);
                    textViewHowTo = itemView.findViewById(R.id.text_view_person_description);
                    listener = onItemClickListener;
        
                    rootView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if(listener != null) {
                                int position = getAdapterPosition();
                                if (position != RecyclerView.NO_POSITION) {
                                    listener.onItemClick(position);
                                }
                            }
                        }
                    });
                    rootView.setOnLongClickListener(new View.OnLongClickListener() {
                        @Override
                        public boolean onLongClick(View v) {
                            if (listener != null) {
                                int position = getAdapterPosition();
                                if (position != RecyclerView.NO_POSITION) {
                                    listener.onItemLongClick(position);
                                }
                            }
                            return true;
                        }
                    });
                    imageViewFav.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if(listener != null) {
                                int position = getAdapterPosition();
                                if (position != RecyclerView.NO_POSITION) {
                                    listener.onFavClick(position);
                                }
                            }
                        }
                    });
        
                }
            }
        
            // Custom Methods
            public PersonWithPets getItem(int position) {
                return people.get(position);
            }
        
            public void setSelected(List<Integer> selected) {
                this.selected = selected;
                notifyDataSetChanged();
            }
        
            public void setPeople(List<PersonWithPets> people) {
                this.people = people;
                notifyDataSetChanged();
            }
        }