首页 > 解决方案 > 选择和删除多个 RecyclerView 项目 - AndroidX

问题描述

我已经编写了一个应用程序,它在回收视图中显示项目列表,并且还在 setOnLongClickListener 中添加了删除选项,但现在我想在“setOnLongClickListener”中添加一个选项,其中项目被选中,然后用户可以根据需要选择尽可能多的项目然后将它们全部删除,但似乎无法找出方法。

这是我的适配器:

public class TextTypingCustomAdapter extends RecyclerView.Adapter<TextTypingCustomAdapter.ViewHolder> implements Filterable {
    private LayoutInflater mLayoutInflater;

    private List<TextTypingObject> mTextTypingObjectList, mTextTypingObjectFilteredList;

    public TextTypingCustomAdapter(@NonNull Context context, @NonNull List<TextTypingObject> textTypingObjectList) {
        try {
            mLayoutInflater = LayoutInflater.from(context);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (mLayoutInflater == null) {
            try {
                mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        mTextTypingObjectList = mTextTypingObjectFilteredList = textTypingObjectList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(mLayoutInflater.inflate(R.layout.item_text_typing, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        TextTypingObject textTypingObject = mTextTypingObjectFilteredList.get(i);

        if (textTypingObject != null) {
            viewHolder.onBindViewHolder(textTypingObject, i == mTextTypingObjectFilteredList.size() - 1);
        }
    }

    @Override
    public int getItemCount() {
        return mTextTypingObjectFilteredList != null ? mTextTypingObjectFilteredList.size() : 0;
    }

    // ----

    class ViewHolder extends RecyclerView.ViewHolder {
        TextView applicationNameTextView;
        ImageView applicationIconImageView;
        TextView dateTimeTextView;
        TextView textTypingTextView;
        TextView itemPackageNameSt;
        View dividerView;


        ViewHolder(@NonNull View itemView) {
            super(itemView);

            // ----

            applicationNameTextView = itemView.findViewById(R.id.item_text_typing_application_name); // Text view
            applicationIconImageView = itemView.findViewById(R.id.item_text_typing_application_icon); // Image view
            dateTimeTextView = itemView.findViewById(R.id.item_text_typing_date_time); // Text view
            textTypingTextView = itemView.findViewById(R.id.item_text_typing_text_typing); // Text view
            dividerView = itemView.findViewById(R.id.item_clips_divider_view); // View
            itemPackageNameSt = itemView.findViewById(R.id.content_input_event_package_name); // Text view
        }

        void onBindViewHolder(@NonNull TextTypingObject textTypingObject, boolean isLastItem) {

            itemView.setOnClickListener(v -> {
                Intent intent = new Intent(itemView.getContext(), TextTypingActivity.class);
                intent.putExtra("id", textTypingObject.getEventId());

                itemView.getContext().startActivity(intent);
            });

            itemView.setOnLongClickListener(v -> {

                CFAlertDialog.Builder builder = new CFAlertDialog.Builder(v.getContext());
                builder.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT);
                builder.setHeaderView(R.layout.more_dialog_typed_text);
                builder.setDialogBackgroundColor(Color.parseColor("#191919"));
                builder.setTextColor(Color.parseColor("#FFFFFF"));
                builder.setItems(new String[]{"Preview", "Delete"}, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int index) {
                        dialogInterface.dismiss();

                        switch (index) {
                            case 0: // "Preview"
                                Intent intent = new Intent(itemView.getContext(), TextTypingActivity.class);
                                intent.putExtra("id", textTypingObject.getEventId());

                                itemView.getContext().startActivity(intent);
                                break;
                            case 1: // "Delete"
                                deleteInputEvent(itemView.getContext(), textTypingObject);
                                break;
                        }

                    }
                });
                builder.show();


                return true;
            });

            // ----

            applicationNameTextView.setText(textTypingObject.getName());
            applicationIconImageView.setImageDrawable(textTypingObject.getIcon());

            // ----

            String dateTime = null;

            if (!DateFormat.is24HourFormat(itemView.getContext())) {
                try {
                    dateTime = new SimpleDateFormat("hh:mm:ss a - E dd/MM/yy", Locale.getDefault()).format(new Date(textTypingObject.getTimestamp()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    dateTime = new SimpleDateFormat("HH:mm:ss - E dd/MM/yy", Locale.getDefault()).format(new Date(textTypingObject.getTimestamp()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // ----

            String textTyping = textTypingObject.getTextTyping();

            if (textTyping != null) {
                if (textTyping.isEmpty() || textTyping.trim().isEmpty()) {
                    textTyping = "Blank space(s)";

                    textTypingTextView.setTextColor(ResourceUtil.getColor(itemView.getContext(), R.color.colorAccent));
                }
            }

            // ----

            dateTimeTextView.setText(dateTime != null ? dateTime : itemView.getContext().getString(R.string.date_time) + ": N/A");
            textTypingTextView.setText(textTyping != null ? textTyping : itemView.getContext().getString(R.string.text_typing) + ": N/A");

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                dividerView.setVisibility(View.GONE);
            } else if (isLastItem) {
                dividerView.setVisibility(View.GONE);
            }


            String packageName = textTypingObject.getPackageName();

            if (packageName != null) {
                String itemPackageName = null;

                // ----

                PackageInfo packageInfo = null;
                try {
                    packageInfo = itemView.getContext().getPackageManager().getPackageInfo(packageName, 0);
                } catch (Exception e) {

                    e.printStackTrace();
                }

                if (packageInfo != null) {
                    ApplicationInfo applicationInfo = packageInfo.applicationInfo;

                    if (applicationInfo != null) {
                        itemPackageName = applicationInfo.packageName;
                    }

                    // ----
                }

                // ----

                if (itemPackageName == null) {
                    itemPackageName = packageName;
                }

                // ----

                itemPackageNameSt.setText(itemPackageName);

            }



        }
    }

    // ----

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String query = constraint != null ? constraint.toString() : null;

                // ----

                if (query != null && !query.isEmpty()) {
                    ArrayList<TextTypingObject> newFilteredTextTypingObjectArrayList = new ArrayList<>();

                    for (TextTypingObject textTypingObject : mTextTypingObjectList) {
                        if (textTypingObject.getTextTyping().toLowerCase(Locale.getDefault()).contains(query.toLowerCase(Locale.getDefault()))) {
                            newFilteredTextTypingObjectArrayList.add(textTypingObject);

                        }

                    }
                    // ----

                    mTextTypingObjectFilteredList = newFilteredTextTypingObjectArrayList;
                } else {
                    mTextTypingObjectFilteredList = mTextTypingObjectList;
                }

                // ----

                FilterResults filterResults = new FilterResults();
                filterResults.values = mTextTypingObjectFilteredList;
                filterResults.count = mTextTypingObjectFilteredList.size();

                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults filterResults) {
                /*if (filterResults.count == 0) {
                    // There is no "notifyDataSetInvalidated()" method in RecyclerView.Adapter
                } else {*/
                mTextTypingObjectFilteredList = (ArrayList<TextTypingObject>) filterResults.values;

                // ----
                notifyDataSetChanged();
                /*}*/
            }
        };
    }

    private void deleteInputEvent(@NonNull Context context, @NonNull TextTypingObject textTypingObject) {

        CFAlertDialog.Builder builder = new CFAlertDialog.Builder(context)
                .setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT)
                .setDialogBackgroundColor(Color.parseColor("#191919"))
                .setHeaderView(R.layout.delete_dialog)
                .addButton("Yes, delete",  Color.parseColor("#FFFFFF"), Color.parseColor("#1976d3"), CFAlertDialog.CFAlertActionStyle.POSITIVE, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
                    dialog.dismiss();

                    Realm realm = null;
                    RealmResults<TypeViewTextChangedEventObject> mTypeViewTextChangedEventObjectRealmResults = null;
                    try {
                        realm = Realm.getDefaultInstance();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if (realm != null && !realm.isClosed()) {
                        InputEventObject clipboardObject = null;
                        try {

                            clipboardObject = realm.where(InputEventObject.class).equalTo("id", textTypingObject.getEventId()).findFirst();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }


                        if (clipboardObject != null) {
                            try {
                                realm.beginTransaction(); // Begin transaction

                                if (mTypeViewTextChangedEventObjectRealmResults != null) {
                                    mTypeViewTextChangedEventObjectRealmResults.deleteAllFromRealm();

                                    mTypeViewTextChangedEventObjectRealmResults = null;
                                }

                                clipboardObject.deleteFromRealm();

                                realm.commitTransaction(); // Commit transaction

                                // Refresh adapter
                                mTextTypingObjectList.remove(textTypingObject);
                                mTextTypingObjectFilteredList.remove(textTypingObject);

                                notifyDataSetChanged();
                                // - Refresh adapter

                                // ----

                               // Toast.makeText(context, "Typed text deleted successfully.", Toast.LENGTH_SHORT).show();
                                DynamicToast.make(context, "Deleted successfully",
                                        context.getResources().getDrawable(R.drawable.ic_delete),
                                        context.getResources().getColor(R.color.white),
                                        context.getResources().getColor(R.color.successToast), Toast.LENGTH_LONG).show();

                            } catch (Exception e) {
                                e.printStackTrace();

                                // ----

                              //  Toast.makeText(context, "Typed text could not be deleted.", Toast.LENGTH_SHORT).show();

                                DynamicToast.make(context, "Could not be deleted",
                                        context.getResources().getDrawable(R.drawable.ic_baseline_block_24px),
                                        context.getResources().getColor(R.color.white),
                                        context.getResources().getColor(R.color.errorToast), Toast.LENGTH_LONG).show();
                            }
                        } else {
                           // Toast.makeText(context, "Typed text could not be deleted.", Toast.LENGTH_SHORT).show();

                            DynamicToast.make(context, "Could not be deleted",
                                    context.getResources().getDrawable(R.drawable.ic_baseline_block_24px),
                                    context.getResources().getColor(R.color.white),
                                    context.getResources().getColor(R.color.errorToast), Toast.LENGTH_LONG).show();
                        }
                    }

                });

        builder.addButton(context.getString(android.R.string.no), Color.parseColor("#000000"), Color.parseColor("#FFFFFF"), CFAlertDialog.CFAlertActionStyle.DEFAULT, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
            dialog.dismiss();
        });

        builder.create().show();
    }
}

这是我的片段:

public class TextTypingTabFragment extends Fragment implements TabLayoutFragmentPagerAdapter.ITabLayoutIconFragmentPagerAdapter {
    private static final String TAG = TextTypingTabFragment.class.getSimpleName();

    private final TextTypingLoaderCallbacks mLoaderCallbacks = new TextTypingLoaderCallbacks();
    private TextTypingCustomAdapter mTextTypingCustomAdapter;

    private View mView;
    private ProgressBar mProgressBar;
    private ScrollView mScrollView;
    private RecyclerView mRecyclerView;

    public TextTypingTabFragment() {
        // Required empty public constructor
    }

    // ----

    private Context getContextNonNull() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            return Objects.requireNonNull(getContext());
        } else {
            return getContext();
        }
    }

    // ----

    private int mItemCount = -1;
    private int mFirstVisibleItemPosition = -1, mFirstCompletelyVisibleItemPosition = -1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtil.d(TAG, "Fragment create");

        Bundle bundle = new Bundle();
        bundle.putString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, MainActivity.sSelectedPackageName);

        getLoaderManager().initLoader(1, bundle, mLoaderCallbacks); // Init with 1

        setHasOptionsMenu(true);
        // ----

        LocalBroadcastManager.getInstance(getContextNonNull()).registerReceiver(mSelectedPackageNameChangedCustomReceiver, new IntentFilter(AppEnvr.ACTION_SELECTED_PACKAGE_NAME_CHANGED));
    }

    @Override
    public void onResume() {
        super.onResume();
        LogUtil.d(TAG, "Fragment resume");

        Bundle bundle = new Bundle();
        bundle.putString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, MainActivity.sSelectedPackageName);

        getLoaderManager().restartLoader(1, bundle, mLoaderCallbacks); // Restart with 1
    }

    @Override
    public void onPause() {
        super.onPause();
        LogUtil.d(TAG, "Fragment pause");

        if (mTextTypingCustomAdapter != null) {
            mItemCount = mTextTypingCustomAdapter.getItemCount();
        }

        if (mRecyclerView != null) {
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();

            if (linearLayoutManager != null) {
                mFirstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
                mFirstCompletelyVisibleItemPosition = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtil.d(TAG, "Fragment destroy");

        LocalBroadcastManager.getInstance(getContextNonNull()).unregisterReceiver(mSelectedPackageNameChangedCustomReceiver);
    }

    // ----

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        return inflater.inflate(R.layout.fragment_text_typing_tab, container, false);
    }

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

        mView = view;
        mProgressBar = view.findViewById(R.id.fragment_text_typing_tab_progress_bar);
        mScrollView = view.findViewById(R.id.fragment_text_typing_tab_scroll_view);
        mRecyclerView = view.findViewById(R.id.fragment_text_typing_tab_recycler_view);
    }

    // ----

    @Override
    public Fragment getItem() {
        return this;
    }

    @Override
    public CharSequence getPageTitle() {
        return "History";
    }

    @Override
    public int getIcon() {
        return R.drawable.ic_typesave;
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.search_menu, menu);

        final SearchView searchView = new SearchView(getActivity());
        searchView.setQuery(null, true);
        searchView.setQueryHint("Search Text");

        try {
            Field mDrawable = SearchView.class.getDeclaredField("mSearchHintIcon");
            mDrawable.setAccessible(true);
            Drawable drawable =  (Drawable) mDrawable.get(searchView);
            drawable.setTint(Color.DKGRAY);
            drawable.setTintMode(PorterDuff.Mode.SRC_IN);

        } catch (Exception e) {
            e.printStackTrace();
        }

        ImageView searchCloseIcon = searchView.findViewById(androidx.appcompat.R.id.search_close_btn);
        searchCloseIcon.setImageResource(R.drawable.ic_close);

        EditText searchEditText = searchView.findViewById(androidx.appcompat.R.id.search_src_text);

        View v = searchView.findViewById(androidx.appcompat.R.id.search_plate);
        v.setBackgroundColor(Color.TRANSPARENT);

        searchEditText.setTextColor(getResources().getColor(R.color.white));
        searchEditText.setHintTextColor(getResources().getColor(R.color.drawerSecondaryText));

        Typeface myCustomFont = Typeface.createFromAsset(getActivity().getAssets(),"fonts/regular.ttf");
        searchEditText.setTypeface(myCustomFont);
        searchEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.search_text));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {

                if(mTextTypingCustomAdapter != null) {
                    Filter filter = mTextTypingCustomAdapter.getFilter();

                    if (filter != null) {
                        filter.filter(s);

                        return true;
                    }
                }

                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {

                if(mTextTypingCustomAdapter != null) {
                    Filter filter = mTextTypingCustomAdapter.getFilter();

                    if (filter != null) {
                        filter.filter(s);

                        return true;
                    }
                }

                return false;
            }
        });

        menu.findItem(R.id.action_search).setActionView(searchView);

    }

    // ----

    private final BroadcastReceiver mSelectedPackageNameChangedCustomReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            LogUtil.d(TAG, "Receiver receive");

            // ----

            if (context == null || intent == null) {
                if (context == null) {
                    LogUtil.w(TAG, "Receiver receive: Context lack");
                }

                if (intent == null) {
                    LogUtil.w(TAG, "Receiver receive: Intent lack");
                }

                return;
            }

            // ----

            String intentAction = null;
            try {
                intentAction = intent.getAction();
            } catch (Exception e) {
                LogUtil.e(TAG, e.getMessage());
                LogUtil.e(TAG, e.toString());

                e.printStackTrace();
            }

            if (intentAction == null || !intentAction.equals(AppEnvr.ACTION_SELECTED_PACKAGE_NAME_CHANGED)) {
                if (intentAction == null) {
                    LogUtil.w(TAG, "Receiver receive: Intent action lack");
                } else if (!intentAction.equals(AppEnvr.ACTION_SELECTED_PACKAGE_NAME_CHANGED)) {
                    LogUtil.w(TAG, "Receiver receive: Intent action mismatch");
                }

                return;
            }

            // ----

            LogUtil.d(TAG, "Receiver receive: OK");

            // ----

            Bundle extras = null;
            try {
                extras = intent.getExtras();
            } catch (Exception e) {
                LogUtil.e(TAG, e.getMessage());
                LogUtil.e(TAG, e.toString());

                e.printStackTrace();
            }

            if (extras != null) {
                if (extras.containsKey(AppEnvr.EXTRA_PACKAGE_NAME_KEY)) {
                    String packageName = extras.getString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, null);

                    // ----

                    Bundle bundle = new Bundle();
                    bundle.putString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, packageName);

                    getLoaderManager().restartLoader(1, bundle, mLoaderCallbacks); // Restart with 1
                }
            }
        }
    };

    // ----

    private final class TextTypingLoaderCallbacks implements LoaderManager.LoaderCallbacks<ArrayList<TextTypingObject>> {
        private String mPackageName = null;

        @NonNull
        @Override
        public Loader<ArrayList<TextTypingObject>> onCreateLoader(int i, @Nullable Bundle bundle) {
            if (mScrollView != null) {
                mScrollView.setVisibility(View.GONE);
            }

            if (mRecyclerView != null) {
                mRecyclerView.setVisibility(View.GONE);
            }

            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.VISIBLE);
            }

            // ----

            if (bundle != null) {
                mPackageName = bundle.getString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, null);
            }

            // ----

            return new TextTypingLoader(getContextNonNull(), mPackageName);
        }

        @Override
        public void onLoadFinished(@NonNull Loader<ArrayList<TextTypingObject>> loader, @Nullable ArrayList<TextTypingObject> textTypingObjectArrayList) {
            if (textTypingObjectArrayList != null && !textTypingObjectArrayList.isEmpty()) {
                mTextTypingCustomAdapter = new TextTypingCustomAdapter(getContextNonNull(), textTypingObjectArrayList);
            } else {
                if (mTextTypingCustomAdapter != null) {
                    mTextTypingCustomAdapter = null;
                }

                // ----

                if (mPackageName != null && MainActivity.sSelectedPackageName != null) {
                    mPackageName = null;
                    MainActivity.sSelectedPackageName = null;

                    getLoaderManager().restartLoader(1, null, mLoaderCallbacks); // Restart with 1

                    return;
                }
            }

            // ----

            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.GONE);
            }

            if (mTextTypingCustomAdapter != null) {
                if (mRecyclerView != null) {
                    int scrollToPosition = -1;

                    // ----

                    if (mItemCount != -1 && mFirstVisibleItemPosition != -1) {
                        int newItemCount = mTextTypingCustomAdapter.getItemCount();

                        // ----

                        if (newItemCount == mItemCount) { // No added/removed events
                            scrollToPosition = mFirstVisibleItemPosition;
                        } else if (newItemCount > mItemCount) { // Added events found
                            if (mFirstVisibleItemPosition != 0) {
                                int addedEventsCount = newItemCount - mItemCount;

                                scrollToPosition = mFirstVisibleItemPosition + addedEventsCount;

                                // ----

                                if (addedEventsCount >= 1 && mFirstVisibleItemPosition >= 1) {
                                    Snackbar snackbar = Snackbar.make(mView, getContextNonNull().getString(R.string.new_events_found, addedEventsCount) + " (item)", Snackbar.LENGTH_SHORT);
                                    snackbar.setAction(getContextNonNull().getString(R.string.scroll), v -> mRecyclerView.smoothScrollToPosition(0));
                                    snackbar.show();
                                }
                            }
                        } else /*if (newItemCount < mItemCount)*/ { // Removed events found
                            scrollToPosition = mFirstVisibleItemPosition;
                        }

                        // ----

                        mFirstVisibleItemPosition = -1;
                        mItemCount = -1;
                    }

                    // ----

                    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mRecyclerView.getContext());
                    linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
                    if (scrollToPosition != -1) {
                        linearLayoutManager.scrollToPosition(scrollToPosition);
                    }

                    mRecyclerView.setLayoutManager(linearLayoutManager);
                    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
                    mRecyclerView.setAdapter(mTextTypingCustomAdapter);

                    // ----

                    mRecyclerView.setVisibility(View.VISIBLE);

                    // ----
                }
            } else {
                if (mScrollView != null) {
                    mScrollView.setVisibility(View.VISIBLE);
                }
            }

            // ----

            if (mPackageName != null) {
                mPackageName = null;
            }
        }

        @Override
        public void onLoaderReset(@NonNull Loader loader) {
        }
    }
}

任何帮助表示赞赏,谢谢!

标签: javaandroid

解决方案


您可以维护所有选定项目的列表。当用户长按项目保存列表中的项目位置并且当用户单击其他项目时,然后将这些项目位置也添加到列表中。您可以在操作栏中向用户显示删除选项,当用户单击该删除选项时,删除列表中存在的所有位置项。


推荐阅读