zoukankan      html  css  js  c++  java
  • Android自定义下拉刷新

    网上的下拉刷新功能很多,不过基本上都是隐藏header的,而项目里面需要只隐藏部分的header,类似QQ好友动态的效果,修改了一些现有的,最后有很多问题,所以就自己自定义了一个,逻辑也很简单,首先就是重写ListView,然后覆写onTouchEvent,然后根据手的触摸位置计算差值,然后移动header.下面是效果图:

    主要的部分就是下拉刷新组件,代码如下,里面我都要注释:

    package com.jwzhangjie.mypullrefresh;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    public class PullReFreshLibrary extends ListView{
    	//下拉的父布局
    	private LinearLayout conterViewLayout;
    	//实现下拉的头部
    	private RelativeLayout headerView;
    	//提示下拉状态
    	private TextView pullTextView;
    	private LayoutInflater mInflater;
    	//下拉框的高度
    	private int headviewHeight;
    	//下拉框距离顶部的初始高度
    	private int initHeight;
    	//手按下去的y轴坐标
    	private int initPosition = 0;
    	//最新的手的y轴坐标
    	private int lastPositon =0;
    	//下拉移动的最小距离
    	private int minMarge = 5;
    	//当前下拉head的距离顶部的高度
    	private int currentHeight = -100;
    	//下拉head的各种状态
    	private static enum State{
            PULL_TO_REFRESH,
            RELEASE_TO_REFRESH,
            REFRESHING,
            REFRESHCOMPLETE,
        }
    	private State state = State.PULL_TO_REFRESH;
    	
    	public PullReFreshLibrary(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		mInflater = LayoutInflater.from(context);
    		conterViewLayout = (LinearLayout) mInflater.inflate(R.layout.headview, null);
    		headerView = (RelativeLayout)conterViewLayout.findViewById(R.id.testHeader);
    		pullTextView = (TextView)headerView.findViewById(R.id.pullTextView);
    		headviewHeight = (int)context.getResources().getDimensionPixelSize(R.dimen.header_view_height);
    		initHeight = (int)context.getResources().getDimensionPixelSize(R.dimen.init_height);
    		addHeaderView(conterViewLayout);
    	}
    	
    	@Override
    	public boolean onTouchEvent(MotionEvent ev) {
    		if (state == State.REFRESHING) {
    			return true;
    		}
    		switch (ev.getAction()) {
    		case MotionEvent.ACTION_DOWN:
    			initPosition = (int)ev.getY();
    			break;
    		case MotionEvent.ACTION_MOVE:
    			if (getFirstVisiblePosition() == 0) {
    				lastPositon = (int)ev.getY();
    				int diff = lastPositon - initPosition;
    				if (Math.abs(diff) > minMarge) {
    					diff = (int)(diff / 2.7);
    				}
    				initPosition = lastPositon;
    				int newHeaderPadding = Math.max(Math.round(currentHeight + diff),  -headviewHeight);
    				if (state != State.REFRESHING && newHeaderPadding != currentHeight) {
    					if (newHeaderPadding > 0) {
    						currentHeight = 0;
    					}else {
    						currentHeight = newHeaderPadding;
    					}
    					margeTop();
    				}
    			}
    			break;
    		case MotionEvent.ACTION_UP:
    			if (state == State.RELEASE_TO_REFRESH) {
    				setState(State.RELEASE_TO_REFRESH);
    			}else if (getFirstVisiblePosition() == 0 && currentHeight > -initHeight) {
    				resetHeader();
    			}
    			break;
    		}
    		return super.onTouchEvent(ev);
    	}
    
    	/**
    	 * 设置下拉head的状态以及处理功能
    	 * @param state
    	 */
    	private void setState(State state){
    		this.state = state;
    		switch (state) {
    		case PULL_TO_REFRESH:
    			pullTextView.setVisibility(View.VISIBLE);
    			pullTextView.setText("下拉刷新");
    			break;
    		case RELEASE_TO_REFRESH:
    			if (onRefreshListener == null) {
    				state = State.PULL_TO_REFRESH;
    				resetHeader();
    			}else {
    				state = State.REFRESHING;
    				pullTextView.setVisibility(View.VISIBLE);
    				pullTextView.setText("刷新中...");
    				onRefreshListener.onRefresh();
    			}
    			break;
    		case REFRESHCOMPLETE:
    			state = State.PULL_TO_REFRESH;
    			pullTextView.setText("下拉刷新");
    			resetHeader();
    			break;
    		}
    	}
    	/**
    	 * 设置下拉head距离顶部的高度
    	 */
    	private void margeTop(){
    		MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) headerView.getLayoutParams();
    		mlp.topMargin = currentHeight;
            headerView.setLayoutParams(mlp);
            if (currentHeight > -10 && state != State.RELEASE_TO_REFRESH) {
            	state = State.RELEASE_TO_REFRESH;
            	pullTextView.setText("松手刷新");
    		}else if (currentHeight < -10 && state != State.PULL_TO_REFRESH) {
    			state = State.PULL_TO_REFRESH;
    			pullTextView.setText("下拉刷新");
    		}
    	}
    	/**
    	 * 初始化下拉head的高度
    	 */
    	private void resetHeader(){
    		MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) headerView.getLayoutParams();
    		mlp.topMargin = -initHeight;
    		currentHeight = -initHeight;
    		headerView.setLayoutParams(mlp);
    	}
    	/**
    	 * 实现刷新过程的回调接口
    	 */
    	private OnRefreshListener onRefreshListener;
    	
    	public void setOnRefreshListener(OnRefreshListener onRefreshListener){
    		this.onRefreshListener = onRefreshListener;
    	}
    	public interface OnRefreshListener{
            public void onRefresh();
        }
    	/**
    	 * 刷新完成调用
    	 */
    	 public void onRefreshComplete(){
    		 setState(State.REFRESHCOMPLETE);
    	}
    	 
    }
    


    适配器adater,这个很简陋,主要是辅助测试

    package com.jwzhangjie.mypullrefresh;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    public class MyAdapter extends BaseAdapter{
    
    	private LayoutInflater mInflater;
    	public MyAdapter(Context context){
    		mInflater = LayoutInflater.from(context);
    	}
    	@Override
    	public int getCount() {
    		return 19;
    	}
    
    	@Override
    	public Object getItem(int position) {
    		return null;
    	}
    
    	@Override
    	public long getItemId(int position) {
    		return 0;
    	}
    
    	@Override
    	public View getView(int position, View convertView, ViewGroup parent) {
    		TextView textView;
    		if (convertView == null) {
    			convertView = mInflater.inflate(R.layout.item_listview, null);
    			textView = (TextView)convertView.findViewById(R.id.item_test);
    			convertView.setTag(textView);
    		}else {
    			textView = (TextView)convertView.getTag();
    		}
    		textView.setText("测试数据:"+position);
    		return convertView;
    	}
    	
    }
    


    然后就是Activity的调用:

    package com.jwzhangjie.mypullrefresh;
    
    import com.jwzhangjie.mypullrefresh.PullReFreshLibrary.OnRefreshListener;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.annotation.SuppressLint;
    import android.app.Activity;
    
    public class MainActivity extends Activity {
    
    	private MyAdapter myAdapter;
    	private PullReFreshLibrary listView;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		myAdapter = new MyAdapter(this);
    		listView = (PullReFreshLibrary)findViewById(R.id.testpull);
    		listView.setAdapter(myAdapter);
    		listView.setOnRefreshListener(new OnRefreshListener() {
    			@Override
    			public void onRefresh() {
    				handler.sendEmptyMessageDelayed(1, 4000);
    			}
    		});
    	}
    	@SuppressLint("HandlerLeak")
    	public Handler handler = new Handler(){
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			listView.onRefreshComplete();
    		}
    		
    	};
    }
    


    我里面的布局也都很简单,

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
       <com.jwzhangjie.mypullrefresh.PullReFreshLibrary 
           android:id="@+id/testpull"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           ></com.jwzhangjie.mypullrefresh.PullReFreshLibrary>
    
    </LinearLayout>
    


    headview.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
    	<RelativeLayout 
    	    android:id="@+id/testHeader"
    	    android:layout_width="match_parent"
    	        android:layout_height="300dip"
    	        android:layout_marginTop="-48dip"
    	         android:background="@drawable/main_photo2"
    	         >
    		<LinearLayout
                android:id="@+id/ptr_id_textwrapper" 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="10dip"
                android:background="@drawable/refresh_text_bg"
                >
                <TextView 
                    android:id="@+id/pullTextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingLeft="20dip"
                    android:paddingRight="20dip"
                    android:paddingTop="5dip"
                    android:paddingBottom="5dip"
                    android:textSize="12sp"
                    android:textColor="#FFFFFFFF"
                    android:layout_gravity="center"
                      android:text="测试刷新"
                     />
            </LinearLayout>
    	</RelativeLayout>
        </LinearLayout>
    


    item_listview.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        
    	<TextView 
    	    android:id="@+id/item_test"
    	    android:layout_width="match_parent"
    	    android:layout_height="40dip"
    	    />
    </LinearLayout>
    


     

     <dimen name="init_height">48dip</dimen>
     <dimen name="header_view_height">300dip</dimen>


     

  • 相关阅读:
    maven安装以及eclipse配置maven
    jquery 图片文件转base64 显示
    Java 解析Excel文件为JSON
    Dropwizard框架入门
    使用Spring Security和OAuth2实现RESTful服务安全认证
    SQL语句大小写是否区分的问题,批量修改整个数据库所有表所有字段大小写
    13个可实现超棒数据可视化效果的Javascript框架
    C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密
    C#使用RSA证书文件加密和解密示例
    C# 中使用 RSA加解密算法
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3478958.html
Copyright © 2011-2022 走看看