Merge pull request #3155 from ByteHamster/empty-view-simplification
Simplify empty view handling on recycler views
This commit is contained in:
commit
0107cf22cc
|
@ -51,6 +51,7 @@ import de.danoeh.antennapod.core.util.FeedItemUtil;
|
|||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
import de.greenrobot.event.EventBus;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
@ -76,7 +77,7 @@ public class AllEpisodesFragment extends Fragment {
|
|||
RecyclerView recyclerView;
|
||||
AllEpisodesRecycleAdapter listAdapter;
|
||||
private ProgressBar progLoading;
|
||||
private View emptyView;
|
||||
EmptyViewHandler emptyView;
|
||||
|
||||
List<FeedItem> episodes;
|
||||
private List<Downloader> downloaderList;
|
||||
|
@ -334,10 +335,10 @@ public class AllEpisodesFragment extends Fragment {
|
|||
onFragmentLoaded();
|
||||
}
|
||||
|
||||
emptyView = root.findViewById(R.id.emptyView);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((TextView)emptyView.findViewById(R.id.emptyViewTitle)).setText(R.string.no_all_episodes_head_label);
|
||||
((TextView)emptyView.findViewById(R.id.emptyViewMessage)).setText(R.string.no_all_episodes_label);
|
||||
emptyView = new EmptyViewHandler(getContext());
|
||||
emptyView.attachToRecyclerView(recyclerView);
|
||||
emptyView.setTitle(R.string.no_all_episodes_head_label);
|
||||
emptyView.setMessage(R.string.no_all_episodes_label);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
@ -350,14 +351,14 @@ public class AllEpisodesFragment extends Fragment {
|
|||
new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes());
|
||||
listAdapter.setHasStableIds(true);
|
||||
recyclerView.setAdapter(listAdapter);
|
||||
emptyView.updateAdapter(listAdapter);
|
||||
}
|
||||
emptyView.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
} else {
|
||||
listAdapter = null;
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
emptyView.updateAdapter(listAdapter);
|
||||
}
|
||||
|
||||
restoreScrollPosition();
|
||||
|
@ -497,7 +498,7 @@ public class AllEpisodesFragment extends Fragment {
|
|||
}
|
||||
if (viewsCreated && !itemsLoaded) {
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
emptyView.hide();
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
}
|
||||
disposable = Observable.fromCallable(this::loadData)
|
||||
|
|
|
@ -51,8 +51,8 @@ public class FavoriteEpisodesFragment extends AllEpisodesFragment {
|
|||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View root = super.onCreateViewHelper(inflater, container, savedInstanceState,
|
||||
R.layout.all_episodes_fragment);
|
||||
((TextView)root.findViewById(R.id.emptyViewTitle)).setText(R.string.no_fav_episodes_head_label);
|
||||
((TextView)root.findViewById(R.id.emptyViewMessage)).setText(R.string.no_fav_episodes_label);
|
||||
emptyView.setTitle(R.string.no_fav_episodes_head_label);
|
||||
emptyView.setMessage(R.string.no_fav_episodes_label);
|
||||
|
||||
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
|
||||
@Override
|
||||
|
|
|
@ -46,8 +46,8 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
|
|||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View root = super.onCreateViewHelper(inflater, container, savedInstanceState,
|
||||
R.layout.all_episodes_fragment);
|
||||
((TextView)root.findViewById(R.id.emptyViewTitle)).setText(R.string.no_new_episodes_head_label);
|
||||
((TextView)root.findViewById(R.id.emptyViewMessage)).setText(R.string.no_new_episodes_label);
|
||||
emptyView.setTitle(R.string.no_new_episodes_head_label);
|
||||
emptyView.setMessage(R.string.no_new_episodes_label);
|
||||
|
||||
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
|
||||
@Override
|
||||
|
|
|
@ -52,6 +52,7 @@ import de.danoeh.antennapod.core.util.LongList;
|
|||
import de.danoeh.antennapod.core.util.QueueSorter;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
import de.greenrobot.event.EventBus;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
@ -72,7 +73,7 @@ public class QueueFragment extends Fragment {
|
|||
private TextView infoBar;
|
||||
private RecyclerView recyclerView;
|
||||
private QueueRecyclerAdapter recyclerAdapter;
|
||||
private View emptyView;
|
||||
private EmptyViewHandler emptyView;
|
||||
private ProgressBar progLoading;
|
||||
|
||||
private List<FeedItem> queue;
|
||||
|
@ -502,11 +503,11 @@ public class QueueFragment extends Fragment {
|
|||
}
|
||||
);
|
||||
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||
//empty view
|
||||
emptyView = root.findViewById(R.id.emptyView);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((TextView)emptyView.findViewById(R.id.emptyViewTitle)).setText(R.string.no_items_header_label);
|
||||
((TextView)emptyView.findViewById(R.id.emptyViewMessage)).setText(R.string.no_items_label);
|
||||
|
||||
emptyView = new EmptyViewHandler(getContext());
|
||||
emptyView.attachToRecyclerView(recyclerView);
|
||||
emptyView.setTitle(R.string.no_items_header_label);
|
||||
emptyView.setMessage(R.string.no_items_label);
|
||||
|
||||
progLoading = root.findViewById(R.id.progLoading);
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
|
@ -522,13 +523,13 @@ public class QueueFragment extends Fragment {
|
|||
new DefaultActionButtonCallback(activity), itemTouchHelper);
|
||||
recyclerAdapter.setHasStableIds(true);
|
||||
recyclerView.setAdapter(recyclerAdapter);
|
||||
emptyView.updateAdapter(recyclerAdapter);
|
||||
}
|
||||
emptyView.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
recyclerAdapter = null;
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
emptyView.updateAdapter(recyclerAdapter);
|
||||
}
|
||||
|
||||
if (restoreScrollPosition) {
|
||||
|
@ -641,7 +642,7 @@ public class QueueFragment extends Fragment {
|
|||
}
|
||||
if (queue == null) {
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
emptyView.hide();
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
}
|
||||
disposable = Observable.fromCallable(DBReader::getQueue)
|
||||
|
|
|
@ -1,59 +1,95 @@
|
|||
package de.danoeh.antennapod.view;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
|
||||
public class EmptyViewHandler extends View {
|
||||
private Activity activity;
|
||||
private int title;
|
||||
private int message;
|
||||
public class EmptyViewHandler {
|
||||
private boolean layoutAdded = false;
|
||||
private RecyclerView recyclerView;
|
||||
private RecyclerView.Adapter adapter;
|
||||
|
||||
private final View emptyView;
|
||||
private final TextView tvTitle;
|
||||
private final TextView tvMessage;
|
||||
|
||||
public EmptyViewHandler(Context context) {
|
||||
super(context);
|
||||
this.setActivity((Activity) context);
|
||||
}
|
||||
|
||||
public int getTitle() {
|
||||
return title;
|
||||
emptyView = View.inflate(context, R.layout.empty_view_layout, null);
|
||||
tvTitle = emptyView.findViewById(R.id.emptyViewTitle);
|
||||
tvMessage = emptyView.findViewById(R.id.emptyViewMessage);
|
||||
}
|
||||
|
||||
public void setTitle(int title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public int getMessage() {
|
||||
return message;
|
||||
tvTitle.setText(title);
|
||||
}
|
||||
|
||||
public void setMessage(int message) {
|
||||
this.message = message;
|
||||
tvMessage.setText(message);
|
||||
}
|
||||
|
||||
public void attachToListView(ListView listView){
|
||||
public void hide() {
|
||||
emptyView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
View emptyView = getActivity().getLayoutInflater().inflate(R.layout.empty_view_layout, null);
|
||||
public void attachToListView(ListView listView) {
|
||||
if (layoutAdded) {
|
||||
throw new IllegalStateException("Can not attach to ListView multiple times");
|
||||
}
|
||||
layoutAdded = true;
|
||||
((ViewGroup) listView.getParent()).addView(emptyView);
|
||||
listView.setEmptyView(emptyView);
|
||||
|
||||
TextView tvTitle = (TextView) emptyView.findViewById(R.id.emptyViewTitle);
|
||||
tvTitle.setText(title);
|
||||
|
||||
TextView tvMessage = (TextView) emptyView.findViewById(R.id.emptyViewMessage);
|
||||
tvMessage.setText(message);
|
||||
|
||||
}
|
||||
|
||||
public Activity getActivity() {
|
||||
return activity;
|
||||
public void attachToRecyclerView(RecyclerView recyclerView) {
|
||||
if (layoutAdded) {
|
||||
throw new IllegalStateException("Can not attach to ListView multiple times");
|
||||
}
|
||||
layoutAdded = true;
|
||||
this.recyclerView = recyclerView;
|
||||
ViewGroup parent = ((ViewGroup) recyclerView.getParent());
|
||||
parent.addView(emptyView);
|
||||
updateAdapter(recyclerView.getAdapter());
|
||||
|
||||
if (parent instanceof RelativeLayout) {
|
||||
RelativeLayout.LayoutParams layoutParams =
|
||||
(RelativeLayout.LayoutParams)emptyView.getLayoutParams();
|
||||
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
|
||||
emptyView.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
public void setActivity(Activity activity) {
|
||||
this.activity = activity;
|
||||
public void updateAdapter(RecyclerView.Adapter adapter) {
|
||||
if (this.adapter != null) {
|
||||
this.adapter.unregisterAdapterDataObserver(adapterObserver);
|
||||
}
|
||||
this.adapter = adapter;
|
||||
if (adapter != null) {
|
||||
adapter.registerAdapterDataObserver(adapterObserver);
|
||||
}
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
private final SimpleAdapterDataObserver adapterObserver = new SimpleAdapterDataObserver() {
|
||||
@Override
|
||||
public void anythingChanged() {
|
||||
updateVisibility();
|
||||
}
|
||||
};
|
||||
|
||||
private void updateVisibility() {
|
||||
boolean empty;
|
||||
if (adapter == null) {
|
||||
empty = true;
|
||||
} else {
|
||||
empty = adapter.getItemCount() == 0;
|
||||
}
|
||||
recyclerView.setVisibility(empty ? View.GONE : View.VISIBLE);
|
||||
emptyView.setVisibility(empty ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package de.danoeh.antennapod.view;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* AdapterDataObserver that relays all events to the method anythingChanged().
|
||||
*/
|
||||
public abstract class SimpleAdapterDataObserver extends RecyclerView.AdapterDataObserver {
|
||||
public abstract void anythingChanged();
|
||||
|
||||
@Override
|
||||
public void onChanged() {
|
||||
anythingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount) {
|
||||
anythingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
|
||||
anythingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
anythingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
|
||||
anythingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||
anythingChanged();
|
||||
}
|
||||
}
|
|
@ -17,10 +17,6 @@
|
|||
tools:itemCount="13"
|
||||
tools:listitem="@layout/new_episodes_listitem" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emptyView"
|
||||
layout="@layout/empty_view_layout"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progLoading"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:layout_centerInParent="true"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -27,10 +27,6 @@
|
|||
android:layout_below="@id/divider"
|
||||
android:scrollbars="vertical"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/emptyView"
|
||||
layout="@layout/empty_view_layout"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progLoading"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
Loading…
Reference in New Issue