自定义控件(PullToRefreshListView,XListView)的原理

来源:互联网 发布:约瑟夫环数组 编辑:程序博客网 时间:2024/06/06 05:16

现在的很多手机新闻客户端,包括qq空间都有下拉刷新的功能,而在github上也有很多类似下拉刷新的开源框架。那其中的原理是什么。。今天闲着蛋疼,就写了一个类似的功能。让我们近距离的了解一下下拉刷新

首先我规划了下拉刷新的几个步骤

1. 些一个headView的布局文件

 

2. 在构造器中初始化headView

 

3. 并且当前自定义控件的对象调用setHeadView添加到头部()

 

4. 设置headView .padding 隐藏 headView 到 屏幕 上方

 

5. 但是需要measureheadView):

  因为创建对象的时候,并不会直接调用onMeasureonMeasure会调用measure),Activity onceate不会测量,会在onstart的时候测量,

activitynew出来的ViewGroup 要显示,或者自定义的ViewGroup 中要测量元素,或者的宽高度的时候 需要调用measure(不用复写onMeasure测量,ListView自己测量)

 

6.调用getMeasureHeight

 

7. (不复写onLayout 摆放,ListView自己摆放)

 

8. 

<span style="background-color: rgb(0, 0, 0);">public class PullRefreshListView extends ListView{private static int STATUS = 0;private static final int IDEL = 1;private static final int REFLASH = 2;private static final int KEYTOP = 3;private ImageView arrow;private TextView tv;View view;//设置成成员变量 因为ontouchEvent也会调用public PullRefreshListView(Context context, AttributeSet attrs) {super(context, attrs);initHeadView(context);}public PullRefreshListView(Context context) {super(context);initHeadView(context);}private void initHeadView(Context context) {view = View.inflate(context, R.layout.headview, null);arrow = (ImageView) view.findViewById(R.id.arrow);tv = (TextView) view.findViewById(R.id.tv);view.measure(0, 0);heightFlag = -view.getMeasuredHeight();height =  heightFlag;view.setPadding(0, height, 0, 0);this.addHeaderView(view);}int heightFlag;//不变的int height;//变化的int startY;@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:startY = (int) ev.getRawY(); break;case MotionEvent.ACTION_MOVE:int newY = (int) ev.getRawY();int dY = newY - startY;height += dY;view.setPadding(0, height, 0, 0);startY = newY;if (height > 0) {//松手刷新STATUS = REFLASH;}else if (height < 0 && height > heightFlag) {STATUS = IDEL;}else {height = heightFlag;System.out.println(height);view.setPadding(0, height, 0, 0);STATUS = KEYTOP;}break;case MotionEvent.ACTION_UP:switch (STATUS) {case IDEL:view.setPadding(0, heightFlag, 0, 0);break;case REFLASH:height = 0;view.setPadding(0, height, 0, 0);//加载数据if (listener != null) {listener.perExecute();}new Thread(){public void run() {//模拟刷新//SystemClock.sleep(5000);//height = heightFlag;//handler.post(new Runnable() {//@Override//public void run() {//view.setPadding(0, heightFlag, 0, 0);//}//});if (listener != null) {listener.doInBackground();handler.post(new Runnable() {@Overridepublic void run() {//height = heightFlag;//view.setPadding(0, heightFlag, 0, 0);listener.doPostExecute();}});}};}.start();break;case KEYTOP://do nothingbreak;}break;}return true;}public interface PullRefreshListViewListener{void perExecute();void doInBackground();void doPostExecute();}private PullRefreshListViewListener listener;public void setListener(PullRefreshListViewListener listener) {this.listener = listener;}private Handler handler = new Handler();}</span>

 设置 当前自定义控件 的监听事件


0 0
原创粉丝点击