Loading and empty views for emails list
This commit is contained in:
@@ -55,6 +55,7 @@ dependencies {
|
||||
compile 'com.google.zxing:core:3.1.0'
|
||||
compile 'com.google.zxing:android-integration:3.1.0'
|
||||
compile 'com.androidplot:androidplot-core:0.6.1'
|
||||
compile 'com.pnikosis:materialish-progress:1.2'
|
||||
|
||||
// Testing-only dependencies
|
||||
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
|
||||
|
||||
@@ -41,8 +41,8 @@ public class EmailListAdapter extends MultiSelectionUtil.SelectableAdapter<Recyc
|
||||
private List<Email> mEmails;
|
||||
private int mIncompleteEmails;
|
||||
|
||||
public static class IncompleteEmailViewHolder extends RecyclerView.ViewHolder {
|
||||
public IncompleteEmailViewHolder(View itemView) {
|
||||
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
|
||||
public SimpleViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
@@ -140,6 +140,9 @@ public class EmailListAdapter extends MultiSelectionUtil.SelectableAdapter<Recyc
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (mEmails == null || mEmails.isEmpty())
|
||||
return R.layout.listitem_empty;
|
||||
|
||||
if (mIncompleteEmails > 0)
|
||||
position--;
|
||||
|
||||
@@ -152,11 +155,10 @@ public class EmailListAdapter extends MultiSelectionUtil.SelectableAdapter<Recyc
|
||||
View v = LayoutInflater.from(parent.getContext())
|
||||
.inflate(viewType, parent, false);
|
||||
switch (viewType) {
|
||||
case R.layout.listitem_incomplete:
|
||||
return new IncompleteEmailViewHolder(v);
|
||||
case R.layout.listitem_email:
|
||||
default:
|
||||
return new EmailViewHolder(v);
|
||||
default:
|
||||
return new SimpleViewHolder(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +166,11 @@ public class EmailListAdapter extends MultiSelectionUtil.SelectableAdapter<Recyc
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case R.layout.listitem_empty:
|
||||
((TextView) holder.itemView).setText(
|
||||
mCtx.getResources().getString(R.string.folder_empty));
|
||||
break;
|
||||
|
||||
case R.layout.listitem_incomplete:
|
||||
((TextView) holder.itemView).setText(
|
||||
mCtx.getResources().getQuantityString(R.plurals.incomplete_emails,
|
||||
@@ -278,6 +285,9 @@ public class EmailListAdapter extends MultiSelectionUtil.SelectableAdapter<Recyc
|
||||
}
|
||||
evh.content.setText(email.getText());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,13 +303,17 @@ public class EmailListAdapter extends MultiSelectionUtil.SelectableAdapter<Recyc
|
||||
// Return the size of the dataset (invoked by the layout manager)
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mEmails != null)
|
||||
return mIncompleteEmails > 0 ? mEmails.size() + 1 : mEmails.size();
|
||||
return 0;
|
||||
if (mEmails == null || mEmails.isEmpty())
|
||||
return 1;
|
||||
|
||||
return mIncompleteEmails > 0 ? mEmails.size() + 1 : mEmails.size();
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
if (mEmails == null || mEmails.isEmpty())
|
||||
return 0;
|
||||
|
||||
Email email = getEmail(position);
|
||||
return email == null ? 0 : email.getMessageID().hashCode();
|
||||
return email == null ? 1 : email.getMessageID().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@@ -37,6 +39,7 @@ import i2p.bote.android.util.AuthenticatedFragment;
|
||||
import i2p.bote.android.util.BetterAsyncTaskLoader;
|
||||
import i2p.bote.android.util.BoteHelper;
|
||||
import i2p.bote.android.util.DividerItemDecoration;
|
||||
import i2p.bote.android.util.LoadingRecyclerView;
|
||||
import i2p.bote.android.util.MoveToDialogFragment;
|
||||
import i2p.bote.android.util.MultiSelectionUtil;
|
||||
import i2p.bote.android.util.MultiSwipeRefreshLayout;
|
||||
@@ -58,7 +61,7 @@ public class EmailListFragment extends AuthenticatedFragment implements
|
||||
private MultiSwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private AsyncTask<Void, Void, Void> mCheckingTask;
|
||||
|
||||
private RecyclerView mEmailsList;
|
||||
private LoadingRecyclerView mEmailsList;
|
||||
private EmailListAdapter mAdapter;
|
||||
private EmailFolder mFolder;
|
||||
|
||||
@@ -107,7 +110,10 @@ public class EmailListFragment extends AuthenticatedFragment implements
|
||||
isInbox ? R.layout.fragment_list_emails_with_refresh : R.layout.fragment_list_emails,
|
||||
container, false);
|
||||
|
||||
mEmailsList = (RecyclerView) v.findViewById(R.id.emails_list);
|
||||
mEmailsList = (LoadingRecyclerView) v.findViewById(R.id.emails_list);
|
||||
View empty = v.findViewById(R.id.empty);
|
||||
ProgressWheel loading = (ProgressWheel) v.findViewById(R.id.loading);
|
||||
mEmailsList.setLoadingView(empty, loading);
|
||||
|
||||
mNewEmail = (ImageButton) v.findViewById(R.id.promoted_action);
|
||||
mNewEmail.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package i2p.bote.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
|
||||
public class LoadingRecyclerView extends RecyclerView {
|
||||
private View mLoadingView;
|
||||
private ProgressWheel mLoadingWheel;
|
||||
private boolean mLoading;
|
||||
final private AdapterDataObserver observer = new AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
mLoading = false;
|
||||
updateLoading();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
mLoading = false;
|
||||
updateLoading();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||
mLoading = false;
|
||||
updateLoading();
|
||||
}
|
||||
};
|
||||
|
||||
public LoadingRecyclerView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public LoadingRecyclerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public LoadingRecyclerView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
private void updateLoading() {
|
||||
if (mLoadingView != null) {
|
||||
mLoadingView.setVisibility(mLoading ? VISIBLE : GONE);
|
||||
setVisibility(mLoading ? GONE : VISIBLE);
|
||||
if (mLoadingWheel != null) {
|
||||
if (mLoading && !mLoadingWheel.isSpinning())
|
||||
mLoadingWheel.spin();
|
||||
else if (!mLoading && mLoadingWheel.isSpinning())
|
||||
mLoadingWheel.stopSpinning();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(Adapter adapter) {
|
||||
final Adapter oldAdapter = getAdapter();
|
||||
if (oldAdapter != null) {
|
||||
oldAdapter.unregisterAdapterDataObserver(observer);
|
||||
}
|
||||
super.setAdapter(adapter);
|
||||
if (adapter != null) {
|
||||
adapter.registerAdapterDataObserver(observer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the views to use for showing state.
|
||||
* <p/>
|
||||
* This method also sets the state to "loading".
|
||||
*
|
||||
* @param loadingView The view to show in place of the RecyclerView while loading.
|
||||
* @param progressWheel The indeterminate ProgressWheel to spin while loading, if any.
|
||||
*/
|
||||
public void setLoadingView(View loadingView, ProgressWheel progressWheel) {
|
||||
mLoadingView = loadingView;
|
||||
mLoadingWheel = progressWheel;
|
||||
setLoading(true);
|
||||
}
|
||||
|
||||
public void setLoading(boolean loading) {
|
||||
mLoading = loading;
|
||||
updateLoading();
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,31 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/emails_list"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<i2p.bote.android.util.LoadingRecyclerView
|
||||
android:id="@+id/emails_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.pnikosis.materialishprogress.ProgressWheel
|
||||
android:id="@+id/loading"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
app:barColor="@color/accent"
|
||||
app:progressIndeterminate="true"/>
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<net.i2p.android.ext.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/promoted_action"
|
||||
|
||||
@@ -10,11 +10,31 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/emails_list"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<i2p.bote.android.util.LoadingRecyclerView
|
||||
android:id="@+id/emails_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.pnikosis.materialishprogress.ProgressWheel
|
||||
android:id="@+id/loading"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
app:barColor="@color/accent"
|
||||
app:progressIndeterminate="true"/>
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<net.i2p.android.ext.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/promoted_action"
|
||||
|
||||
6
app/src/main/res/layout/listitem_empty.xml
Normal file
6
app/src/main/res/layout/listitem_empty.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_height_one_line"
|
||||
android:gravity="center"/>
|
||||
Reference in New Issue
Block a user