我们都知道在Android中scrollview和listview都能滑动,如果scrollview嵌套listview会出现一些问题,比如listview不能正常显示item...但是在一些项目中,一些页面内容比较多,需要在外面放一个scrollview,里面还会嵌套listview,而listview上面还有很多布局。这时候就会出现一些问题。所以遇见这种情况我们要重新listview的onMeasure方法,
设为最大模式(MeasureSpec.AT_MOST)这个也就是父组件,能够给出的最大的空间,当前组件的长或宽最大只能为这么大,当然也可以比这个小。意思是在scrollview中让listview显示所有的item。
public class MyListView extends ListView{
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
如果这时候还要实现listview的的下拉刷新上拉加载更多,那就会比较麻烦了,因为listview上面还有很多布局,显然这时候用传统的listview的下拉刷新上拉加载更多是不行的。那么我们是否可以换一种思路来想,我们是否可以封装一个可以下拉刷新,上拉更多的scrollview,在scrollview的上拉刷新下拉更多的监听事件里调用listview的下拉刷新上拉加载更多的方法,然后更新一下listview的adapter。是不是这样就可以实现scrollview中嵌套listview的下拉刷新上拉加载更多了。
public class PullToRefreshLayout extends RelativeLayout {
public static final String TAG = "PullToRefreshLayout";
// 初始状态
public static final int INIT = 0;
// 释放刷新
public static final int RELEASE_TO_REFRESH = 1;
// 正在刷新
public static final int REFRESHING = 2;
// 释放加载
public static final int RELEASE_TO_LOAD = 3;
// 正在加载
public static final int LOADING = 4;
// 操作完毕
public static final int DONE = 5;
// 当前状态
private int state = INIT;
// 刷新回调接口
private OnRefreshListener mListener;
// 刷新成功
public static final int SUCCEED = 0;
// 刷新失败
public static final int FAIL = 1;
// 按下Y坐标,上一个事件点Y坐标
private float downY, lastY;
// 下拉的距离。注意:pullDownY和pullUpY不可能同时不为0
public float pullDownY = 0;
// 上拉的距离
private float pullUpY = 0;
// 释放刷新的距离
private float refreshDist = 200;
// 释放加载的距离
private float loadmoreDist = 200;
private MyTimer timer;
// 回滚速度
public float MOVE_SPEED = 8;
// 第一次执行布局
private boolean isLayout = false;
// 在刷新过程中滑动操作
private boolean isTouch = false;
// 手指滑动距离与下拉头的滑动距离比,中间会随正切函数变化
private float radio = 2;
// 下拉箭头的转180°动画
private RotateAnimation rotateAnimation;
// 均匀旋转动画
private RotateAnimation refreshingAnimation;
// 下拉头
private View refreshView;
// 下拉的箭头
private View pullView;
// 正在刷新的图标
private View refreshingView;
// 刷新结果图标
private View refreshStateImageView;
// 刷新结果:成功或失败
private TextView refreshStateTextView;
// 上拉头
private View loadmoreView;
// 上拉的箭头
private View pullUpView;
// 正在加载的图标
private View loadingView;
// 加载结果图标
private View loadStateImageView;
// 加载结果:成功或失败
private TextView loadStateTextView;
// 实现了Pullable接口的View
private View pullableView;
// 过滤多点触碰
private int mEvents;
// 这两个变量用来控制pull的方向,如果不加控制,当情况满足可上拉又可下拉时没法下拉
private boolean canPullDown =