From f978d307a9b62169b85fc3846f2c6a7b52ac5296 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Nov 2020 20:20:37 +0100 Subject: [PATCH] Converted nav list to RecyclerView --- .../antennapod/adapter/NavListAdapter.java | 212 +++++++----------- .../fragment/NavDrawerFragment.java | 118 +++++----- app/src/main/res/layout/nav_list.xml | 2 +- 3 files changed, 145 insertions(+), 187 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java index 300687e70..74ffd8d9b 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -1,20 +1,19 @@ package de.danoeh.antennapod.adapter; import android.app.Activity; -import android.content.Context; import android.content.SharedPreferences; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import android.util.TypedValue; -import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; +import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; @@ -44,10 +43,9 @@ import java.util.List; /** * BaseAdapter for the navigation drawer */ -public class NavListAdapter extends BaseAdapter +public class NavListAdapter extends RecyclerView.Adapter implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final int VIEW_TYPE_COUNT = 3; public static final int VIEW_TYPE_NAV = 0; public static final int VIEW_TYPE_SECTION_DIVIDER = 1; private static final int VIEW_TYPE_SUBSCRIPTION = 2; @@ -145,9 +143,8 @@ public class NavListAdapter extends BaseAdapter return Collections.unmodifiableList(fragmentTags); } - @Override - public int getCount() { + public int getItemCount() { int baseCount = getSubscriptionOffset(); if (showSubscriptionList) { baseCount += itemAccess.getCount(); @@ -155,18 +152,6 @@ public class NavListAdapter extends BaseAdapter return baseCount; } - @Override - public Object getItem(int position) { - int viewType = getItemViewType(position); - if (viewType == VIEW_TYPE_NAV) { - return getLabel(fragmentTags.get(position)); - } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { - return ""; - } else { - return itemAccess.getItem(position); - } - } - @Override public long getItemId(int position) { int viewType = getItemViewType(position); @@ -177,11 +162,6 @@ public class NavListAdapter extends BaseAdapter } } - @Override - public boolean hasStableIds() { - return true; - } - @Override public int getItemViewType(int position) { if (0 <= position && position < fragmentTags.size()) { @@ -193,68 +173,59 @@ public class NavListAdapter extends BaseAdapter } } - @Override - public int getViewTypeCount() { - return VIEW_TYPE_COUNT; - } - public int getSubscriptionOffset() { return fragmentTags.size() > 0 ? fragmentTags.size() + 1 : 0; } + @NonNull + @Override + public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_NAV) { + return new NavHolder(View.inflate(activity.get(), R.layout.nav_listitem, null)); + } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { + return new DividerHolder(View.inflate(activity.get(), R.layout.nav_section_item, null)); + } else { + return new FeedHolder(View.inflate(activity.get(), R.layout.nav_listitem, null)); + } + } @Override - public View getView(int position, View convertView, ViewGroup parent) { + public void onBindViewHolder(@NonNull Holder holder, int position) { int viewType = getItemViewType(position); - View v; if (viewType == VIEW_TYPE_NAV) { - v = getNavView((String) getItem(position), position, convertView, parent); + bindNavView(getLabel(fragmentTags.get(position)), position, (NavHolder) holder); } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { - v = getSectionDividerView(convertView, parent); + bindSectionDivider((DividerHolder) holder); } else { int itemPos = position - getSubscriptionOffset(); NavDrawerData.DrawerItem item = itemAccess.getItem(itemPos); if (item.type == NavDrawerData.DrawerItem.Type.FEED) { - v = getFeedView((NavDrawerData.FeedDrawerItem) item, convertView, parent); + bindFeedView((NavDrawerData.FeedDrawerItem) item, (FeedHolder) holder); } else { - v = getFolderView((NavDrawerData.FolderDrawerItem) item, convertView, parent); + bindFolderView((NavDrawerData.FolderDrawerItem) item, (FeedHolder) holder); } } - if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) { + if (viewType != VIEW_TYPE_SECTION_DIVIDER) { TypedValue typedValue = new TypedValue(); if (position == itemAccess.getSelectedItemIndex()) { - v.getContext().getTheme().resolveAttribute(R.attr.drawer_activated_color, typedValue, true); - v.setBackgroundResource(typedValue.resourceId); + activity.get().getTheme().resolveAttribute(R.attr.drawer_activated_color, typedValue, true); + holder.itemView.setBackgroundResource(typedValue.resourceId); } else { - v.getContext().getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true); - v.setBackgroundResource(typedValue.resourceId); + activity.get().getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true); + holder.itemView.setBackgroundResource(typedValue.resourceId); } + + holder.itemView.setOnClickListener(v -> itemAccess.onItemClick(position)); + holder.itemView.setOnLongClickListener(v -> itemAccess.onItemLongClick(position)); } - return v; } - private View getNavView(String title, int position, View convertView, ViewGroup parent) { + private void bindNavView(String title, int position, NavHolder holder) { Activity context = activity.get(); if(context == null) { - return null; + return; } - NavHolder holder; - if (convertView == null) { - holder = new NavHolder(); - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - convertView = inflater.inflate(R.layout.nav_listitem, parent, false); - - holder.image = convertView.findViewById(R.id.imgvCover); - holder.title = convertView.findViewById(R.id.txtvTitle); - holder.count = convertView.findViewById(R.id.txtvCount); - convertView.setTag(holder); - } else { - holder = (NavHolder) convertView.getTag(); - } - holder.title.setText(title); // reset for re-use @@ -301,56 +272,30 @@ public class NavListAdapter extends BaseAdapter } holder.image.setImageDrawable(getDrawable(fragmentTags.get(position))); - - return convertView; } - private View getSectionDividerView(View convertView, ViewGroup parent) { + private void bindSectionDivider(DividerHolder holder) { Activity context = activity.get(); if(context == null) { - return null; + return; } - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - convertView = inflater.inflate(R.layout.nav_section_item, parent, false); - TextView feedsFilteredMsg = convertView.findViewById(R.id.nav_feeds_filtered_message); if (UserPreferences.getSubscriptionsFilter().isEnabled() && showSubscriptionList) { - convertView.setEnabled(true); - feedsFilteredMsg.setText("{md-info-outline} " + context.getString(R.string.subscriptions_are_filtered)); - Iconify.addIcons(feedsFilteredMsg); - feedsFilteredMsg.setVisibility(View.VISIBLE); + holder.itemView.setEnabled(true); + holder.feedsFilteredMsg.setText("{md-info-outline} " + context.getString(R.string.subscriptions_are_filtered)); + Iconify.addIcons(holder.feedsFilteredMsg); + holder.feedsFilteredMsg.setVisibility(View.VISIBLE); } else { - convertView.setEnabled(false); - feedsFilteredMsg.setVisibility(View.GONE); + holder.itemView.setEnabled(false); + holder.feedsFilteredMsg.setVisibility(View.GONE); } - - return convertView; } - private View getFeedView(NavDrawerData.FeedDrawerItem drawerItem, View convertView, ViewGroup parent) { + private void bindFeedView(NavDrawerData.FeedDrawerItem drawerItem, FeedHolder holder) { Feed feed = drawerItem.feed; Activity context = activity.get(); if (context == null) { - return null; - } - - FeedHolder holder; - if (convertView == null) { - holder = new FeedHolder(); - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - convertView = inflater.inflate(R.layout.nav_listitem, parent, false); - - holder.image = convertView.findViewById(R.id.imgvCover); - holder.title = convertView.findViewById(R.id.txtvTitle); - holder.failure = convertView.findViewById(R.id.itxtvFailure); - holder.count = convertView.findViewById(R.id.txtvCount); - convertView.setTag(holder); - } else { - holder = (FeedHolder) convertView.getTag(); + return; } Glide.with(context) @@ -381,31 +326,13 @@ public class NavListAdapter extends BaseAdapter } else { holder.count.setVisibility(View.GONE); } - convertView.setPadding(drawerItem.layer * 50, 0, 0, 0); // TODO - return convertView; + holder.itemView.setPadding(drawerItem.layer * 50, 0, 0, 0); // TODO } - private View getFolderView(NavDrawerData.FolderDrawerItem drawerItem, View convertView, ViewGroup parent) { + private void bindFolderView(NavDrawerData.FolderDrawerItem drawerItem, FeedHolder holder) { Activity context = activity.get(); if (context == null) { - return null; - } - - FeedHolder holder; - if (convertView == null) { - holder = new FeedHolder(); - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - convertView = inflater.inflate(R.layout.nav_listitem, parent, false); - - holder.image = convertView.findViewById(R.id.imgvCover); - holder.title = convertView.findViewById(R.id.txtvTitle); - holder.failure = convertView.findViewById(R.id.itxtvFailure); - holder.count = convertView.findViewById(R.id.txtvCount); - convertView.setTag(holder); - } else { - holder = (FeedHolder) convertView.getTag(); + return; } holder.image.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.ic_folder)); @@ -413,21 +340,50 @@ public class NavListAdapter extends BaseAdapter holder.failure.setVisibility(View.GONE); holder.count.setText("?"); - convertView.setPadding(drawerItem.layer * 50, 0, 0, 0); // TODO - return convertView; + holder.itemView.setPadding(drawerItem.layer * 50, 0, 0, 0); // TODO } - static class NavHolder { - ImageView image; - TextView title; - TextView count; + static class Holder extends RecyclerView.ViewHolder { + public Holder(@NonNull View itemView) { + super(itemView); + } } - static class FeedHolder { - ImageView image; - TextView title; - IconTextView failure; - TextView count; + static class DividerHolder extends Holder { + final TextView feedsFilteredMsg; + + public DividerHolder(@NonNull View itemView) { + super(itemView); + feedsFilteredMsg = itemView.findViewById(R.id.nav_feeds_filtered_message); + } + } + + static class NavHolder extends Holder { + final ImageView image; + final TextView title; + final TextView count; + + public NavHolder(@NonNull View itemView) { + super(itemView); + image = itemView.findViewById(R.id.imgvCover); + title = itemView.findViewById(R.id.txtvTitle); + count = itemView.findViewById(R.id.txtvCount); + } + } + + static class FeedHolder extends Holder { + final ImageView image; + final TextView title; + final IconTextView failure; + final TextView count; + + public FeedHolder(@NonNull View itemView) { + super(itemView); + image = itemView.findViewById(R.id.imgvCover); + title = itemView.findViewById(R.id.txtvTitle); + failure = itemView.findViewById(R.id.itxtvFailure); + count = itemView.findViewById(R.id.txtvCount); + } } public interface ItemAccess { @@ -440,6 +396,8 @@ public class NavListAdapter extends BaseAdapter int getReclaimableItems(); int getFeedCounter(long feedId); int getFeedCounterSum(); + void onItemClick(int position); + boolean onItemLongClick(int position); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java index e64a4e11f..a97ad40f1 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java @@ -21,6 +21,8 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.bottomsheet.BottomSheetBehavior; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; @@ -57,8 +59,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -public class NavDrawerFragment extends Fragment implements AdapterView.OnItemClickListener, - AdapterView.OnItemLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener { +public class NavDrawerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener { @VisibleForTesting public static final String PREF_LAST_FRAGMENT_TAG = "prefLastFragmentTag"; @VisibleForTesting @@ -91,11 +92,11 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli View root = inflater.inflate(R.layout.nav_list, container, false); progressBar = root.findViewById(R.id.progressBar); - ListView navList = root.findViewById(R.id.nav_list); + RecyclerView navList = root.findViewById(R.id.nav_list); navAdapter = new NavListAdapter(itemAccess, getActivity()); + navAdapter.setHasStableIds(true); navList.setAdapter(navAdapter); - navList.setOnItemClickListener(this); - navList.setOnItemLongClickListener(this); + navList.setLayoutManager(new LinearLayoutManager(getContext())); registerForContextMenu(navList); updateSelection(); @@ -376,6 +377,59 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli return sum; } + @Override + public void onItemClick(int position) { + int viewType = navAdapter.getItemViewType(position); + if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER) { + if (position < navAdapter.getSubscriptionOffset()) { + String tag = navAdapter.getTags().get(position); + if (getActivity() instanceof MainActivity) { + ((MainActivity) getActivity()).loadFragment(tag, null); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); + } else { + showMainActivity(tag); + } + } else { + int pos = position - navAdapter.getSubscriptionOffset(); + NavDrawerData.DrawerItem clickedItem = flatItemList.get(pos); + + if (clickedItem.type == NavDrawerData.DrawerItem.Type.FEED) { + long feedId = ((NavDrawerData.FeedDrawerItem) clickedItem).feed.getId(); + if (getActivity() instanceof MainActivity) { + ((MainActivity) getActivity()).loadFeedFragmentById(feedId, null); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); + } else { + Intent intent = new Intent(getActivity(), MainActivity.class); + intent.putExtra(MainActivity.EXTRA_FEED_ID, feedId); + startActivity(intent); + } + } else { + NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) clickedItem); + if (openFolders.contains(folder.name)) { + openFolders.remove(folder.name); + } else { + openFolders.add(folder.name); + } + flatItemList = makeFlatDrawerData(navDrawerData.items); + navAdapter.notifyDataSetChanged(); + } + } + } else if (UserPreferences.getSubscriptionsFilter().isEnabled() + && navAdapter.showSubscriptionList) { + SubscriptionsFilterDialog.showDialog(requireContext()); + } + } + + @Override + public boolean onItemLongClick(int position) { + if (position < navAdapter.getTags().size()) { + showDrawerPreferencesDialog(); + return true; + } else { + NavDrawerFragment.this.position = position; + return false; + } + } }; private void loadData() { @@ -410,60 +464,6 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli return flatItems; } - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - int viewType = parent.getAdapter().getItemViewType(position); - if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER) { - if (position < navAdapter.getSubscriptionOffset()) { - String tag = navAdapter.getTags().get(position); - if (getActivity() instanceof MainActivity) { - ((MainActivity) getActivity()).loadFragment(tag, null); - ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); - } else { - showMainActivity(tag); - } - } else { - int pos = position - navAdapter.getSubscriptionOffset(); - NavDrawerData.DrawerItem clickedItem = flatItemList.get(pos); - - if (clickedItem.type == NavDrawerData.DrawerItem.Type.FEED) { - long feedId = ((NavDrawerData.FeedDrawerItem) clickedItem).feed.getId(); - if (getActivity() instanceof MainActivity) { - ((MainActivity) getActivity()).loadFeedFragmentById(feedId, null); - ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); - } else { - Intent intent = new Intent(getActivity(), MainActivity.class); - intent.putExtra(MainActivity.EXTRA_FEED_ID, feedId); - startActivity(intent); - } - } else { - NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) clickedItem); - if (openFolders.contains(folder.name)) { - openFolders.remove(folder.name); - } else { - openFolders.add(folder.name); - } - flatItemList = makeFlatDrawerData(navDrawerData.items); - navAdapter.notifyDataSetChanged(); - } - } - } else if (UserPreferences.getSubscriptionsFilter().isEnabled() - && navAdapter.showSubscriptionList) { - SubscriptionsFilterDialog.showDialog(requireContext()); - } - } - - @Override - public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - if (position < navAdapter.getTags().size()) { - showDrawerPreferencesDialog(); - return true; - } else { - this.position = position; - return false; - } - } - public static void saveLastNavFragment(Context context, String tag) { Log.d(TAG, "saveLastNavFragment(tag: " + tag + ")"); SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); diff --git a/app/src/main/res/layout/nav_list.xml b/app/src/main/res/layout/nav_list.xml index ed850cc86..70a71a453 100644 --- a/app/src/main/res/layout/nav_list.xml +++ b/app/src/main/res/layout/nav_list.xml @@ -57,7 +57,7 @@ android:background="?android:attr/listDivider" tools:background="@android:color/holo_red_dark" /> -