├── .gitignore
├── LICENSE
├── README.md
├── app
├── build.gradle.kts
├── libs
│ ├── ffmpeg-core.aar
│ └── ffmpeg-native.aar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── projectmaterial
│ │ └── videos
│ │ ├── activity
│ │ ├── CollectionActivity.java
│ │ ├── SettingsActivity.java
│ │ ├── VideoLibraryActivity.java
│ │ └── base
│ │ │ ├── BaseActivity.java
│ │ │ └── BaseSettingsActivity.java
│ │ ├── adapter
│ │ ├── CollectionAdapter.java
│ │ ├── FavoriteVideoAdapter.java
│ │ ├── MenuItemAdapter.java
│ │ ├── MoreInfoAdapter.java
│ │ ├── VideoAdapter.java
│ │ └── base
│ │ │ └── BaseVideoAdapter.java
│ │ ├── app
│ │ └── VideoApplication.java
│ │ ├── behavior
│ │ └── FragmentContainerViewBehavior.java
│ │ ├── bottomsheet
│ │ ├── BottomSheetUtils.java
│ │ ├── CollectionSortingDialogFragment.java
│ │ └── VideoSortingDialogFragment.java
│ │ ├── comparator
│ │ ├── CollectionComparatorDate.java
│ │ ├── CollectionComparatorName.java
│ │ ├── CollectionComparatorVideoCount.java
│ │ ├── VideoComparatorDate.java
│ │ ├── VideoComparatorDuration.java
│ │ ├── VideoComparatorName.java
│ │ └── VideoComparatorSize.java
│ │ ├── database
│ │ ├── Collection.java
│ │ └── Video.java
│ │ ├── fragment
│ │ ├── CollectionFragment.java
│ │ ├── CollectionsFragment.java
│ │ ├── FavoritesFragment.java
│ │ ├── SettingsFragment.java
│ │ ├── VideosFragment.java
│ │ └── base
│ │ │ └── BaseFragment.java
│ │ ├── model
│ │ ├── MenuItem.java
│ │ └── MoreInfo.java
│ │ ├── recyclerview
│ │ ├── GridLayoutItemDecoration.java
│ │ ├── GridSpacingItemDecoration.java
│ │ ├── LinearLayoutItemDecoration.java
│ │ ├── NonScrollableGridLayoutManager.java
│ │ └── NonScrollableLinearLayoutManager.java
│ │ ├── util
│ │ ├── AdapterUtils.java
│ │ ├── BitmapCache.java
│ │ ├── BottomSheetDialogUtils.java
│ │ ├── CollectionUtils.java
│ │ ├── DialogUtils.java
│ │ ├── GeneralUtils.java
│ │ ├── LayoutType.java
│ │ ├── MediaMetadataHelper.java
│ │ ├── SortingCriteria.java
│ │ ├── SortingOrder.java
│ │ ├── SortingUtils.java
│ │ ├── ThumbnailLoader.java
│ │ ├── VideoOptionUtils.java
│ │ └── VideoUtils.java
│ │ ├── viewholder
│ │ ├── CollectionViewHolder.java
│ │ └── VideoViewHolder.java
│ │ ├── viewmodel
│ │ ├── CollectionViewModel.java
│ │ ├── FavoriteVideoViewModel.java
│ │ └── VideoViewModel.java
│ │ ├── widget
│ │ └── EmptyStateView.java
│ │ └── worker
│ │ └── VideoFetchWorker.java
│ └── res
│ ├── drawable-anydpi
│ ├── ic_launcher_foreground.xml
│ └── ic_launcher_monochrome.xml
│ ├── drawable
│ ├── bottom_nav_folders.xml
│ ├── bottom_nav_starred.xml
│ ├── bottom_nav_videos.xml
│ ├── empty_state_view_collections.xml
│ ├── empty_state_view_favorites.xml
│ ├── empty_state_view_videos.xml
│ ├── moreinfo_background.xml
│ ├── placeholder_thumbnail.xml
│ ├── placeholder_thumbnail_icon.xml
│ ├── projectx_selectable_item_background.xml
│ ├── quantum_ic_animated_images_vd_theme_24.xml
│ ├── quantum_ic_arrow_back_vd_theme_24.xml
│ ├── quantum_ic_calendar_clock_vd_theme_24.xml
│ ├── quantum_ic_check_vd_theme_24.xml
│ ├── quantum_ic_delete_vd_theme_24.xml
│ ├── quantum_ic_edit_vd_theme_24.xml
│ ├── quantum_ic_folder_filled_vd_theme_24.xml
│ ├── quantum_ic_folder_vd_theme_24.xml
│ ├── quantum_ic_grid_view_vd_theme_24.xml
│ ├── quantum_ic_info_vd_theme_24.xml
│ ├── quantum_ic_more_vert_vd_theme_24.xml
│ ├── quantum_ic_movie_filled_vd_theme_24.xml
│ ├── quantum_ic_movie_vd_theme_24.xml
│ ├── quantum_ic_settings_vd_theme_24.xml
│ ├── quantum_ic_share_vd_theme_24.xml
│ ├── quantum_ic_sort_vd_theme_24.xml
│ ├── quantum_ic_star_filled_vd_theme_24.xml
│ ├── quantum_ic_star_vd_theme_24.xml
│ ├── quantum_ic_straighten_vd_theme_24.xml
│ ├── quantum_ic_text_fields_vd_theme_24.xml
│ ├── quantum_ic_view_agenda_vd_theme_24.xml
│ ├── quantum_ic_weight_vd_theme_24.xml
│ └── quantum_splashscreen_icon.xml
│ ├── layout
│ ├── activity_collection.xml
│ ├── activity_main.xml
│ ├── activity_settings.xml
│ ├── bottom_sheet_moreinfo_collection.xml
│ ├── bottom_sheet_moreinfo_video.xml
│ ├── bottom_sheet_options_menu.xml
│ ├── bottom_sheet_sorting_collection.xml
│ ├── bottom_sheet_sorting_video.xml
│ ├── collapsing_toolbar_base_layout.xml
│ ├── collapsing_toolbar_content_layout.xml
│ ├── dialog_rename.xml
│ ├── empty_state_view.xml
│ ├── fragment_collection.xml
│ ├── fragment_collections.xml
│ ├── fragment_favorites.xml
│ ├── fragment_videos.xml
│ ├── item_collection_grid.xml
│ ├── item_collection_list.xml
│ ├── item_filter.xml
│ ├── item_video.xml
│ ├── menu_item_view.xml
│ └── moreinfo_item_view.xml
│ ├── menu
│ ├── menu_collections.xml
│ ├── menu_favorites.xml
│ ├── menu_navigation.xml
│ └── menu_videos.xml
│ ├── mipmap-anydpi
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── navigation
│ └── main_nav.xml
│ ├── values-en-rGB
│ └── strings.xml
│ ├── values-in
│ └── strings.xml
│ ├── values-night
│ ├── colors.xml
│ └── themes.xml
│ ├── values-pt-rBR
│ └── strings.xml
│ ├── values-ru
│ └── strings.xml
│ ├── values-zh-rCN
│ └── strings.xml
│ ├── values
│ ├── arrays.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── themes.xml
│ └── xml
│ ├── file_paths.xml
│ ├── locales_config.xml
│ └── preferences.xml
├── build.gradle.kts
├── components
├── build.gradle.kts
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── projectmaterial
│ │ └── widget
│ │ └── MaterialCheckedTextView.java
│ └── res
│ ├── color
│ ├── m3_checked_text_background_color.xml
│ ├── m3_checked_text_icon_tint.xml
│ ├── m3_checked_text_ripple_color.xml
│ └── m3_checked_text_text_color.xml
│ ├── drawable
│ └── quantum_ic_check_vd_theme_24.xml
│ ├── layout
│ └── m3_alert_select_dialog_singlechoice.xml
│ └── values
│ ├── attrs.xml
│ ├── dimens.xml
│ ├── styles.xml
│ └── themes.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── preference
├── build.gradle.kts
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── projectmaterial
│ │ └── preference
│ │ ├── M3EditTextPreference.java
│ │ ├── M3EditTextPreferenceDialogFragment.java
│ │ ├── M3FooterPreference.java
│ │ ├── M3ListPreferenceDialogFragment.java
│ │ ├── M3MultiSelectListPreferenceDialogFragment.java
│ │ ├── M3PreferenceDialogFragment.java
│ │ ├── M3PreferenceFragment.java
│ │ └── M3TopIntroPreference.java
│ └── res
│ ├── drawable
│ └── quantum_ic_info_vd_theme_24.xml
│ ├── layout-v33
│ ├── m3_preference.xml
│ ├── m3_preference_footer.xml
│ └── m3_preference_top_intro.xml
│ ├── layout
│ ├── m3_icon_frame.xml
│ ├── m3_preference.xml
│ ├── m3_preference_dialog_edittext.xml
│ ├── m3_preference_footer.xml
│ ├── m3_preference_top_intro.xml
│ └── m3_preference_widget_switch_compat.xml
│ └── values
│ ├── attrs.xml
│ ├── bools.xml
│ ├── styles.xml
│ ├── themes.xml
│ └── tokens.xml
└── settings.gradle.kts
/.gitignore:
--------------------------------------------------------------------------------
1 | # Gradle files
2 | .gradle/
3 | build/
4 |
5 | # Local configuration file (sdk path, etc)
6 | local.properties
7 |
8 | # Log/OS Files
9 | *.log
10 |
11 | # Android Studio generated files and folders
12 | captures/
13 | .externalNativeBuild/
14 | .cxx/
15 | *.apk
16 | output.json
17 |
18 | # IntelliJ
19 | *.iml
20 | .idea/
21 | misc.xml
22 | deploymentTargetDropDown.xml
23 | render.experimental.xml
24 |
25 | # Keystore files
26 | *.jks
27 | *.keystore
28 |
29 | # Google Services (e.g. APIs or Firebase)
30 | google-services.json
31 |
32 | # Android Profiling
33 | *.hprof
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Videos
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | An application designed to elegantly display and organize videos stored locally on your device, featuring a refined and intuitive user interface.
13 |
14 | ## Features
15 | - Modern Material 3 Design
16 | - Utilizes MediaStore and FFmpeg for swift metadata retrieval
17 | - Ability to rename, share, or delete directly within the app
18 |
19 | ## Screenshots
20 | |  |  |  |
21 | |---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
22 | |  |  |  |
23 |
24 | ## License
25 | This project is licensed under the GNU General Public License v3.0. For further details, please refer to the [LICENSE](https://github.com/project-material/Videos/blob/main/LICENSE) file.
26 |
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | id("androidx.navigation.safeargs")
4 | }
5 |
6 | android {
7 | namespace = "com.projectmaterial.videos"
8 | compileSdk = 34
9 | buildToolsVersion = "34.0.4"
10 |
11 | defaultConfig {
12 | applicationId = "com.projectmaterial.videos"
13 | minSdk = 31
14 | targetSdk = 34
15 | versionCode = 1023
16 | versionName = "1.0.2-beta03"
17 |
18 | ndk {
19 | abiFilters += listOf("arm64-v8a")
20 | }
21 |
22 | vectorDrawables {
23 | useSupportLibrary = true
24 | }
25 | }
26 |
27 | dependenciesInfo {
28 | includeInApk = false
29 | }
30 |
31 | packaging {
32 | dex {
33 | useLegacyPackaging = false
34 | }
35 |
36 | jniLibs {
37 | useLegacyPackaging = false
38 | }
39 |
40 | resources {
41 | excludes += "META-INF/**"
42 | excludes += "com/**"
43 | excludes += "kotlin/**"
44 | excludes += "okhttp3/**"
45 | excludes += "**.properties"
46 | excludes += "**.bin"
47 | }
48 | }
49 |
50 | compileOptions {
51 | sourceCompatibility = JavaVersion.VERSION_17
52 | targetCompatibility = JavaVersion.VERSION_17
53 | }
54 |
55 | buildTypes {
56 | getByName("release") {
57 | isMinifyEnabled = true
58 | isShrinkResources = true
59 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
60 | }
61 | }
62 | }
63 |
64 | dependencies {
65 | implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
66 | implementation(project(":preference"))
67 | implementation("androidx.activity:activity:1.9.3")
68 | implementation("androidx.appcompat:appcompat:1.7.0")
69 | implementation("androidx.collection:collection:1.4.5")
70 | implementation("androidx.constraintlayout:constraintlayout:2.2.0")
71 | implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0")
72 | implementation("androidx.core:core:1.13.1")
73 | implementation("androidx.fragment:fragment:1.6.2")
74 | implementation("androidx.navigation:navigation-fragment:2.8.4")
75 | implementation("androidx.navigation:navigation-ui:2.8.4")
76 | implementation("androidx.preference:preference:1.2.1")
77 | implementation("androidx.recyclerview:recyclerview:1.3.2")
78 | implementation("androidx.work:work-runtime:2.9.1")
79 | implementation("com.github.bumptech.glide:glide:4.16.0")
80 | implementation("com.google.android.material:material:1.13.0-alpha08")
81 | }
--------------------------------------------------------------------------------
/app/libs/ffmpeg-core.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/project-material/Videos/7ed3c9f8def8c197a2c4b5c6d74f1e2ebbe17190/app/libs/ffmpeg-core.aar
--------------------------------------------------------------------------------
/app/libs/ffmpeg-native.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/project-material/Videos/7ed3c9f8def8c197a2c4b5c6d74f1e2ebbe17190/app/libs/ffmpeg-native.aar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | -keep class wseemann.media.FFmpegMediaMetadataRetriever {
24 | *;
25 | }
26 |
27 | -keep class wseemann.media.** { *; }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
40 |
45 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/projectmaterial/videos/activity/CollectionActivity.java:
--------------------------------------------------------------------------------
1 | package com.projectmaterial.videos.activity;
2 |
3 | import android.os.Bundle;
4 | import android.view.MenuItem;
5 | import androidx.activity.EdgeToEdge;
6 | import androidx.annotation.NonNull;
7 | import androidx.annotation.Nullable;
8 | import androidx.appcompat.widget.Toolbar;
9 | import androidx.coordinatorlayout.widget.CoordinatorLayout;
10 | import com.google.android.material.snackbar.Snackbar;
11 | import com.projectmaterial.videos.R;
12 | import com.projectmaterial.videos.activity.base.BaseActivity;
13 | import com.projectmaterial.videos.fragment.CollectionFragment;
14 | import com.projectmaterial.videos.util.CollectionUtils;
15 |
16 | public class CollectionActivity extends BaseActivity {
17 |
18 | private CoordinatorLayout coordinator;
19 |
20 | @Override
21 | protected void onCreate(@Nullable Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setCurrentActivity(this);
24 | setContentView(R.layout.activity_collection);
25 |
26 | String collectionKey = getIntent().getStringExtra("collection_key");
27 |
28 | coordinator = findViewById(R.id.coordinator);
29 | coordinator.setBackgroundColor(getColor(coordinator, R.attr.colorSurface));
30 |
31 | Toolbar toolbar = findViewById(R.id.toolbar);
32 | toolbar.setNavigationIcon(R.drawable.quantum_ic_arrow_back_vd_theme_24);
33 | toolbar.setTitle(CollectionUtils.getCollectionName(this, collectionKey));
34 | setSupportActionBar(toolbar);
35 |
36 | getSupportFragmentManager()
37 | .beginTransaction()
38 | .replace(R.id.fragment_container, CollectionFragment.newInstance(collectionKey))
39 | .commitNow();
40 | }
41 |
42 | @Override
43 | public boolean onOptionsItemSelected(MenuItem item) {
44 | switch (item.getItemId()) {
45 | case android.R.id.home:
46 | finishAfterTransition();
47 | return true;
48 | default:
49 | return super.onOptionsItemSelected(item);
50 | }
51 | }
52 |
53 | public void showSnackbar(@NonNull CharSequence message) {
54 | Snackbar.make(coordinator, message, Snackbar.LENGTH_SHORT).show();
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/projectmaterial/videos/activity/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | package com.projectmaterial.videos.activity;
2 |
3 | import android.os.Bundle;
4 | import androidx.annotation.Nullable;
5 | import com.projectmaterial.videos.R;
6 | import com.projectmaterial.videos.activity.base.BaseSettingsActivity;
7 | import com.projectmaterial.videos.fragment.SettingsFragment;
8 |
9 | public class SettingsActivity extends BaseSettingsActivity {
10 |
11 | private SettingsFragment settingsFragment;
12 |
13 | @Override
14 | protected void onCreate(@Nullable Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | settingsFragment = new SettingsFragment();
17 | getSupportFragmentManager()
18 | .beginTransaction()
19 | .replace(R.id.fragment_container, settingsFragment)
20 | .commitNow();
21 | }
22 |
23 | @Override
24 | protected void onStart() {
25 | super.onStart();
26 | setTitle(R.string.settings);
27 | }
28 |
29 | @Override
30 | protected void restart() {
31 | if (settingsFragment.isPreferenceChanged()) {
32 | try {
33 | finish();
34 | overrideTransition();
35 | startActivity(getIntent());
36 | overrideTransition();
37 | } catch (Throwable e) {
38 | e.printStackTrace();
39 | recreate();
40 | }
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/projectmaterial/videos/activity/base/BaseSettingsActivity.java:
--------------------------------------------------------------------------------
1 | package com.projectmaterial.videos.activity.base;
2 |
3 | import android.content.res.Configuration;
4 | import android.content.res.Resources;
5 | import android.graphics.text.LineBreakConfig;
6 | import android.os.Build;
7 | import android.os.Bundle;
8 | import android.text.Layout;
9 | import android.view.MenuItem;
10 | import androidx.annotation.NonNull;
11 | import androidx.annotation.Nullable;
12 | import androidx.appcompat.widget.Toolbar;
13 | import androidx.coordinatorlayout.widget.CoordinatorLayout;
14 | import com.google.android.material.appbar.AppBarLayout;
15 | import com.google.android.material.appbar.CollapsingToolbarLayout;
16 | import com.projectmaterial.videos.R;
17 |
18 | public class BaseSettingsActivity extends BaseActivity {
19 |
20 | @Override
21 | protected void onCreate(@Nullable Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_settings);
24 |
25 | AppBarLayout appBar = findViewById(R.id.app_bar);
26 | AppBarLayout.Behavior appBarBehavior = new AppBarLayout.Behavior();
27 | appBarBehavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
28 | @Override
29 | public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
30 | Resources resources = appBarLayout.getResources();
31 | Configuration configuration = resources.getConfiguration();
32 | return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE;
33 | }
34 | });
35 |
36 | CoordinatorLayout coordinator = findViewById(R.id.coordinator);
37 | coordinator.setBackgroundColor(getColor(coordinator, R.attr.colorSurface));
38 | CoordinatorLayout.LayoutParams coordinatorParams = (CoordinatorLayout.LayoutParams) appBar.getLayoutParams();
39 | coordinatorParams.setBehavior(appBarBehavior);
40 |
41 | CollapsingToolbarLayout collapsingToolbar = findViewById(R.id.collapsing_toolbar);
42 | collapsingToolbar.setLineSpacingMultiplier(1.1f);
43 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
44 | collapsingToolbar.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL_FAST);
45 | collapsingToolbar.setStaticLayoutBuilderConfigurer(staticLayoutBuilderConfigurer -> {
46 | staticLayoutBuilderConfigurer.setLineBreakConfig(new LineBreakConfig.Builder()
47 | .setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE)
48 | .build());
49 | });
50 | }
51 |
52 | Toolbar toolbar = findViewById(R.id.toolbar);
53 | toolbar.setNavigationIcon(R.drawable.quantum_ic_arrow_back_vd_theme_24);
54 | setSupportActionBar(toolbar);
55 | }
56 |
57 | @Override
58 | public boolean onOptionsItemSelected(MenuItem item) {
59 | switch (item.getItemId()) {
60 | case android.R.id.home:
61 | finishAfterTransition();
62 | return true;
63 | default:
64 | return super.onOptionsItemSelected(item);
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/projectmaterial/videos/adapter/MenuItemAdapter.java:
--------------------------------------------------------------------------------
1 | package com.projectmaterial.videos.adapter;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 | import androidx.annotation.NonNull;
9 | import androidx.recyclerview.widget.RecyclerView;
10 | import com.projectmaterial.videos.R;
11 | import com.projectmaterial.videos.model.MenuItem;
12 | import java.util.List;
13 |
14 | public class MenuItemAdapter extends RecyclerView.Adapter {
15 | private final List