Adds correct footer behaviour to account lists and unifies it with how timelines use them.
This commit is contained in:
parent
3955649b9c
commit
275cd51a6d
15 changed files with 164 additions and 124 deletions
|
@ -21,7 +21,6 @@ import android.support.v7.widget.RecyclerView;
|
|||
import com.keylesspalace.tusky.entity.Account;
|
||||
import com.keylesspalace.tusky.interfaces.AccountActionListener;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -29,6 +28,8 @@ import java.util.List;
|
|||
public abstract class AccountAdapter extends RecyclerView.Adapter {
|
||||
List<Account> accountList;
|
||||
AccountActionListener accountActionListener;
|
||||
FooterViewHolder.State footerState;
|
||||
|
||||
private String topId;
|
||||
private String bottomId;
|
||||
|
||||
|
@ -36,6 +37,7 @@ public abstract class AccountAdapter extends RecyclerView.Adapter {
|
|||
super();
|
||||
accountList = new ArrayList<>();
|
||||
this.accountActionListener = accountActionListener;
|
||||
footerState = FooterViewHolder.State.END;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -119,6 +121,10 @@ public abstract class AccountAdapter extends RecyclerView.Adapter {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void setFooterState(FooterViewHolder.State newFooterState) {
|
||||
footerState = newFooterState;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getBottomId() {
|
||||
return bottomId;
|
||||
|
|
|
@ -59,6 +59,9 @@ public class BlocksAdapter extends AccountAdapter {
|
|||
BlockedUserViewHolder holder = (BlockedUserViewHolder) viewHolder;
|
||||
holder.setupWithAccount(accountList.get(position));
|
||||
holder.setupActionListener(accountActionListener, true);
|
||||
} else {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(footerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,9 @@ public class FollowAdapter extends AccountAdapter {
|
|||
AccountViewHolder holder = (AccountViewHolder) viewHolder;
|
||||
holder.setupWithAccount(accountList.get(position));
|
||||
holder.setupActionListener(accountActionListener);
|
||||
} else {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(footerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ public class FollowRequestsAdapter extends AccountAdapter {
|
|||
FollowRequestViewHolder holder = (FollowRequestViewHolder) viewHolder;
|
||||
holder.setupWithAccount(accountList.get(position));
|
||||
holder.setupActionListener(accountActionListener);
|
||||
} else {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(footerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,18 +15,59 @@
|
|||
|
||||
package com.keylesspalace.tusky.adapter;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.v7.content.res.AppCompatResources;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.keylesspalace.tusky.R;
|
||||
|
||||
class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||
public class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||
public enum State {
|
||||
EMPTY,
|
||||
END,
|
||||
LOADING
|
||||
}
|
||||
|
||||
private View container;
|
||||
private ProgressBar progressBar;
|
||||
private TextView endMessage;
|
||||
|
||||
FooterViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ProgressBar progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
|
||||
if (progressBar != null) {
|
||||
progressBar.setIndeterminate(true);
|
||||
container = itemView.findViewById(R.id.footer_container);
|
||||
progressBar = (ProgressBar) itemView.findViewById(R.id.footer_progress_bar);
|
||||
endMessage = (TextView) itemView.findViewById(R.id.footer_end_message);
|
||||
Drawable top = AppCompatResources.getDrawable(itemView.getContext(),
|
||||
R.drawable.elephant_friend);
|
||||
if (top != null) {
|
||||
top.setBounds(0, 0, top.getIntrinsicWidth() / 2, top.getIntrinsicHeight() / 2);
|
||||
}
|
||||
endMessage.setCompoundDrawables(null, top, null, null);
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
switch (state) {
|
||||
case LOADING: {
|
||||
container.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
endMessage.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
case END: {
|
||||
container.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
endMessage.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
case EMPTY: {
|
||||
container.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
endMessage.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,6 +44,9 @@ public class MutesAdapter extends AccountAdapter {
|
|||
MutedUserViewHolder holder = (MutedUserViewHolder) viewHolder;
|
||||
holder.setupWithAccount(accountList.get(position));
|
||||
holder.setupActionListener(accountActionListener, true, position);
|
||||
} else {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(footerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,16 +46,10 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
|
|||
private static final int VIEW_TYPE_STATUS_NOTIFICATION = 2;
|
||||
private static final int VIEW_TYPE_FOLLOW = 3;
|
||||
|
||||
public enum FooterState {
|
||||
EMPTY,
|
||||
END,
|
||||
LOADING
|
||||
}
|
||||
|
||||
private List<Notification> notifications;
|
||||
private StatusActionListener statusListener;
|
||||
private NotificationActionListener notificationActionListener;
|
||||
private FooterState footerState = FooterState.END;
|
||||
private FooterViewHolder.State footerState;
|
||||
private boolean mediaPreviewEnabled;
|
||||
private String bottomId;
|
||||
private String topId;
|
||||
|
@ -66,6 +60,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
|
|||
notifications = new ArrayList<>();
|
||||
this.statusListener = statusListener;
|
||||
this.notificationActionListener = notificationActionListener;
|
||||
footerState = FooterViewHolder.State.END;
|
||||
mediaPreviewEnabled = true;
|
||||
}
|
||||
|
||||
|
@ -79,24 +74,8 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
|
|||
return new StatusViewHolder(view);
|
||||
}
|
||||
case VIEW_TYPE_FOOTER: {
|
||||
View view;
|
||||
switch (footerState) {
|
||||
default:
|
||||
case LOADING:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.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;
|
||||
}
|
||||
}
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_footer, parent, false);
|
||||
return new FooterViewHolder(view);
|
||||
}
|
||||
case VIEW_TYPE_STATUS_NOTIFICATION: {
|
||||
|
@ -140,6 +119,9 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(footerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,12 +234,8 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setFooterState(FooterState newFooterState) {
|
||||
FooterState oldValue = footerState;
|
||||
public void setFooterState(FooterViewHolder.State newFooterState) {
|
||||
footerState = newFooterState;
|
||||
if (footerState != oldValue) {
|
||||
notifyItemChanged(notifications.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -34,15 +34,9 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
|
|||
private static final int VIEW_TYPE_STATUS = 0;
|
||||
private static final int VIEW_TYPE_FOOTER = 1;
|
||||
|
||||
public enum FooterState {
|
||||
EMPTY,
|
||||
END,
|
||||
LOADING
|
||||
}
|
||||
|
||||
private List<Status> statuses;
|
||||
private StatusActionListener statusListener;
|
||||
private FooterState footerState = FooterState.END;
|
||||
private FooterViewHolder.State footerState;
|
||||
private boolean mediaPreviewEnabled;
|
||||
private String topId;
|
||||
private String bottomId;
|
||||
|
@ -51,6 +45,7 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
|
|||
super();
|
||||
statuses = new ArrayList<>();
|
||||
this.statusListener = statusListener;
|
||||
footerState = FooterViewHolder.State.END;
|
||||
mediaPreviewEnabled = true;
|
||||
}
|
||||
|
||||
|
@ -64,24 +59,8 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
|
|||
return new StatusViewHolder(view);
|
||||
}
|
||||
case VIEW_TYPE_FOOTER: {
|
||||
View view;
|
||||
switch (footerState) {
|
||||
default:
|
||||
case LOADING:
|
||||
view = LayoutInflater.from(viewGroup.getContext())
|
||||
.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;
|
||||
}
|
||||
}
|
||||
View view = LayoutInflater.from(viewGroup.getContext())
|
||||
.inflate(R.layout.item_footer, viewGroup, false);
|
||||
return new FooterViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +72,9 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
|
|||
StatusViewHolder holder = (StatusViewHolder) viewHolder;
|
||||
Status status = statuses.get(position);
|
||||
holder.setupWithStatus(status, statusListener, mediaPreviewEnabled);
|
||||
} else {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(footerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,12 +174,8 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
|
|||
return null;
|
||||
}
|
||||
|
||||
public void setFooterState(FooterState newFooterState) {
|
||||
FooterState oldValue = footerState;
|
||||
public void setFooterState(FooterViewHolder.State newFooterState) {
|
||||
footerState = newFooterState;
|
||||
if (footerState != oldValue) {
|
||||
notifyItemChanged(statuses.size());
|
||||
}
|
||||
}
|
||||
|
||||
public void setMediaPreviewEnabled(boolean enabled) {
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.keylesspalace.tusky.adapter.AccountAdapter;
|
|||
import com.keylesspalace.tusky.adapter.BlocksAdapter;
|
||||
import com.keylesspalace.tusky.adapter.FollowAdapter;
|
||||
import com.keylesspalace.tusky.adapter.FollowRequestsAdapter;
|
||||
import com.keylesspalace.tusky.adapter.FooterViewHolder;
|
||||
import com.keylesspalace.tusky.adapter.MutesAdapter;
|
||||
import com.keylesspalace.tusky.BaseActivity;
|
||||
import com.keylesspalace.tusky.entity.Account;
|
||||
|
@ -358,7 +359,12 @@ public class AccountListFragment extends BaseFragment implements AccountActionLi
|
|||
}
|
||||
|
||||
private void onRespondToFollowRequestFailure(boolean accept, String accountId) {
|
||||
String verb = (accept) ? "accept" : "reject";
|
||||
String verb;
|
||||
if (accept) {
|
||||
verb = "accept";
|
||||
} else {
|
||||
verb = "reject";
|
||||
}
|
||||
String message = String.format("Failed to %s account id %s.", verb, accountId);
|
||||
Log.e(TAG, message);
|
||||
}
|
||||
|
@ -399,6 +405,11 @@ public class AccountListFragment extends BaseFragment implements AccountActionLi
|
|||
bottomFetches++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fromId != null || adapter.getItemCount() <= 1) {
|
||||
setFooterState(FooterViewHolder.State.LOADING);
|
||||
}
|
||||
|
||||
Callback<List<Account>> cb = new Callback<List<Account>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<Account>> call, Response<List<Account>> response) {
|
||||
|
@ -456,6 +467,11 @@ public class AccountListFragment extends BaseFragment implements AccountActionLi
|
|||
}
|
||||
}
|
||||
fulfillAnyQueuedFetches(fetchEnd);
|
||||
if (accounts.size() == 0 && adapter.getItemCount() == 1) {
|
||||
setFooterState(FooterViewHolder.State.EMPTY);
|
||||
} else {
|
||||
setFooterState(FooterViewHolder.State.END);
|
||||
}
|
||||
}
|
||||
|
||||
private void onFetchAccountsFailure(Exception exception, FetchEnd fetchEnd) {
|
||||
|
@ -463,6 +479,20 @@ public class AccountListFragment extends BaseFragment implements AccountActionLi
|
|||
fulfillAnyQueuedFetches(fetchEnd);
|
||||
}
|
||||
|
||||
/* This needs to be called from the endless scroll listener, which does not allow notifying the
|
||||
* adapter during the callback. So, this is the workaround. */
|
||||
private void setFooterState(FooterViewHolder.State state) {
|
||||
// Set the adapter to set its state when it's bound, if the current Footer is offscreen.
|
||||
adapter.setFooterState(state);
|
||||
// Check if it's onscreen, and update it directly if it is.
|
||||
RecyclerView.ViewHolder viewHolder =
|
||||
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
||||
if (viewHolder != null) {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void onRefresh() {
|
||||
fetchAccounts(null, adapter.getTopId(), FetchEnd.TOP);
|
||||
}
|
||||
|
@ -478,7 +508,6 @@ public class AccountListFragment extends BaseFragment implements AccountActionLi
|
|||
bottomLoading = false;
|
||||
if (bottomFetches > 0) {
|
||||
bottomFetches--;
|
||||
Log.d(TAG, "extra fetchos " + bottomFetches);
|
||||
onLoadMore(recyclerView);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -34,6 +34,7 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
|
||||
import com.keylesspalace.tusky.MainActivity;
|
||||
import com.keylesspalace.tusky.adapter.FooterViewHolder;
|
||||
import com.keylesspalace.tusky.adapter.NotificationsAdapter;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.entity.Notification;
|
||||
|
@ -274,7 +275,7 @@ public class NotificationsFragment extends SFragment implements
|
|||
}
|
||||
|
||||
if (fromId != null || adapter.getItemCount() <= 1) {
|
||||
adapter.setFooterState(NotificationsAdapter.FooterState.LOADING);
|
||||
setFooterState(FooterViewHolder.State.LOADING);
|
||||
}
|
||||
|
||||
Call<List<Notification>> call = mastodonApi.notifications(fromId, uptoId, null);
|
||||
|
@ -341,9 +342,9 @@ public class NotificationsFragment extends SFragment implements
|
|||
}
|
||||
fulfillAnyQueuedFetches(fetchEnd);
|
||||
if (notifications.size() == 0 && adapter.getItemCount() == 1) {
|
||||
adapter.setFooterState(NotificationsAdapter.FooterState.EMPTY);
|
||||
setFooterState(FooterViewHolder.State.EMPTY);
|
||||
} else {
|
||||
adapter.setFooterState(NotificationsAdapter.FooterState.END);
|
||||
setFooterState(FooterViewHolder.State.END);
|
||||
}
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
|
@ -354,6 +355,20 @@ public class NotificationsFragment extends SFragment implements
|
|||
fulfillAnyQueuedFetches(fetchEnd);
|
||||
}
|
||||
|
||||
/* This needs to be called from the endless scroll listener, which does not allow notifying the
|
||||
* adapter during the callback. So, this is the workaround. */
|
||||
private void setFooterState(FooterViewHolder.State state) {
|
||||
// Set the adapter to set its state when it's bound, if the current Footer is offscreen.
|
||||
adapter.setFooterState(state);
|
||||
// Check if it's onscreen, and update it directly if it is.
|
||||
RecyclerView.ViewHolder viewHolder =
|
||||
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
||||
if (viewHolder != null) {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void fulfillAnyQueuedFetches(FetchEnd fetchEnd) {
|
||||
switch (fetchEnd) {
|
||||
case BOTTOM: {
|
||||
|
|
|
@ -35,6 +35,7 @@ import android.view.ViewGroup;
|
|||
|
||||
import com.keylesspalace.tusky.MainActivity;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.adapter.FooterViewHolder;
|
||||
import com.keylesspalace.tusky.adapter.TimelineAdapter;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
|
@ -359,7 +360,7 @@ public class TimelineFragment extends SFragment implements
|
|||
}
|
||||
|
||||
if (fromId != null || adapter.getItemCount() <= 1) {
|
||||
adapter.setFooterState(TimelineAdapter.FooterState.LOADING);
|
||||
setFooterState(FooterViewHolder.State.LOADING);
|
||||
}
|
||||
|
||||
Callback<List<Status>> callback = new Callback<List<Status>>() {
|
||||
|
@ -422,9 +423,9 @@ public class TimelineFragment extends SFragment implements
|
|||
}
|
||||
fulfillAnyQueuedFetches(fetchEnd);
|
||||
if (statuses.size() == 0 && adapter.getItemCount() == 1) {
|
||||
adapter.setFooterState(TimelineAdapter.FooterState.EMPTY);
|
||||
setFooterState(FooterViewHolder.State.EMPTY);
|
||||
} else {
|
||||
adapter.setFooterState(TimelineAdapter.FooterState.END);
|
||||
setFooterState(FooterViewHolder.State.END);
|
||||
}
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
|
@ -435,6 +436,20 @@ public class TimelineFragment extends SFragment implements
|
|||
fulfillAnyQueuedFetches(fetchEnd);
|
||||
}
|
||||
|
||||
/* This needs to be called from the endless scroll listener, which does not allow notifying the
|
||||
* adapter during the callback. So, this is the workaround. */
|
||||
private void setFooterState(FooterViewHolder.State state) {
|
||||
// Set the adapter to set its state when it's bound, if the current Footer is offscreen.
|
||||
adapter.setFooterState(state);
|
||||
// Check if it's onscreen, and update it directly if it is.
|
||||
RecyclerView.ViewHolder viewHolder =
|
||||
recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount() - 1);
|
||||
if (viewHolder != null) {
|
||||
FooterViewHolder holder = (FooterViewHolder) viewHolder;
|
||||
holder.setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void fulfillAnyQueuedFetches(FetchEnd fetchEnd) {
|
||||
switch (fetchEnd) {
|
||||
case BOTTOM: {
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout 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">
|
||||
android:id="@+id/footer_container">
|
||||
|
||||
<LinearLayout
|
||||
<ProgressBar
|
||||
android:id="@+id/footer_progress_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
<ProgressBar
|
||||
android:id="@+id/footer_progress_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminate="true" />
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/footer_end_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/footer_empty"
|
||||
android:textAlignment="center"
|
||||
android:layout_centerInParent="true"
|
||||
android:drawablePadding="16dp" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -1,25 +0,0 @@
|
|||
<?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>
|
|
@ -1,9 +0,0 @@
|
|||
<?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>
|
|
@ -40,10 +40,7 @@
|
|||
<string name="status_content_warning_show_more">Show More</string>
|
||||
<string name="status_content_warning_show_less">Show Less</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_accounts">end of the accounts</string>
|
||||
<string name="footer_empty">There are no toots here so far. Pull down to refresh!</string>
|
||||
<string name="footer_empty">Nothing here. Pull down to refresh!</string>
|
||||
|
||||
<string name="notification_reblog_format">%s boosted your toot</string>
|
||||
<string name="notification_favourite_format">%s favourited your toot</string>
|
||||
|
|
Loading…
Reference in a new issue