android 下拉刷新 快速实现

 

 

参考原文连接:http://blog.csdn.net/nono_love_lilith/article/details/7100845

先上图:

 

 

这里要用到的关键技术就是onTouch的拦截与分发,如果没有这个基础,先花一两分钟搞定消化我另外一篇文章:最快速掌握,及快速理解 onTouch 事件的拦截与分发   链接:http://blog.csdn.net/qishaohe/article/details/10221307

 

关键代码:RefreshableView.java

package com.qige.test;

import android.content.Context;
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.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Scroller;
import android.widget.TextView;

/**
 * 刷新控制view
 * 
 * @author Nono
 * 
 */
public class RefreshableView extends LinearLayout {

	private static final String TAG = "RefreshableView";
	private Scroller scroller;
	private View refreshView;
	private ImageView refreshIndicatorView;
	private int refreshHeight = 80;
	private ProgressBar bar;
	private TextView downTextView;
	private TextView timeTextView;

	private RefreshListener refreshListener;

	private String downTextString;
	private String releaseTextString;

	private Long refreshTime = null;
	private int lastX;
	private int lastY;


	// 在刷新中标记
	private boolean isRefreshing = false;
	
	
	private Context mContext;
	public RefreshableView(Context context) {
		super(context);
		mContext = context;
		
	}
	public RefreshableView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		init();
		
	}
	private void init() {
		// TODO Auto-generated method stub
		//滑动对象,
		scroller = new Scroller(mContext);
		
		//刷新视图顶端的的view
		 refreshView = LayoutInflater.from(mContext).inflate(R.layout.refresh_top_item, null);
		//指示器view
		 refreshIndicatorView = (ImageView) refreshView.findViewById(R.id.indicator);
		//刷新bar
		bar = (ProgressBar) refreshView.findViewById(R.id.progress);
		//下拉显示text
		 downTextView = (TextView) refreshView.findViewById(R.id.refresh_hint);
		//下来显示时间
		 timeTextView = (TextView) refreshView.findViewById(R.id.refresh_time);
		
		LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0);
//		lp.topMargin = refreshTargetTop;
		lp.gravity = Gravity.CENTER;
		addView(refreshView, lp);
		downTextString = mContext.getResources().getString(R.string.refresh_down_text);
		releaseTextString = mContext.getResources().getString(R.string.refresh_release_text);	
	}




	/**
	 * 刷新
	 * @param time
	 */
	private void setRefreshText(String time) {
		// TODO Auto-generated method stub
		//timeTextView.setText(time);
	}


	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		int y= (int) event.getRawY();
		
		
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			break;

		case MotionEvent.ACTION_MOVE:
			Log.i(TAG, "ACTION_MOVE");
			//y移动坐标
			int m = y - lastY;
//			if(((m < 6) && (m > -1)) || (!enterScrollState )){
				 doMovement(m);
//			}
			//记录下此刻y坐标
			this.lastY = y;
			break;
			
		case MotionEvent.ACTION_UP:
			Log.i(TAG, "ACTION_UP");
			
			fling();
			
			break;
		}
		return true;
	}


	/**
	 * up事件处理
	 */
	private void fling() {
		// TODO Auto-generated method stub
		LinearLayout.LayoutParams lp = (LayoutParams) refreshView.getLayoutParams();
		Log.i(TAG, "fling()" + lp.height);
		if(lp.height > refreshHeight){//拉到了触发可刷新事件
			refresh();	
		}else{
			returnInitState();
		}
	}
	

	
	private void returnInitState() {
		// TODO Auto-generated method stub
		 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)this.refreshView.getLayoutParams();
		 int i = lp.height;
		 scroller.startScroll(0, i, 0, -i);
		 invalidate();
	}
	private void refresh() {
		// TODO Auto-generated method stub
		 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)this.refreshView.getLayoutParams();
		 int i = lp.height;
		 refreshIndicatorView.setVisibility(View.GONE);
		 bar.setVisibility(View.VISIBLE);
		 timeTextView.setVisibility(View.GONE);
		 downTextView.setText("正在刷新......");
		 scroller.startScroll(0, i, 0, refreshHeight-i);
		 invalidate();
		 if(refreshListener !=null){
			 refreshListener.onRefresh(this);
			 isRefreshing = true;
		 }
	}
	
	/**
	 * 
	 */
	@Override
	public void computeScroll() {

		// TODO Auto-generated method stub
		if(scroller.computeScrollOffset()){
			int i = this.scroller.getCurrY();
		      LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)this.refreshView.getLayoutParams();
		      int k = Math.max(i, 0);
		      lp.height = k;
				Log.d(TAG, "执行computeScroll"+lp.height);
		      this.refreshView.setLayoutParams(lp);
		      this.refreshView.invalidate();
		      invalidate();
		}
	}
	/**
	 * 下拉move事件处理
	 * @param moveY
	 */
	private void doMovement(int moveY) {
		// TODO Auto-generated method stub
		Log.d("RefreshableView", "执行doMovement");
		LinearLayout.LayoutParams lp = (LayoutParams) refreshView.getLayoutParams();
		if(lp.height>=0){
			//获取view的高度
			float f1 =lp.height;
			float f2 = moveY * 0.3F;
			int i = (int)(f1+f2);
			//修改高度
			if(i>0){
				lp.height = i;
			}else{
				lp.height = 0;
			}
			Log.d("RefreshableView", lp.height+"");
			//修改后刷新
			refreshView.setLayoutParams(lp);
			refreshView.invalidate();
			invalidate();
		}
//		timeTextView.setVisibility(View.VISIBLE);
		if(refreshTime!= null){
			setRefreshTime(refreshTime);
		}
		if(lp.height>0){
			refreshIndicatorView.setVisibility(View.VISIBLE);
			downTextView.setVisibility(View.VISIBLE);
			bar.setVisibility(View.GONE);
			
			if(lp.height >=  refreshHeight){
				downTextView.setText(R.string.refresh_release_text);
				refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_up);
			}else if(lp.height < refreshHeight ){
				downTextView.setText(R.string.refresh_down_text);
				refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_down);
			}
		}else{
			timeTextView.setVisibility(View.GONE);
			refreshIndicatorView.setVisibility(View.GONE);
			downTextView.setVisibility(View.GONE);
		}
		
	}


	public void setRefreshListener(RefreshListener listener) {
		this.refreshListener = listener;
	}

	/**
	 * 刷新时间
	 * @param refreshTime2
	 */
	private void setRefreshTime(Long time) {
		// TODO Auto-generated method stub
		
	}

	/**
	 * 结束刷新事件
	 */
	public void finishRefresh(){
		Log.i(TAG, "执行了=====finishRefresh");
		 LinearLayout.LayoutParams lp= (LinearLayout.LayoutParams)this.refreshView.getLayoutParams();
		    int i = lp.height;
		    refreshIndicatorView.setVisibility(View.GONE);
		    bar.setVisibility(View.GONE);
		    downTextView.setVisibility(View.GONE);
//		    timeTextView.setVisibility(View.VISIBLE);
		    scroller.startScroll(0, i, 0, -i);
		    invalidate();
		    isRefreshing = false;  
	}

	
	/*该方法一般和ontouchEvent 一起用
	 * (non-Javadoc)
	 * @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent e) {
		// TODO Auto-generated method stub
		int action = e.getAction();
		int y= (int) e.getRawY();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			lastY = y;
			Log.d("onInterceptTouchEvent", "lastY:"+lastY);
			break;

		case MotionEvent.ACTION_MOVE:

			//y移动坐标
			int m = y - lastY;
			Log.d("onInterceptTouchEvent", "ACTION_MOVE:"+m);
			 //记录下此刻y坐标  
//            this.lastY = y;  
             if(m > 6 &&  canScroll()){  
                return true;  
            }  
			break;
		case MotionEvent.ACTION_UP:
			
			break;
			
	case MotionEvent.ACTION_CANCEL:
			
			break;
		}
		return false;
	}
	private boolean canScroll() {
		// TODO Auto-generated method stub
		View childView;
		if(getChildCount()>1){
			childView = this.getChildAt(1);
			if(childView instanceof ListView){
				int top =((ListView)childView).getChildAt(0).getTop(); 
				int pad =((ListView)childView).getListPaddingTop(); 
				if((Math.abs(top-pad)) < 3&&
						((ListView) childView).getFirstVisiblePosition() == 0){
					return true;
				}else{
					return false;
				}
			}else if(childView instanceof GridView){
				int top =((GridView)childView).getChildAt(0).getTop(); 
				int pad =((GridView)childView).getListPaddingTop(); 
				if((Math.abs(top-pad)) < 3&&
						((GridView) childView).getFirstVisiblePosition() == 0){
					return true;
				}else{
					return false;
				}
			}else if(childView instanceof ScrollView){
				if(((ScrollView)childView).getScrollY() == 0){
					return true;
				}else{
					return false;
				}
			}
			
		}
		return false;
	}
	/**
	 * 刷新监听接口
	 * @author Nono
	 *
	 */
	public interface RefreshListener{
		public void onRefresh(RefreshableView view);
	}
}


 refresh_top_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:gravity="center"
    android:layout_gravity="center"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <ImageView 
        android:id="@+id/indicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <ProgressBar 
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
      />
	<TextView 
	    android:id="@+id/refresh_hint"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    />
	<TextView 
	    android:id="@+id/refresh_time"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    />
</LinearLayout>

 

测试代码:testActivity.java

package com.qige.test;

import javax.security.auth.PrivateCredentialPermission;

import com.qige.test.RefreshableView.RefreshListener;
import com.qige.test.SharedPreferencesHelper;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

public class TestActivity extends Activity{
/** Called when the activity is first created. */
public static final String szSPName="com.kingsense.emenu.ui_preferences";	//sp名称
public static SharedPreferencesHelper sp=null;
Dialog initDataDialog;
private ListView dataList;
//private GridView dataGrid;
private BaseAdapter dataAdapter;
private String[] goods = {"商品一","商品二","商品三","商品四","商品午","商品六","商品七","商品一","商品二","商品三","商品四","商品午","商品六","商品七"};
private RefreshableView refreshableView;
//private String TAG = "slipMenu"; 


@Override
public void onCreate(Bundle savedInstanceState) {
	
  super.onCreate(savedInstanceState);
  	setContentView(R.layout.main);
  	dataList = (ListView)findViewById(R.id.data_list);
//  	dataGrid = (GridView) findViewById(R.id.data_grid);
  	refreshableView = (RefreshableView) findViewById(R.id.refresh_widget);
  	refreshableView.setRefreshListener(new RefreshListener() {
		
		@Override
		public void onRefresh(RefreshableView view) {
			// TODO Auto-generated method stub
			new AsyncTask<Object, Object, Object>(){
				@Override
				protected Object doInBackground(Object... params) {
					// TODO Auto-generated method stub
					try {
						Thread.sleep(5*1000);
					} catch (Exception e) {
						// TODO: handle exception
					}
					return true;
				}

				@Override
				protected void onPostExecute(Object result) {
					// TODO Auto-generated method stub
					super.onPostExecute(result);
					refreshableView.finishRefresh();
				}

				@Override
				protected void onPreExecute() {
					// TODO Auto-generated method stub
					super.onPreExecute();
					
				}
			}.execute();
		}
	});
  	dataAdapter = new BaseAdapter() {
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			TextView goodsView = new TextView(TestActivity.this);
			goodsView.setText(goods[position]);
			goodsView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT,80));
			goodsView.setTextColor(getResources().getColor(R.color.text_color_white));
			goodsView.setBackgroundColor(getResources().getColor(R.color.text_color_price));
			return goodsView;
		}
		
		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}
		
		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return position;
		}
		
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return goods.length;
		}
	};
	dataList.setAdapter(dataAdapter);
//	dataGrid.setAdapter(dataAdapter);
	dataAdapter.notifyDataSetChanged();
	
  }
  
}


main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout   
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"    
    android:layout_width="match_parent"  
    android:layout_height="match_parent"
    android:background="#fff"> 
    <TextView android:layout_width="fill_parent"
        android:layout_height="48dp"
        android:text="菜品数据刷新"
        android:gravity="center_horizontal"/>
	 <com.qige.test.RefreshableView
	     android:id="@+id/refresh_widget"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
         android:background="#ccc" 
         android:orientation="vertical"
        >
 	<ListView 
	    android:id="@+id/data_list"
	    android:layout_width="fill_parent" 
	    android:scrollbars="none"  
	    android:fadingEdge="none"  
   		android:layout_height="wrap_content" 
  	   android:scrollingCache="false"   
	    android:background="#ccc">
	</ListView> 
<!-- 	<GridView 
	     android:id="@+id/data_grid"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:numColumns="3"> 
	    
	</GridView>
	-->
	</com.qige.test.RefreshableView>
</LinearLayout>


 

string.xml:

    <string name="refresh_down_text">下拉刷新</string>
    <string name="refresh_release_text">送开可刷新</string>


 


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值