Timeline footer improvements
This commit is contained in:
parent
69c1b88ff4
commit
d732c5d0a7
|
@ -23,6 +23,8 @@ class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||||
FooterViewHolder(View itemView) {
|
FooterViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
ProgressBar progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
|
ProgressBar progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
|
||||||
|
if (progressBar != null) {
|
||||||
progressBar.setIndeterminate(true);
|
progressBar.setIndeterminate(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -42,9 +42,16 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
|
||||||
private static final int VIEW_TYPE_STATUS_NOTIFICATION = 2;
|
private static final int VIEW_TYPE_STATUS_NOTIFICATION = 2;
|
||||||
private static final int VIEW_TYPE_FOLLOW = 3;
|
private static final int VIEW_TYPE_FOLLOW = 3;
|
||||||
|
|
||||||
|
enum FooterState {
|
||||||
|
EMPTY,
|
||||||
|
END,
|
||||||
|
LOADING
|
||||||
|
}
|
||||||
|
|
||||||
private List<Notification> notifications;
|
private List<Notification> notifications;
|
||||||
private StatusActionListener statusListener;
|
private StatusActionListener statusListener;
|
||||||
private NotificationActionListener notificationActionListener;
|
private NotificationActionListener notificationActionListener;
|
||||||
|
private FooterState footerState = FooterState.END;
|
||||||
|
|
||||||
NotificationsAdapter(StatusActionListener statusListener,
|
NotificationsAdapter(StatusActionListener statusListener,
|
||||||
NotificationActionListener notificationActionListener) {
|
NotificationActionListener notificationActionListener) {
|
||||||
|
@ -54,6 +61,15 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
|
||||||
this.notificationActionListener = notificationActionListener;
|
this.notificationActionListener = notificationActionListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setFooterState(FooterState newFooterState) {
|
||||||
|
FooterState oldValue = footerState;
|
||||||
|
footerState = newFooterState;
|
||||||
|
if (footerState != oldValue) {
|
||||||
|
notifyItemChanged(notifications.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
switch (viewType) {
|
switch (viewType) {
|
||||||
|
@ -64,8 +80,24 @@ class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRe
|
||||||
return new StatusViewHolder(view);
|
return new StatusViewHolder(view);
|
||||||
}
|
}
|
||||||
case VIEW_TYPE_FOOTER: {
|
case VIEW_TYPE_FOOTER: {
|
||||||
View view = LayoutInflater.from(parent.getContext())
|
View view;
|
||||||
|
switch (footerState) {
|
||||||
|
default:
|
||||||
|
case LOADING:
|
||||||
|
view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.item_footer, parent, false);
|
.inflate(R.layout.item_footer, parent, false);
|
||||||
|
break;
|
||||||
|
case END: {
|
||||||
|
view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_footer_end, parent, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EMPTY: {
|
||||||
|
view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_footer_empty, parent, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return new FooterViewHolder(view);
|
return new FooterViewHolder(view);
|
||||||
}
|
}
|
||||||
case VIEW_TYPE_STATUS_NOTIFICATION: {
|
case VIEW_TYPE_STATUS_NOTIFICATION: {
|
||||||
|
|
|
@ -144,6 +144,10 @@ public class NotificationsFragment extends SFragment implements
|
||||||
private void sendFetchNotificationsRequest(final String fromId, String uptoId) {
|
private void sendFetchNotificationsRequest(final String fromId, String uptoId) {
|
||||||
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
|
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
|
||||||
|
|
||||||
|
if (fromId != null || adapter.getItemCount() <= 1) {
|
||||||
|
adapter.setFooterState(NotificationsAdapter.FooterState.LOADING);
|
||||||
|
}
|
||||||
|
|
||||||
listCall = api.notifications(fromId, uptoId, null);
|
listCall = api.notifications(fromId, uptoId, null);
|
||||||
|
|
||||||
listCall.enqueue(new Callback<List<Notification>>() {
|
listCall.enqueue(new Callback<List<Notification>>() {
|
||||||
|
@ -192,6 +196,11 @@ public class NotificationsFragment extends SFragment implements
|
||||||
} else {
|
} else {
|
||||||
adapter.update(notifications);
|
adapter.update(notifications);
|
||||||
}
|
}
|
||||||
|
if (notifications.size() == 0 && adapter.getItemCount() == 1) {
|
||||||
|
adapter.setFooterState(NotificationsAdapter.FooterState.EMPTY);
|
||||||
|
} else if (fromId != null) {
|
||||||
|
adapter.setFooterState(NotificationsAdapter.FooterState.END);
|
||||||
|
}
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,15 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
|
||||||
private static final int VIEW_TYPE_STATUS = 0;
|
private static final int VIEW_TYPE_STATUS = 0;
|
||||||
private static final int VIEW_TYPE_FOOTER = 1;
|
private static final int VIEW_TYPE_FOOTER = 1;
|
||||||
|
|
||||||
|
enum FooterState {
|
||||||
|
EMPTY,
|
||||||
|
END,
|
||||||
|
LOADING
|
||||||
|
}
|
||||||
|
|
||||||
private List<Status> statuses;
|
private List<Status> statuses;
|
||||||
private StatusActionListener statusListener;
|
private StatusActionListener statusListener;
|
||||||
|
private FooterState footerState = FooterState.END;
|
||||||
|
|
||||||
TimelineAdapter(StatusActionListener statusListener) {
|
TimelineAdapter(StatusActionListener statusListener) {
|
||||||
super();
|
super();
|
||||||
|
@ -49,13 +56,37 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
|
||||||
return new StatusViewHolder(view);
|
return new StatusViewHolder(view);
|
||||||
}
|
}
|
||||||
case VIEW_TYPE_FOOTER: {
|
case VIEW_TYPE_FOOTER: {
|
||||||
View view = LayoutInflater.from(viewGroup.getContext())
|
View view;
|
||||||
|
switch (footerState) {
|
||||||
|
default:
|
||||||
|
case LOADING:
|
||||||
|
view = LayoutInflater.from(viewGroup.getContext())
|
||||||
.inflate(R.layout.item_footer, viewGroup, false);
|
.inflate(R.layout.item_footer, viewGroup, false);
|
||||||
|
break;
|
||||||
|
case END: {
|
||||||
|
view = LayoutInflater.from(viewGroup.getContext())
|
||||||
|
.inflate(R.layout.item_footer_end, viewGroup, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EMPTY: {
|
||||||
|
view = LayoutInflater.from(viewGroup.getContext())
|
||||||
|
.inflate(R.layout.item_footer_empty, viewGroup, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return new FooterViewHolder(view);
|
return new FooterViewHolder(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFooterState(FooterState newFooterState) {
|
||||||
|
FooterState oldValue = footerState;
|
||||||
|
footerState = newFooterState;
|
||||||
|
if (footerState != oldValue) {
|
||||||
|
notifyItemChanged(statuses.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
|
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
if (position < statuses.size()) {
|
if (position < statuses.size()) {
|
||||||
|
|
|
@ -214,6 +214,10 @@ public class TimelineFragment extends SFragment implements
|
||||||
private void sendFetchTimelineRequest(@Nullable final String fromId, @Nullable String uptoId) {
|
private void sendFetchTimelineRequest(@Nullable final String fromId, @Nullable String uptoId) {
|
||||||
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
|
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
|
||||||
|
|
||||||
|
if (fromId != null || adapter.getItemCount() <= 1) {
|
||||||
|
adapter.setFooterState(TimelineAdapter.FooterState.LOADING);
|
||||||
|
}
|
||||||
|
|
||||||
Callback<List<Status>> cb = new Callback<List<Status>>() {
|
Callback<List<Status>> cb = new Callback<List<Status>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<List<Status>> call, retrofit2.Response<List<Status>> response) {
|
public void onResponse(Call<List<Status>> call, retrofit2.Response<List<Status>> response) {
|
||||||
|
@ -282,6 +286,11 @@ public class TimelineFragment extends SFragment implements
|
||||||
} else {
|
} else {
|
||||||
adapter.update(statuses);
|
adapter.update(statuses);
|
||||||
}
|
}
|
||||||
|
if (statuses.size() == 0 && adapter.getItemCount() == 1) {
|
||||||
|
adapter.setFooterState(TimelineAdapter.FooterState.EMPTY);
|
||||||
|
} else if(fromId != null) {
|
||||||
|
adapter.setFooterState(TimelineAdapter.FooterState.END);
|
||||||
|
}
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/elephant_friend" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/footer_empty"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -38,6 +38,7 @@
|
||||||
<string name="footer_end_of_statuses">end of the statuses</string>
|
<string name="footer_end_of_statuses">end of the statuses</string>
|
||||||
<string name="footer_end_of_notifications">end of the notifications</string>
|
<string name="footer_end_of_notifications">end of the notifications</string>
|
||||||
<string name="footer_end_of_accounts">end of the accounts</string>
|
<string name="footer_end_of_accounts">end of the accounts</string>
|
||||||
|
<string name="footer_empty">There are no toots here so far. Pull down to refresh!</string>
|
||||||
|
|
||||||
<string name="notification_reblog_format">%s boosted your toot</string>
|
<string name="notification_reblog_format">%s boosted your toot</string>
|
||||||
<string name="notification_favourite_format">%s favourited your toot</string>
|
<string name="notification_favourite_format">%s favourited your toot</string>
|
||||||
|
|
Loading…
Reference in New Issue