上拉加载,下拉刷新的列表控件,大家一定都封装过,或者使用过
源代码,我会在最后贴出来
这篇代码主要是为了解决两个问题
1.滑动冲突得问题
2.listview无数据时,无数据布局的展示问题
下方列出的代码,主要就是为了解决listview与父布局之间的滑动冲突
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
private boolean mIsEnd = false;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mOnScrollListener != null) {
mOnScrollListener.onScrollStateChanged(view, scrollState);
}
if (scrollState == SCROLL_STATE_IDLE) {
//1:到达底部 2:底部当前可以加载更多 3:顶部不在刷新中状态
Log.i("syntapp", mIsEnd + "===" + mLoadMoreStatus + "====" + isRefreshing());
if (mIsEnd && mLoadMoreStatus == LoadMoreStatus.CLICK_TO_LOAD && !isRefreshing()) {
setLoadMoreStatus(LoadMoreStatus.LOADING);
if (mLoadMoreStatus != null) {
mOnLoadListener.onLoad(false);
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
mIsEnd = firstVisibleItem + visibleItemCount >= totalItemCount - 1;
if (mOnMyScrollListener != null) {
mOnMyScrollListener.onScrollItem(firstVisibleItem, visibleItemCount, totalItemCount);
}
}
});
super.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
if (mLoadMoreStatus != LoadMoreStatus.LOADING) {
if (mOnLoadListener != null) {
mOnLoadListener.onLoad(true);
// mEmptyView.setVisibility(GONE);
}
} else {
SimpleListView.super.setRefreshing(false);
}
}
});
那么接下来我们来解决listView的恐怖剧展示问题
//1.我们需要添加一个空布局的显示,这里的activity_no_data可以根据自己的实际需要去设计
mEmptyView = LayoutInflater.from(context).inflate(R.layout.activity_no_data, null);
mListView = new ListView(context, attrs);
FrameLayout rl = new FrameLayout(context);
rl.addView(mEmptyView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
rl.addView(mListView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(rl);
//2.我们需要解决listview在上拉加载和下拉刷新的触摸事件,让我们想要的的触摸极致点位与代码上的判断重合
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (mListView.getChildAt(0) != null && mListView.getFirstVisiblePosition() == 0 &&
mListView.getChildAt(0).getTop() >= 0) {//或者 listView.getChildAt(0).getTop() >= listView.getListPaddingTop())
((ViewGroup) ((ViewGroup) mListView.getParent()).getParent()).setEnabled(true);
Log.d("TAG", "reach top!!!");
} else {
if (mListView.getAdapter().getCount() == 0) {
((ViewGroup) ((ViewGroup) mListView.getParent()).getParent()).setEnabled(true);
} else {
((ViewGroup) ((ViewGroup) mListView.getParent()).getParent()).setEnabled(false);
}
Log.d("TAG", "not reach top!!!");
}
}
return false;
}
});
接下来,我贴出来全部的代码段,当然了,这里面还是有很多无用的代码段,根据自己的实际需求去增删吧
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.DataSetObserver;
import android.os.Parcelable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.avicsafety.lib.R;
public class SimpleListView extends SwipeRefreshLayout {
private ListView mListView;
private LoadMoreStatus mLoadMoreStatus = LoadMoreStatus.CLICK_TO_LOAD;
private OnLoadListener mOnLoadListener;
private OnMyScrollListener mOnMyScrollListener;
private TextView mLoadMoreView;
private AbsListView.OnScrollListener mOnScrollListener;
private View mEmptyView;
private ListAdapter mAdapter;
private float startY;
private float startX;
// 记录viewPager是否拖拽的标记
private boolean mIsVpDragger;
private int mTouchSlop;
/**
* 加载更多状态
*/
public enum LoadMoreStatus {
/**
* 点击加载更多
*/
CLICK_TO_LOAD,
/**
* 正在加载
*/
LOADING,
/**
* 没有更多内容了
*/
LOADED_ALL
}
/**
* 加载监听器
*/
public interface OnLoadListener {
/**
* 下来刷新或者加载更多时触发该回调
*
* @param isRefresh true为下拉刷新 false为加载更多
*/
void onLoad(boolean isRefresh);
}
public interface OnMyScrollListener {
void onScrollItem(int firstVisibleItem, int visibleItemCount, int totalItemCount);
}
public SimpleListView(Context context) {
super(context);
init(context, null);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
public SimpleListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
mEmptyView = LayoutInflater.from(context).inflate(R.layout.activity_no_data, null);
emptyView = mEmptyView;
mListView = new ListView(context, attrs);
FrameLayout rl = new FrameLayout(context);
rl.addView(mEmptyView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
rl.addView(mListView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(rl);
// addView(mListView,new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// ((ViewGroup)mListView.getParent()).addView(mEmptyView);
// mListView.setEmptyView(mEmptyView);
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
private boolean mIsEnd = false;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mOnScrollListener != null) {
mOnScrollListener.onScrollStateChanged(view, scrollState);
}
if (scrollState == SCROLL_STATE_IDLE) {
//1:到达底部 2:底部当前可以加载更多 3:顶部不在刷新中状态
Log.i("syntapp", mIsEnd + "===" + mLoadMoreStatus + "====" + isRefreshing());
if (mIsEnd && mLoadMoreStatus == LoadMoreStatus.CLICK_TO_LOAD && !isRefreshing()) {
setLoadMoreStatus(LoadMoreStatus.LOADING);
if (mLoadMoreStatus != null) {
mOnLoadListener.onLoad(false);
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
mIsEnd = firstVisibleItem + visibleItemCount >= totalItemCount - 1;
if (mOnMyScrollListener != null) {
mOnMyScrollListener.onScrollItem(firstVisibleItem, visibleItemCount, totalItemCount);
}
}
});
super.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
if (mLoadMoreStatus != LoadMoreStatus.LOADING) {
if (mOnLoadListener != null) {
mOnLoadListener.onLoad(true);
// mEmptyView.setVisibility(GONE);
}
} else {
SimpleListView.super.setRefreshing(false);
}
}
});
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (mListView.getChildAt(0) != null && mListView.getFirstVisiblePosition() == 0 &&
mListView.getChildAt(0).getTop() >= 0) {//或者 listView.getChildAt(0).getTop() >= listView.getListPaddingTop())
((ViewGroup) ((ViewGroup) mListView.getParent()).getParent()).setEnabled(true);
Log.d("TAG", "reach top!!!");
} else {
if (mListView.getAdapter().getCount() == 0) {
((ViewGroup) ((ViewGroup) mListView.getParent()).getParent()).setEnabled(true);
} else {
((ViewGroup) ((ViewGroup) mListView.getParent()).getParent()).setEnabled(false);
}
Log.d("TAG", "not reach top!!!");
}
}
return false;
}
});
}
public void setSelection(int position) {
if (mListView != null) {
mListView.setSelection(position);
}
}
public void addHeaderView(View view) {
mListView.addHeaderView(view);
}
public void addHeaderView(View v, Object data, boolean isSelectable) {
mListView.addHeaderView(v, data, isSelectable);
}
public void addFooterView(View view) {
mListView.addFooterView(view);
}
public void addFooterView(View v, Object data, boolean isSelectable) {
mListView.addFooterView(v, data, isSelectable);
}
public void setOnScrollListener(AbsListView.OnScrollListener listener) {
mOnScrollListener = listener;
}
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
mListView.setOnItemClickListener(listener);
}
public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener) {
mListView.setOnItemLongClickListener(listener);
}
public void setEmptyView(View emptyView) {
if (emptyView != null) {
mEmptyView = emptyView;
if (mAdapter != null && mAdapter.getCount() > 0) {
mEmptyView.setVisibility(View.GONE);
} else {
mEmptyView.setVisibility(View.VISIBLE);
}
// mListView.setEmptyView(emptyView);
}
}
public void setEmptyView(boolean fale) {
if (fale) {
mEmptyView.setVisibility(VISIBLE);
} else {
mEmptyView.setVisibility(GONE);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// 记录手指按下的位置
startY = ev.getY();
startX = ev.getX();
// 初始化标记
mIsVpDragger = false;
break;
case MotionEvent.ACTION_MOVE:
// 如果viewpager正在拖拽中,那么不拦截它的事件,直接return false;
if (mIsVpDragger) {
return false;
}
// 获取当前手指位置
float endY = ev.getY();
float endX = ev.getX();
float distanceX = Math.abs(endX - startX);
float distanceY = Math.abs(endY - startY);
// 如果X轴位移大于Y轴位移,那么将事件交给viewPager处理。
if (distanceX > mTouchSlop && distanceX > distanceY) {
mIsVpDragger = true;
return false;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// 初始化标记
mIsVpDragger = false;
break;
}
// 如果是Y轴位移大于X轴,事件交给swipeRefreshLayout处理。
return super.onInterceptTouchEvent(ev);
}
@Override
@Deprecated
public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
}
@Override
@Deprecated
public void setRefreshing(boolean refreshing) {
}
public void setAdapter(final ListAdapter adapter) {
if (adapter == null) {
return;
}
mAdapter = adapter;
if (mLoadMoreView == null) {
mLoadMoreView = new TextView(getContext());
mLoadMoreView.setTextColor(0xff333333);
mLoadMoreView.setTextSize(14);
mLoadMoreView.setGravity(Gravity.CENTER);
// int count = adapter.getCount();
// mLoadMoreView.setVisibility(count == 0 ? View.GONE : View.VISIBLE);
// if (mEmptyView != null) {
// mEmptyView.setVisibility(count == 0 ? View.VISIBLE : View.GONE);
// }
mLoadMoreView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mLoadMoreStatus == LoadMoreStatus.CLICK_TO_LOAD && !isRefreshing()) {
setLoadMoreStatus(LoadMoreStatus.LOADING);
if (mLoadMoreStatus != null) {
mOnLoadListener.onLoad(false);
}
}
}
});
mLoadMoreView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, getResources().getDimensionPixelOffset(R.dimen.dp10) * 4));
// mListView.addFooterView(mLoadMoreView);
}
mListView.setAdapter(adapter);
// adapter.registerDataSetObserver(new DataSetObserver() {
// @Override
// public void onChanged() {
// int count = adapter.getCount();
// mLoadMoreView.setVisibility(count == 0 ? View.GONE : View.VISIBLE);
// if (mEmptyView != null) {
// mEmptyView.setVisibility(count == 0 ? View.VISIBLE : View.GONE);
// }
// }
// });
}
private void setLoadMoreStatus(LoadMoreStatus status) {
mLoadMoreStatus = status;
if (mLoadMoreView != null) {
// if (mLoadMoreStatus == LoadMoreStatus.LOADED_ALL) {
// mLoadMoreView.setText("没有更多内容了");
// } else if (mLoadMoreStatus == LoadMoreStatus.LOADING) {
// mLoadMoreView.setText("正在加载...");
// } else {
// mLoadMoreView.setText("点击加载更多");
// }
if (mLoadMoreStatus == LoadMoreStatus.LOADED_ALL) {
mLoadMoreView.setText("");
mLoadMoreView.setVisibility(GONE);
} else if (mLoadMoreStatus == LoadMoreStatus.LOADING) {
mLoadMoreView.setText("正在加载...");
mLoadMoreView.setVisibility(VISIBLE);
} else {
mLoadMoreView.setText("");
mLoadMoreView.setVisibility(GONE);
}
}
}
public void setOnLoadListener(OnLoadListener listener) {
mOnLoadListener = listener;
}
public void setmOnMyScrollListener(OnMyScrollListener listener) {
mOnMyScrollListener = listener;
}
public void finishLoad(boolean loadAll) {
super.setRefreshing(false);
setLoadMoreStatus(loadAll ? LoadMoreStatus.LOADED_ALL : LoadMoreStatus.CLICK_TO_LOAD);
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
try {
super.onRestoreInstanceState(state);
} catch (Exception e) {
}
state = null;
}
private static View emptyView;
public static class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, final Intent intent) {
// Toast.makeText(context,"Intent Detected.", Toast.LENGTH_LONG).show();
if (emptyView != null) {
emptyView.setVisibility(GONE);
}
}
}
}