より多くの機能の実装をロード
多くの友达は开発の中ですべてページのロードの需要に出会うことを信じて、この需要を満たすために、ListviewあるいはRecyclerViewを使うのに関わらずすべて1つのロードのもっと多い机能を必要として、多くの友达はネット上のドロップダウンのリフレッシュの実现の一大検索を発见して、どうしてロードがもっと多くて相対的に少ないのか、もっと多い机能をロードするのが比较的に简単なためです最も主要な原因は、より多くの機能をロードすることであり、厳密にはコントロールの機能として実現することはできませんが、ビジネスロジックとより密接になる必要があります.
以下では、ListViewのロード機能の実装について説明します.RecyclerViewの実装については、後述します.
まずListViewでこの機能を実現し,まずListViewのFooterViewを利用して異なる状態でFooterViewを表示または非表示にすることを考える.
OK、ListViewが一番下にスライドすると自動的にロードがトリガーされる機能を作りたいです.ListViewの親AbsListViewには、次の方法があります.
スライドリスニング、ListViewにはもちろんこの方法があります.このリスニングがあれば、ListViewスライドの状態をリスニングし、このリスニングを実現することができます.
私たちはここで仕事をすることができます.次は簡単です.
ここでは,ロード中のViewを表示する必要があるか否かを比較する.
次の作業は、FooterViewのステータスと表示と非表示を制御するための一連のインタフェースを提供することです.ListViewのフルコードを貼り付けます.
これはカスタムListViewです.FooterViewをロードし、ステータスを制御するクラスも必要です.
基本的には終わりですが、FooterViewのビューは自分で勝手に発揮しましょう.どんなにきれいにデザインしたいか、もっときれいにしましょう.
以下では、ListViewのロード機能の実装について説明します.RecyclerViewの実装については、後述します.
まずListViewでこの機能を実現し,まずListViewのFooterViewを利用して異なる状態でFooterViewを表示または非表示にすることを考える.
OK、ListViewが一番下にスライドすると自動的にロードがトリガーされる機能を作りたいです.ListViewの親AbsListViewには、次の方法があります.
public void setOnScrollListener(OnScrollListener l) {
mOnScrollListener = l;
invokeOnItemScrollListener();
}
スライドリスニング、ListViewにはもちろんこの方法があります.このリスニングがあれば、ListViewスライドの状態をリスニングし、このリスニングを実現することができます.
private OnScrollListener mOnScrollListener = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
};
私たちはここで仕事をすることができます.次は簡単です.
private boolean needLoad(int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int lastVisibleItem = firstVisibleItem + visibleItemCount;
boolean isAtListEnd = lastVisibleItem == totalItemCount;
return !mIsPullUpLoading && isAtListEnd;
}
ここでは,ロード中のViewを表示する必要があるか否かを比較する.
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Start a new loading when the last item scrolls into screen, instead of overriding method onTouchEvent.
if (needLoad(firstVisibleItem, visibleItemCount, totalItemCount)&&!hasNoMoreItem) {
startPullUpLoad();
L.d(" need scroll");
}
}
次の作業は、FooterViewのステータスと表示と非表示を制御するための一連のインタフェースを提供することです.ListViewのフルコードを貼り付けます.
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
/**
* Created by qiaopeng on 16/11/23.
*/
public class LoadMoreInterceptListView extends ListView {
public LoadMoreInterceptListView(Context context) {
this(context, null);
}
public LoadMoreInterceptListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadMoreInterceptListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private boolean hasNoMoreItem = false;
public interface OnPullUpLoadListener {
void onPullUpLoading();
}
public void setOnPullUpLoadListener(OnPullUpLoadListener listener) {
mOnPullUpLoadListener = listener;
}
// When loading finished, the controller should call this public method to update footer view.
public void onPullUpLoadFinished(boolean hasNoMoreItems) {
// Clear flag
mIsPullUpLoading = false;
hasNoMoreItem = hasNoMoreItems;
if (hasNoMoreItems) {
// when have no more items, update footer view to: NO MORE
mFooterView.updateView(PullUpLoadListViewFooter.State.NOT_LOADING, FOOTER_VIEW_CONTENT_NO_MORE,true);
} else {
// The other cases: (1)Loading succeed and still has more items, (2)Loading failed,
// should hide footer view.
hideFooterView();
}
}
private static final String FOOTER_VIEW_CONTENT_LOADING = " ...";
private static final String FOOTER_VIEW_CONTENT_NO_MORE = " ";
private PullUpLoadListViewFooter mFooterView;
// The flag used to avoid loading again when the list view is already in loading state.
private boolean mIsPullUpLoading;
// The controller should register this listener.
private OnPullUpLoadListener mOnPullUpLoadListener;
private void init() {
mIsPullUpLoading = false;
setOnScrollListener(mOnScrollListener);
}
private OnScrollListener mOnScrollListener = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
// do nothing.
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Start a new loading when the last item scrolls into screen, instead of overriding method onTouchEvent.
if (needLoad(firstVisibleItem, visibleItemCount, totalItemCount)&&!hasNoMoreItem) {
startPullUpLoad();
L.d(" need scroll");
}
}
private boolean needLoad(int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int lastVisibleItem = firstVisibleItem + visibleItemCount;
boolean isAtListEnd = lastVisibleItem == totalItemCount;
return !mIsPullUpLoading && isAtListEnd;
}
};
private void startPullUpLoad() {
if (mOnPullUpLoadListener != null) {
// Show the foot view and update its state to LOADING.
showFooterView();
// Set flag
mIsPullUpLoading = true;
// Call the callback to notify the listView's hosted controller to load data.
mOnPullUpLoadListener.onPullUpLoading();
}
}
private void showFooterView() {
if (mFooterView == null) {
mFooterView = new PullUpLoadListViewFooter(getContext());
addFooterView(mFooterView);
}
mFooterView.setVisibility(View.VISIBLE);
mFooterView.updateView(PullUpLoadListViewFooter.State.LOADING, FOOTER_VIEW_CONTENT_LOADING,true);
}
// It's better to hide footer instead of removing.
// Since after removing, we should create a new footer instance and add it into view hierarchy again,
// this will call findViewById many times which waste time.
private void hideFooterView() {
if (mFooterView != null) {
mFooterView.setVisibility(View.INVISIBLE);
}
}
}
これはカスタムListViewです.FooterViewをロードし、ステータスを制御するクラスも必要です.
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.umed.youyueyizu.R;
/**
* Created by qiaopeng on 16/11/23.
*/
public class PullUpLoadListViewFooter extends LinearLayout {
public enum State {
LOADING,
NOT_LOADING,
}
public PullUpLoadListViewFooter(Context context) {
this(context, null);
}
public PullUpLoadListViewFooter(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void updateView(State state, String content,boolean visible) {
if (visible){
if (state == State.LOADING) {
mLoadingLinearLayout.setVisibility(View.VISIBLE);
mNotLoadingLinearLayout.setVisibility(View.INVISIBLE);
mLoadingLabel.setText(content);
} else if (state == State.NOT_LOADING){
mLoadingLinearLayout.setVisibility(View.INVISIBLE);
mNotLoadingLinearLayout.setVisibility(View.VISIBLE);
mNotLoadingLabel.setText(content);
}}else{
mLoadingLinearLayout.setVisibility(View.INVISIBLE);
mNotLoadingLinearLayout.setVisibility(View.INVISIBLE);
mNotLoadingLabel.setText(content);
}
}
private LinearLayout mLoadingLinearLayout;
private TextView mLoadingLabel;
private LinearLayout mNotLoadingLinearLayout;
private TextView mNotLoadingLabel;
// pul in R.id.pul*** means "pull up load"
private void init() {
inflate(getContext(), R.layout.pull_listview_footer, this);
mLoadingLinearLayout = (LinearLayout) findViewById(R.id.pulListViewFooter_loading);
mLoadingLabel = (TextView) findViewById(R.id.pulListViewFooter_loadingLabel);
mNotLoadingLinearLayout = (LinearLayout) findViewById(R.id.pulListViewFooter_notLoading);
mNotLoadingLabel = (TextView) findViewById(R.id.pulListViewFooter_notLoadingLabel);
}
}
基本的には終わりですが、FooterViewのビューは自分で勝手に発揮しましょう.どんなにきれいにデザインしたいか、もっときれいにしましょう.