下拉刷新菜单
步骤:1、建立一个类RefreshListView继承ListView 2、为该ListView填充数据 2、然后定义一个头布局 3、通过ListView的addHeaderListView()将该布局加载到ListView的前面 4、通过paddingTop设置为负数来实现隐藏头部,但要先手动测量组件的高度和宽度 |
技术点: 0-1、 设置一个组件隐藏 android:visibility="gone" 0-2、设置ProgressBar样式(详解见下面) android:indeterminateDrawable="@drawable/custom_progressbar" 1、加到ListView的最前面 addHeaderView(viewHeader); 2、手动测量组件的高度和宽度,调用ListView私有的方法,复制过来 /**
* 2、测量并计算head的宽度和高度
* 测量item,这是在ListView中私有的方法,所以可以将其黏贴过来
* Measure a particular list child.
* TODO: unify with setUpChild.
* @param viewHeader The child.
*/
private void measureHeader(View viewHeader) {
ViewGroup.LayoutParams lp = viewHeader.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);// 测量标准
int lpHeight = lp.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
viewHeader.measure(childWidthSpec, childHeightSpec);
}3、如果获取测量后的高度,getMeasuredHeight()而不是getHeight() viewHeader.getMeasuredHeight();//获取测量后的高度 |
核心代码: package cn.zengfansheng.refreshListview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class RefreshListView extends ListView {
public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeader();// 初始化头
}
public RefreshListView(Context context) {
super(context);
initHeader();// 初始化头
}
/**
* 1、初始化头
*/
public void initHeader() {
View viewHeader = View.inflate(getContext(), R.layout.listview_head, null);
ImageView iv_arrow = (ImageView) viewHeader.findViewById(R.id.iv_arrow);
ProgressBar pb = (ProgressBar) viewHeader.findViewById(R.id.pb);
TextView tv_refresh = (TextView) viewHeader.findViewById(R.id.tv_refresh_status);
TextView tv_last_update = (TextView) viewHeader.findViewById(R.id.tv_last_update_time);
System.out.println("测量前,通过getHeight()获取viewHeader的高度:"+viewHeader.getHeight());//0
// 由于ListView每一个item,都会进行测量高度,但是现在还没有测量,所以需要手动测量
// 测量viewHeader的高度和宽度
measureHeader(viewHeader);
System.out.println("测量后,通过getHeight()获取viewHeader的高度:"+viewHeader.getHeight());//0
int viewHeaderMeasuredHeight = viewHeader.getMeasuredHeight();//获取测量后的高度
System.out.println("测量后,通过getMeasuredHeight()获取viewHeader的高度:"+viewHeaderMeasuredHeight);//59
// 如何实现head开始就隐藏呢,利用paddingTop
//viewHeader.setPadding(0, -viewHeaderMeasuredHeight / 2, 0, 0);//此时,只显示viewHeader高度的一半
viewHeader.setPadding(0, -viewHeaderMeasuredHeight, 0, 0);// 这样,就可以隐藏了
addHeaderView(viewHeader);
}
/**
* 2、测量并计算head的宽度和高度
* 测量item,这是在ListView中私有的方法,所以可以将其黏贴过来
* Measure a particular list child.
* TODO: unify with setUpChild.
* @param viewHeader The child.
*/
private void measureHeader(View viewHeader) {
ViewGroup.LayoutParams lp = viewHeader.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);// 测量标准
int lpHeight = lp.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
viewHeader.measure(childWidthSpec, childHeightSpec);
}
} |
|
1、 <ProgressBar
android:id="@+id/pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/custom_progressbar" />custom_progressbar.xml <?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
<shape
android:innerRadiusRatio="3" //内半径
android:shape="ring"
android:thicknessRatio="8" //宽度
android:useLevel="false" > //一直在转,来回在转
<gradient
android:centerColor="#FF6A6A"
android:endColor="#FF0000"
android:startColor="#FFFFFF"
android:type="sweep" /> //扫描
</shape>
</rotate>
|