mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 19:29:06 +01:00
197 lines
5.3 KiB
Java
197 lines
5.3 KiB
Java
package org.briarproject.android.util;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.TypedArray;
|
|
import android.os.Build;
|
|
import android.support.v7.widget.RecyclerView;
|
|
import android.support.v7.widget.RecyclerView.Adapter;
|
|
import android.util.AttributeSet;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.widget.FrameLayout;
|
|
import android.widget.ProgressBar;
|
|
import android.widget.TextView;
|
|
|
|
import org.briarproject.R;
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION;
|
|
|
|
public class BriarRecyclerView extends FrameLayout {
|
|
|
|
private static final long DEFAULT_REFRESH_INTERVAL = MIN_RESOLUTION;
|
|
private static final Logger LOG =
|
|
Logger.getLogger(BriarRecyclerView.class.getName());
|
|
|
|
private RecyclerView recyclerView;
|
|
private TextView emptyView;
|
|
private ProgressBar progressBar;
|
|
private RecyclerView.AdapterDataObserver emptyObserver;
|
|
private Runnable refresher = null;
|
|
private boolean isScrollingToEnd = false;
|
|
|
|
public BriarRecyclerView(Context context) {
|
|
this(context, null, 0);
|
|
}
|
|
|
|
public BriarRecyclerView(Context context, AttributeSet attrs) {
|
|
this(context, attrs, 0);
|
|
}
|
|
|
|
public BriarRecyclerView(Context context, AttributeSet attrs,
|
|
int defStyle) {
|
|
super(context, attrs, defStyle);
|
|
|
|
TypedArray attributes = context.obtainStyledAttributes(attrs,
|
|
R.styleable.BriarRecyclerView);
|
|
isScrollingToEnd = attributes
|
|
.getBoolean(R.styleable.BriarRecyclerView_scrollToEnd, true);
|
|
attributes.recycle();
|
|
}
|
|
|
|
@Override
|
|
protected void onDetachedFromWindow() {
|
|
super.onDetachedFromWindow();
|
|
stopPeriodicUpdate();
|
|
}
|
|
|
|
private void initViews() {
|
|
View v = LayoutInflater.from(getContext()).inflate(
|
|
R.layout.briar_recycler_view, this, true);
|
|
|
|
recyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);
|
|
emptyView = (TextView) v.findViewById(R.id.emptyView);
|
|
progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
|
|
|
|
showProgressBar();
|
|
|
|
// scroll down when opening keyboard
|
|
if (isScrollingToEnd && Build.VERSION.SDK_INT >= 11) {
|
|
recyclerView.addOnLayoutChangeListener(
|
|
new View.OnLayoutChangeListener() {
|
|
@Override
|
|
public void onLayoutChange(View v, int left, int top,
|
|
int right, int bottom, int oldLeft, int oldTop,
|
|
int oldRight, int oldBottom) {
|
|
if (bottom < oldBottom) {
|
|
recyclerView.postDelayed(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
scrollToPosition(
|
|
recyclerView.getAdapter()
|
|
.getItemCount() - 1);
|
|
}
|
|
}, 100);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
emptyObserver = new RecyclerView.AdapterDataObserver() {
|
|
@Override
|
|
public void onItemRangeInserted(int positionStart, int itemCount) {
|
|
super.onItemRangeInserted(positionStart, itemCount);
|
|
if (itemCount > 0) showData();
|
|
}
|
|
};
|
|
}
|
|
|
|
public void setLayoutManager(RecyclerView.LayoutManager layout) {
|
|
if (recyclerView == null) initViews();
|
|
recyclerView.setLayoutManager(layout);
|
|
}
|
|
|
|
public void setAdapter(Adapter adapter) {
|
|
if (recyclerView == null) initViews();
|
|
|
|
Adapter oldAdapter = recyclerView.getAdapter();
|
|
if (oldAdapter != null) {
|
|
oldAdapter.unregisterAdapterDataObserver(emptyObserver);
|
|
}
|
|
|
|
recyclerView.setAdapter(adapter);
|
|
|
|
if (adapter != null) {
|
|
adapter.registerAdapterDataObserver(emptyObserver);
|
|
|
|
if (adapter.getItemCount() > 0) {
|
|
// only show data if adapter has data already
|
|
// otherwise progress bar is shown
|
|
emptyObserver.onChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setEmptyText(String text) {
|
|
if (recyclerView == null) initViews();
|
|
emptyView.setText(text);
|
|
}
|
|
|
|
public void setEmptyText(int res) {
|
|
if (recyclerView == null) initViews();
|
|
emptyView.setText(res);
|
|
}
|
|
|
|
public void showProgressBar() {
|
|
if (recyclerView == null) initViews();
|
|
recyclerView.setVisibility(INVISIBLE);
|
|
emptyView.setVisibility(INVISIBLE);
|
|
progressBar.setVisibility(VISIBLE);
|
|
}
|
|
|
|
public void showData() {
|
|
if (recyclerView == null) initViews();
|
|
Adapter adapter = recyclerView.getAdapter();
|
|
if (adapter != null) {
|
|
if (adapter.getItemCount() == 0) {
|
|
emptyView.setVisibility(VISIBLE);
|
|
recyclerView.setVisibility(INVISIBLE);
|
|
} else {
|
|
// use GONE here so empty view doesn't use space on small lists
|
|
emptyView.setVisibility(GONE);
|
|
recyclerView.setVisibility(VISIBLE);
|
|
}
|
|
progressBar.setVisibility(GONE);
|
|
}
|
|
}
|
|
|
|
public void scrollToPosition(int position) {
|
|
if (recyclerView == null) initViews();
|
|
recyclerView.scrollToPosition(position);
|
|
}
|
|
|
|
public void smoothScrollToPosition(int position) {
|
|
if (recyclerView == null) initViews();
|
|
recyclerView.smoothScrollToPosition(position);
|
|
}
|
|
|
|
public RecyclerView getRecyclerView() {
|
|
return this.recyclerView;
|
|
}
|
|
|
|
public void startPeriodicUpdate() {
|
|
if (recyclerView == null || recyclerView.getAdapter() == null) {
|
|
throw new IllegalStateException("Need to call setAdapter() first!");
|
|
}
|
|
refresher = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
LOG.info("Updating Content...");
|
|
recyclerView.getAdapter().notifyDataSetChanged();
|
|
postDelayed(refresher, DEFAULT_REFRESH_INTERVAL);
|
|
}
|
|
};
|
|
LOG.info("Adding Handler Callback");
|
|
postDelayed(refresher, DEFAULT_REFRESH_INTERVAL);
|
|
}
|
|
|
|
public void stopPeriodicUpdate() {
|
|
if (refresher != null) {
|
|
LOG.info("Removing Handler Callback");
|
|
removeCallbacks(refresher);
|
|
}
|
|
}
|
|
|
|
}
|