Search in sources :

Example 11 with InfoFullscreenHelper

use of xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper in project grocy-android by patzly.

the class TasksFragment method onViewCreated.

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    activity = (MainActivity) requireActivity();
    viewModel = new ViewModelProvider(this).get(TasksViewModel.class);
    viewModel.setOfflineLive(!activity.isOnline());
    binding.setViewModel(viewModel);
    binding.setActivity(activity);
    binding.setFragment(this);
    binding.setLifecycleOwner(getViewLifecycleOwner());
    infoFullscreenHelper = new InfoFullscreenHelper(binding.frame);
    clickUtil = new ClickUtil();
    // APP BAR BEHAVIOR
    appBarBehavior = new AppBarBehavior(activity, binding.appBarDefault, binding.appBarSearch, savedInstanceState);
    binding.recycler.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false));
    binding.recycler.setAdapter(new MasterPlaceholderAdapter());
    if (savedInstanceState == null) {
        binding.recycler.scrollToPosition(0);
        viewModel.resetSearch();
    }
    viewModel.getIsLoadingLive().observe(getViewLifecycleOwner(), state -> {
        if (!state) {
            viewModel.setCurrentQueueLoading(null);
        }
    });
    viewModel.getInfoFullscreenLive().observe(getViewLifecycleOwner(), infoFullscreen -> infoFullscreenHelper.setInfo(infoFullscreen));
    viewModel.getFilteredTasksLive().observe(getViewLifecycleOwner(), items -> {
        if (items == null) {
            return;
        }
        if (items.isEmpty()) {
            InfoFullscreen info;
            if (viewModel.isSearchActive()) {
                info = new InfoFullscreen(InfoFullscreen.INFO_NO_SEARCH_RESULTS);
            } else {
                info = new InfoFullscreen(InfoFullscreen.INFO_EMPTY_TASKS);
            }
            viewModel.getInfoFullscreenLive().setValue(info);
        } else {
            viewModel.getInfoFullscreenLive().setValue(null);
        }
        if (binding.recycler.getAdapter() instanceof TasksItemAdapter) {
            ((TasksItemAdapter) binding.recycler.getAdapter()).updateData(items, viewModel.getSortMode());
        } else {
            binding.recycler.setAdapter(new TasksItemAdapter(requireContext(), items, this, viewModel.getSortMode()));
        }
    });
    viewModel.getEventHandler().observeEvent(getViewLifecycleOwner(), event -> {
        if (event.getType() == Event.SNACKBAR_MESSAGE) {
            activity.showSnackbar(((SnackbarMessage) event).getSnackbar(activity, activity.binding.frameMainContainer));
        }
    });
    if (swipeBehavior == null) {
        swipeBehavior = new SwipeBehavior(activity, swipeStarted -> binding.swipe.setEnabled(!swipeStarted)) {

            @Override
            public void instantiateUnderlayButton(RecyclerView.ViewHolder viewHolder, List<UnderlayButton> underlayButtons) {
                int position = viewHolder.getAdapterPosition();
                ArrayList<Task> displayedItems = viewModel.getFilteredTasksLive().getValue();
                if (displayedItems == null || position < 0 || position >= displayedItems.size()) {
                    return;
                }
                Task task = displayedItems.get(position);
                underlayButtons.add(new UnderlayButton(R.drawable.ic_round_done, pos -> {
                    if (pos >= displayedItems.size()) {
                        return;
                    }
                    swipeBehavior.recoverLatestSwipedItem();
                    viewModel.performAction(ACTION.UNDO, displayedItems.get(pos));
                }));
            }
        };
    }
    swipeBehavior.attachToRecyclerView(binding.recycler);
    hideDisabledFeatures();
    if (savedInstanceState == null) {
        viewModel.loadFromDatabase(true);
    }
    updateUI(savedInstanceState == null);
}
Also used : TasksItemAdapter(xyz.zedler.patrick.grocy.adapter.TasksItemAdapter) Bundle(android.os.Bundle) MasterPlaceholderAdapter(xyz.zedler.patrick.grocy.adapter.MasterPlaceholderAdapter) NonNull(androidx.annotation.NonNull) InfoFullscreenHelper(xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper) MainActivity(xyz.zedler.patrick.grocy.activity.MainActivity) MenuItem(android.view.MenuItem) ArrayList(java.util.ArrayList) Event(xyz.zedler.patrick.grocy.model.Event) InfoFullscreen(xyz.zedler.patrick.grocy.model.InfoFullscreen) R(xyz.zedler.patrick.grocy.R) ActivityInfo(android.content.pm.ActivityInfo) ViewUtil(xyz.zedler.patrick.grocy.util.ViewUtil) View(android.view.View) Animation(android.view.animation.Animation) RecyclerView(androidx.recyclerview.widget.RecyclerView) ACTION(xyz.zedler.patrick.grocy.util.Constants.ACTION) ViewModelProvider(androidx.lifecycle.ViewModelProvider) LayoutInflater(android.view.LayoutInflater) AppBarBehavior(xyz.zedler.patrick.grocy.behavior.AppBarBehavior) SwipeBehavior(xyz.zedler.patrick.grocy.behavior.SwipeBehavior) Constants(xyz.zedler.patrick.grocy.util.Constants) POSITION(xyz.zedler.patrick.grocy.util.Constants.FAB.POSITION) ViewGroup(android.view.ViewGroup) FragmentTasksBinding(xyz.zedler.patrick.grocy.databinding.FragmentTasksBinding) Task(xyz.zedler.patrick.grocy.model.Task) List(java.util.List) Nullable(androidx.annotation.Nullable) ClickUtil(xyz.zedler.patrick.grocy.util.ClickUtil) TasksViewModel(xyz.zedler.patrick.grocy.viewmodel.TasksViewModel) SnackbarMessage(xyz.zedler.patrick.grocy.model.SnackbarMessage) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) Snackbar(com.google.android.material.snackbar.Snackbar) Task(xyz.zedler.patrick.grocy.model.Task) AppBarBehavior(xyz.zedler.patrick.grocy.behavior.AppBarBehavior) MasterPlaceholderAdapter(xyz.zedler.patrick.grocy.adapter.MasterPlaceholderAdapter) ArrayList(java.util.ArrayList) SwipeBehavior(xyz.zedler.patrick.grocy.behavior.SwipeBehavior) TasksViewModel(xyz.zedler.patrick.grocy.viewmodel.TasksViewModel) InfoFullscreenHelper(xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) InfoFullscreen(xyz.zedler.patrick.grocy.model.InfoFullscreen) ClickUtil(xyz.zedler.patrick.grocy.util.ClickUtil) TasksItemAdapter(xyz.zedler.patrick.grocy.adapter.TasksItemAdapter) RecyclerView(androidx.recyclerview.widget.RecyclerView) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Example 12 with InfoFullscreenHelper

use of xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper in project grocy-android by patzly.

the class ConsumeFragment method onViewCreated.

@Override
public void onViewCreated(@Nullable View view, @Nullable Bundle savedInstanceState) {
    activity = (MainActivity) requireActivity();
    ConsumeFragmentArgs args = ConsumeFragmentArgs.fromBundle(requireArguments());
    viewModel = new ViewModelProvider(this, new ConsumeViewModel.ConsumeViewModelFactory(activity.getApplication(), args)).get(ConsumeViewModel.class);
    binding.setActivity(activity);
    binding.setViewModel(viewModel);
    binding.setFragment(this);
    binding.setFormData(viewModel.getFormData());
    binding.setLifecycleOwner(getViewLifecycleOwner());
    infoFullscreenHelper = new InfoFullscreenHelper(binding.container);
    viewModel.getInfoFullscreenLive().observe(getViewLifecycleOwner(), infoFullscreen -> infoFullscreenHelper.setInfo(infoFullscreen));
    viewModel.getIsLoadingLive().observe(getViewLifecycleOwner(), isDownloading -> binding.swipe.setRefreshing(isDownloading));
    viewModel.getEventHandler().observeEvent(getViewLifecycleOwner(), event -> {
        if (event.getType() == Event.SNACKBAR_MESSAGE) {
            activity.showSnackbar(((SnackbarMessage) event).getSnackbar(activity, activity.binding.frameMainContainer));
        } else if (event.getType() == Event.CONSUME_SUCCESS) {
            assert getArguments() != null;
            if (PurchaseFragmentArgs.fromBundle(getArguments()).getCloseWhenFinished()) {
                activity.navigateUp();
            } else {
                viewModel.getFormData().clearForm();
                focusProductInputIfNecessary();
                embeddedFragmentScanner.startScannerIfVisible();
            }
        } else if (event.getType() == Event.BOTTOM_SHEET) {
            BottomSheetEvent bottomSheetEvent = (BottomSheetEvent) event;
            activity.showBottomSheet(bottomSheetEvent.getBottomSheet(), event.getBundle());
        } else if (event.getType() == Event.FOCUS_INVALID_VIEWS) {
            focusNextInvalidView();
        } else if (event.getType() == Event.QUICK_MODE_ENABLED) {
            focusProductInputIfNecessary();
        } else if (event.getType() == Event.QUICK_MODE_DISABLED) {
            clearInputFocus();
        } else if (event.getType() == Event.CONTINUE_SCANNING) {
            embeddedFragmentScanner.startScannerIfVisible();
        } else if (event.getType() == Event.CHOOSE_PRODUCT) {
            String barcode = event.getBundle().getString(ARGUMENT.BARCODE);
            navigate(ConsumeFragmentDirections.actionConsumeFragmentToChooseProductFragment(barcode).setForbidCreateProduct(true));
        }
    });
    Integer productIdSavedSate = (Integer) getFromThisDestinationNow(Constants.ARGUMENT.PRODUCT_ID);
    if (productIdSavedSate != null) {
        removeForThisDestination(Constants.ARGUMENT.PRODUCT_ID);
        viewModel.setQueueEmptyAction(() -> viewModel.setProduct(productIdSavedSate, null, null));
    } else if (NumUtil.isStringInt(args.getProductId())) {
        int productId = Integer.parseInt(args.getProductId());
        setArguments(new ConsumeFragmentArgs.Builder(args).setProductId(null).build().toBundle());
        viewModel.setQueueEmptyAction(() -> viewModel.setProduct(productId, null, null));
    }
    String barcode = (String) getFromThisDestinationNow(ARGUMENT.BARCODE);
    if (barcode != null) {
        removeForThisDestination(Constants.ARGUMENT.BARCODE);
        viewModel.addBarcodeToExistingProduct(barcode);
    }
    embeddedFragmentScanner.setScannerVisibilityLive(viewModel.getFormData().getScannerVisibilityLive());
    // following line is necessary because no observers are set in Views
    viewModel.getFormData().getQuantityUnitStockLive().observe(getViewLifecycleOwner(), i -> {
    });
    viewModel.getFormData().getProductDetailsLive().observe(getViewLifecycleOwner(), productDetails -> {
        MenuItem menuItem = activity.getBottomMenu().findItem(R.id.action_open);
        if (productDetails != null && productDetails.getProduct().getEnableTareWeightHandlingBoolean() || menuItem == null || !viewModel.isFeatureEnabled(PREF.FEATURE_STOCK_OPENED_TRACKING)) {
            return;
        }
        menuItem.setVisible(productDetails != null);
    });
    if (savedInstanceState == null) {
        viewModel.loadFromDatabase(true);
    }
    focusProductInputIfNecessary();
    updateUI(args.getAnimateStart() && savedInstanceState == null);
}
Also used : BottomSheetEvent(xyz.zedler.patrick.grocy.model.BottomSheetEvent) ConsumeViewModel(xyz.zedler.patrick.grocy.viewmodel.ConsumeViewModel) MenuItem(android.view.MenuItem) InfoFullscreenHelper(xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Example 13 with InfoFullscreenHelper

use of xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper in project grocy-android by patzly.

the class MasterDataOverviewFragment method onViewCreated.

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    activity = (MainActivity) requireActivity();
    viewModel = new ViewModelProvider(this).get(MasterDataOverviewViewModel.class);
    viewModel.setOfflineLive(!activity.isOnline());
    binding.back.setOnClickListener(v -> activity.navigateUp());
    binding.linearProducts.setOnClickListener(v -> navigate(MasterDataOverviewFragmentDirections.actionMasterDataOverviewFragmentToMasterObjectListFragment(GrocyApi.ENTITY.PRODUCTS)));
    binding.linearQuantityUnits.setOnClickListener(v -> navigate(MasterDataOverviewFragmentDirections.actionMasterDataOverviewFragmentToMasterObjectListFragment(GrocyApi.ENTITY.QUANTITY_UNITS)));
    binding.linearLocations.setOnClickListener(v -> navigate(MasterDataOverviewFragmentDirections.actionMasterDataOverviewFragmentToMasterObjectListFragment(GrocyApi.ENTITY.LOCATIONS)));
    binding.linearProductGroups.setOnClickListener(v -> navigate(MasterDataOverviewFragmentDirections.actionMasterDataOverviewFragmentToMasterObjectListFragment(GrocyApi.ENTITY.PRODUCT_GROUPS)));
    binding.linearStores.setOnClickListener(v -> navigate(MasterDataOverviewFragmentDirections.actionMasterDataOverviewFragmentToMasterObjectListFragment(GrocyApi.ENTITY.STORES)));
    binding.linearTaskCategories.setOnClickListener(v -> navigate(MasterDataOverviewFragmentDirections.actionMasterDataOverviewFragmentToMasterObjectListFragment(GrocyApi.ENTITY.TASK_CATEGORIES)));
    viewModel.getIsLoadingLive().observe(getViewLifecycleOwner(), state -> {
        binding.swipe.setRefreshing(state);
        if (!state) {
            viewModel.setCurrentQueueLoading(null);
        }
    });
    binding.swipe.setOnRefreshListener(() -> viewModel.downloadDataForceUpdate());
    binding.swipe.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(activity, R.color.surface));
    binding.swipe.setColorSchemeColors(ContextCompat.getColor(activity, R.color.secondary));
    viewModel.getEventHandler().observeEvent(getViewLifecycleOwner(), event -> {
        if (event.getType() == Event.SNACKBAR_MESSAGE) {
            activity.showSnackbar(((SnackbarMessage) event).getSnackbar(activity, activity.binding.frameMainContainer));
        }
    });
    infoFullscreenHelper = new InfoFullscreenHelper(binding.frameContainer);
    viewModel.getInfoFullscreenLive().observe(getViewLifecycleOwner(), infoFullscreen -> infoFullscreenHelper.setInfo(infoFullscreen));
    viewModel.getOfflineLive().observe(getViewLifecycleOwner(), this::appBarOfflineInfo);
    viewModel.getProductsLive().observe(getViewLifecycleOwner(), products -> binding.countProducts.setText(products != null ? String.valueOf(products.size()) : getString(R.string.subtitle_unknown)));
    viewModel.getLocationsLive().observe(getViewLifecycleOwner(), locations -> binding.countLocations.setText(locations != null ? String.valueOf(locations.size()) : getString(R.string.subtitle_unknown)));
    viewModel.getStoresLive().observe(getViewLifecycleOwner(), stores -> binding.countStores.setText(stores != null ? String.valueOf(stores.size()) : getString(R.string.subtitle_unknown)));
    viewModel.getQuantityUnitsLive().observe(getViewLifecycleOwner(), quantityUnits -> binding.countQuantityUnits.setText(quantityUnits != null ? String.valueOf(quantityUnits.size()) : getString(R.string.subtitle_unknown)));
    viewModel.getProductGroupsLive().observe(getViewLifecycleOwner(), productGroups -> binding.countProductGroups.setText(productGroups != null ? String.valueOf(productGroups.size()) : getString(R.string.subtitle_unknown)));
    viewModel.getTaskCategoriesLive().observe(getViewLifecycleOwner(), taskCategories -> binding.countTaskCategories.setText(taskCategories != null ? String.valueOf(taskCategories.size()) : getString(R.string.subtitle_unknown)));
    // for offline info in app bar
    binding.swipe.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
    if (savedInstanceState == null) {
        viewModel.loadFromDatabase(true);
    }
    hideDisabledFeatures();
    // UPDATE UI
    updateUI((getArguments() == null || getArguments().getBoolean(Constants.ARGUMENT.ANIMATED, true)) && savedInstanceState == null);
}
Also used : MasterDataOverviewViewModel(xyz.zedler.patrick.grocy.viewmodel.MasterDataOverviewViewModel) InfoFullscreenHelper(xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Example 14 with InfoFullscreenHelper

use of xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper in project grocy-android by patzly.

the class MasterProductCatLocationFragment method onViewCreated.

@Override
public void onViewCreated(@Nullable View view, @Nullable Bundle savedInstanceState) {
    activity = (MainActivity) requireActivity();
    MasterProductFragmentArgs args = MasterProductFragmentArgs.fromBundle(requireArguments());
    viewModel = new ViewModelProvider(this, new MasterProductCatLocationViewModel.MasterProductCatLocationViewModelFactory(activity.getApplication(), args)).get(MasterProductCatLocationViewModel.class);
    binding.setActivity(activity);
    binding.setFormData(viewModel.getFormData());
    binding.setViewModel(viewModel);
    binding.setFragment(this);
    binding.setLifecycleOwner(getViewLifecycleOwner());
    viewModel.getEventHandler().observeEvent(getViewLifecycleOwner(), event -> {
        if (event.getType() == Event.SNACKBAR_MESSAGE) {
            SnackbarMessage message = (SnackbarMessage) event;
            Snackbar snack = message.getSnackbar(activity, activity.binding.frameMainContainer);
            activity.showSnackbar(snack);
        } else if (event.getType() == Event.NAVIGATE_UP) {
            activity.navigateUp();
        } else if (event.getType() == Event.SET_SHOPPING_LIST_ID) {
            int id = event.getBundle().getInt(Constants.ARGUMENT.SELECTED_ID);
            setForDestination(R.id.shoppingListFragment, Constants.ARGUMENT.SELECTED_ID, id);
        } else if (event.getType() == Event.BOTTOM_SHEET) {
            BottomSheetEvent bottomSheetEvent = (BottomSheetEvent) event;
            activity.showBottomSheet(bottomSheetEvent.getBottomSheet(), event.getBundle());
        }
    });
    infoFullscreenHelper = new InfoFullscreenHelper(binding.container);
    viewModel.getInfoFullscreenLive().observe(getViewLifecycleOwner(), infoFullscreen -> infoFullscreenHelper.setInfo(infoFullscreen));
    viewModel.getIsLoadingLive().observe(getViewLifecycleOwner(), isLoading -> {
        if (!isLoading) {
            viewModel.setCurrentQueueLoading(null);
        }
    });
    if (savedInstanceState == null) {
        viewModel.loadFromDatabase(true);
    }
    updateUI(savedInstanceState == null);
}
Also used : SnackbarMessage(xyz.zedler.patrick.grocy.model.SnackbarMessage) BottomSheetEvent(xyz.zedler.patrick.grocy.model.BottomSheetEvent) InfoFullscreenHelper(xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper) ViewModelProvider(androidx.lifecycle.ViewModelProvider) MasterProductCatLocationViewModel(xyz.zedler.patrick.grocy.viewmodel.MasterProductCatLocationViewModel) Snackbar(com.google.android.material.snackbar.Snackbar)

Example 15 with InfoFullscreenHelper

use of xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper in project grocy-android by patzly.

the class MasterProductCatQuantityUnitFragment method onViewCreated.

@Override
public void onViewCreated(@Nullable View view, @Nullable Bundle savedInstanceState) {
    activity = (MainActivity) requireActivity();
    MasterProductFragmentArgs args = MasterProductFragmentArgs.fromBundle(requireArguments());
    viewModel = new ViewModelProvider(this, new MasterProductCatQuantityUnitViewModel.MasterProductCatQuantityUnitViewModelFactory(activity.getApplication(), args)).get(MasterProductCatQuantityUnitViewModel.class);
    binding.setActivity(activity);
    binding.setFormData(viewModel.getFormData());
    binding.setViewModel(viewModel);
    binding.setFragment(this);
    binding.setLifecycleOwner(getViewLifecycleOwner());
    viewModel.getEventHandler().observeEvent(getViewLifecycleOwner(), event -> {
        if (event.getType() == Event.SNACKBAR_MESSAGE) {
            SnackbarMessage message = (SnackbarMessage) event;
            Snackbar snack = message.getSnackbar(activity, activity.binding.frameMainContainer);
            activity.showSnackbar(snack);
        } else if (event.getType() == Event.NAVIGATE_UP) {
            activity.navigateUp();
        } else if (event.getType() == Event.SET_SHOPPING_LIST_ID) {
            int id = event.getBundle().getInt(Constants.ARGUMENT.SELECTED_ID);
            setForDestination(R.id.shoppingListFragment, Constants.ARGUMENT.SELECTED_ID, id);
        } else if (event.getType() == Event.BOTTOM_SHEET) {
            BottomSheetEvent bottomSheetEvent = (BottomSheetEvent) event;
            activity.showBottomSheet(bottomSheetEvent.getBottomSheet(), event.getBundle());
        }
    });
    infoFullscreenHelper = new InfoFullscreenHelper(binding.container);
    viewModel.getInfoFullscreenLive().observe(getViewLifecycleOwner(), infoFullscreen -> infoFullscreenHelper.setInfo(infoFullscreen));
    viewModel.getIsLoadingLive().observe(getViewLifecycleOwner(), isLoading -> {
        if (!isLoading) {
            viewModel.setCurrentQueueLoading(null);
        }
    });
    if (savedInstanceState == null) {
        viewModel.loadFromDatabase(true);
    }
    updateUI(savedInstanceState == null);
}
Also used : SnackbarMessage(xyz.zedler.patrick.grocy.model.SnackbarMessage) BottomSheetEvent(xyz.zedler.patrick.grocy.model.BottomSheetEvent) InfoFullscreenHelper(xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper) MasterProductCatQuantityUnitViewModel(xyz.zedler.patrick.grocy.viewmodel.MasterProductCatQuantityUnitViewModel) ViewModelProvider(androidx.lifecycle.ViewModelProvider) Snackbar(com.google.android.material.snackbar.Snackbar)

Aggregations

ViewModelProvider (androidx.lifecycle.ViewModelProvider)23 InfoFullscreenHelper (xyz.zedler.patrick.grocy.helper.InfoFullscreenHelper)23 BottomSheetEvent (xyz.zedler.patrick.grocy.model.BottomSheetEvent)16 SnackbarMessage (xyz.zedler.patrick.grocy.model.SnackbarMessage)15 Snackbar (com.google.android.material.snackbar.Snackbar)14 InfoFullscreen (xyz.zedler.patrick.grocy.model.InfoFullscreen)9 ClickUtil (xyz.zedler.patrick.grocy.util.ClickUtil)8 LinearLayoutManager (androidx.recyclerview.widget.LinearLayoutManager)7 MenuItem (android.view.MenuItem)4 MasterPlaceholderAdapter (xyz.zedler.patrick.grocy.adapter.MasterPlaceholderAdapter)4 AppBarBehavior (xyz.zedler.patrick.grocy.behavior.AppBarBehavior)4 Bundle (android.os.Bundle)3 Handler (android.os.Handler)3 LayoutInflater (android.view.LayoutInflater)3 View (android.view.View)3 ViewGroup (android.view.ViewGroup)3 NonNull (androidx.annotation.NonNull)3 Nullable (androidx.annotation.Nullable)3 DefaultItemAnimator (androidx.recyclerview.widget.DefaultItemAnimator)3 RecyclerView (androidx.recyclerview.widget.RecyclerView)3