Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android listview的下拉刷新

Android listview的下拉刷新

編輯:關於Android編程

 

好久沒有寫博客了,今天我就寫一個listview的下拉刷新分享給大家,希望對大家學習或者工作上有所幫助,其實呢,大家都知道,在現在的app當中,下拉刷新是比較常用的功能,用到的地方太多了,所以,今天我也就結合自己的思想給家真理一下,那麼好,接下來,讓我們一起學習,讓你分分鐘寫出自己想要的自定義listview下拉刷新

 

 

一:實現思路

1.實現將listview添加頭部view,也就是下拉要出現是頭部布局

2.將頭部的view給隱藏(這點需要特別注意)

3.給listview設置滑動監聽(用於判斷是否到頭部)

4.設置手勢事件,手指移動的時候的所做的操作

 

二:源碼實例

1.自定義控件

package com.zengtao.refreshview;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
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.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.zengtao.pulltorefreshtest.R;

/**
 * 下拉刷新listview
 * 
 * @author zengtao 2015年3月17日 下午7:13:55
 */
public class RefreshableView extends ListView implements OnScrollListener {

	/** 下拉刷新的頭部 */
	private View headerView;

	/** 頭部的箭頭 */
	private ImageView arrawImage;

	/** 更新刷新之後的時間 */
	private TextView lastUpdatTime;

	/** 刷新的一個狀態 */
	private TextView stateMessage;

	/** 加載進度 */
	private ProgressBar progressBar;

	/** 獲取頭部文件的高度 */
	private int headerHeight;

	/** 當前第一個可見的位置 */
	private int firstVisibleItem;

	/** 標記當前是否能刷新 */
	private boolean isReflash;

	/** 按下的y值 */
	private int startY;

	/** 下拉的狀態 */
	private int state;

	/** 正常狀態 */
	private final int NONE = 0;

	/** 提示下拉刷新狀態 */
	private final int PULL = 1;

	/** 提示釋放刷新狀態 */
	private final int REFPULL = 2;

	/** 提示正在刷新 */
	private final int LOADING = 3;

	/** ListView 當前滾動位置 */
	private int scorellStatep;

	/** 數據回調接口 */
	private IReflashLinster iReflashLinster;

	public RefreshableView(Context context) {
		super(context);
		initView(context);
	}

	public RefreshableView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initView(context);
	}

	public RefreshableView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	/**
	 * 作用:初始化下拉刷新的頭部
	 * 
	 * @param context
	 *            :上下文
	 */
	@SuppressLint("InflateParams")
	private void initView(Context context) {
		headerView = LayoutInflater.from(context).inflate(
				R.layout.pull_to_refresh, null);
		// 初始化試圖
		arrawImage = (ImageView) headerView.findViewById(R.id.iv_arrow);
		stateMessage = (TextView) headerView.findViewById(R.id.pull_state);
		lastUpdatTime = (TextView) headerView.findViewById(R.id.lastupdatetime);
		progressBar = (ProgressBar) headerView.findViewById(R.id.progress_bar);

		// 通知父布局,才能取到多高,否則為0
		measureView(headerView);
		headerHeight = headerView.getMeasuredHeight();
		topPadding(-headerHeight);
		this.addHeaderView(headerView);
		this.setOnScrollListener(this);
	}

	/**
	 * 通知父布局我該占取多少的height 和 width
	 * 
	 * @param view
	 *            :試圖布局
	 */
	private void measureView(View view) {
		ViewGroup.LayoutParams p = view.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
		int tempHeight = p.height;
		int height;
		if (tempHeight > 0) {
			height = MeasureSpec.makeMeasureSpec(tempHeight,
					MeasureSpec.EXACTLY);
		} else {
			height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
		}
		view.measure(width, height);
	}

	/**
	 * 設置header布局的上邊距
	 * 
	 * @param topHeight
	 *            : 上邊距高度
	 */
	private void topPadding(int topPadding) {
		headerView.setPadding(headerView.getPaddingLeft(), topPadding,
				headerView.getPaddingRight(), headerView.getPaddingBottom());
		headerView.invalidate();
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		this.scorellStatep = scrollState;
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		this.firstVisibleItem = firstVisibleItem;
	}

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// listview 已經滑到頭部
			if (firstVisibleItem == 0) {
				isReflash = true;
				startY = (int) ev.getY();
			}
			break;
		case MotionEvent.ACTION_MOVE:
			// 移動的時候所做的操作
			onMove(ev);
			break;
		case MotionEvent.ACTION_UP:
			// 松開的時候看是處於什麼狀態
			if (state == REFPULL) {
				state = LOADING; // 可以加載數據了
				reflashViewBySate();
				reflashComplete();
				iReflashLinster.reflash();
			} else if (state == PULL) {
				state = NONE;
				isReflash = false;
				reflashViewBySate();
			}
			break;
		}
		return super.onTouchEvent(ev);
	}

	/**
	 * 手指移動的時候的所做的操作
	 * 
	 * @param ev
	 */
	private void onMove(MotionEvent ev) {
		// 是不是能刷新
		if (!isReflash) {
			return;
		}
		// 當前移動的位置
		int tempY = (int) ev.getY();
		int spance = tempY - startY;
		// 頂部布局是一點一點的顯示出來,所以要不停的設置頂部布局
		int topPadding = spance - headerHeight;
		
		switch (state) {
		case NONE:
			// 當用戶更下拉的時候狀態:提示下拉狀態
			if (spance > 0) {
				state = PULL;
			}
			break;
		case PULL:
			topPadding(topPadding);
			// 用戶下拉超過一定並且處於滑動滾動的的時候:提示松開刷新狀態
			if (spance > headerHeight + 20
					&& scorellStatep == SCROLL_STATE_TOUCH_SCROLL) {
				state = REFPULL;
				reflashViewBySate();
			}
			break;
		case REFPULL:
			topPadding(topPadding);
			// 當用戶回滾到低於一定高度的時候:提示下拉刷新狀態
			if (spance < headerHeight + 20) {
				state = PULL;
				reflashViewBySate();
			} else if (spance <= 0) {
				state = NONE;
				isReflash = false;
				reflashViewBySate();
			}
		}
	}

	/**
	 * 根據狀態:在去決定是否刷新數據和加載布局
	 */
	private void reflashViewBySate() {

		// 動畫效果
		RotateAnimation animation = new RotateAnimation(0, 180,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		animation.setDuration(500);
		animation.setFillAfter(true);

		// 動畫效果
		RotateAnimation animation1 = new RotateAnimation(180, 0,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		animation1.setDuration(500);
		animation1.setFillAfter(true);

		switch (state) {
		case NONE:
			topPadding(-headerHeight);
			arrawImage.clearAnimation();
			
			break;
		case PULL:
			arrawImage.setVisibility(View.VISIBLE);
			progressBar.setVisibility(View.GONE);

			stateMessage.setText("下拉可以刷新");
			arrawImage.clearAnimation();
			arrawImage.setAnimation(animation1);
			break;
		case REFPULL:
			arrawImage.setVisibility(View.VISIBLE);
			progressBar.setVisibility(View.GONE);

			stateMessage.setText("松開可以刷新");
			arrawImage.clearAnimation();
			arrawImage.setAnimation(animation);
			break;
		case LOADING:
			topPadding(50);
			progressBar.setVisibility(View.VISIBLE);
			arrawImage.setVisibility(View.GONE);

			stateMessage.setText("正在刷新...");
			arrawImage.clearAnimation();
			break;
		}
	}

	/**
	 * 刷新完成之後,更改刷新時間
	 */
	@SuppressLint("SimpleDateFormat")
	public void reflashComplete() {
		state = NONE;
		isReflash = false;
		reflashViewBySate();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
		Date date = new Date(System.currentTimeMillis());
		String time = sdf.format(date);
		lastUpdatTime.setText(time);
	}

	public interface IReflashLinster {	
		public void reflash();
	}

	public void setIReflashLinster(IReflashLinster iReflashLinster) {
		this.iReflashLinster = iReflashLinster;
	}

 

2.Maintivity 在主界面中的使用

 

package com.zengtao.pulltorefreshtest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Window;
import android.widget.ArrayAdapter;

import com.zengtao.refreshview.RefreshableView;
import com.zengtao.refreshview.RefreshableView.IReflashLinster;

public class MainActivity extends Activity implements IReflashLinster {
	private RefreshableView listView;
	private ArrayAdapter Adapter;
	private String[] str = { "傻逼才是王道 1", "傻逼才是王道  2", "text 3", "傻逼才是王道 4", "傻逼才是王道 5",
			"傻逼才是王道 6", "傻逼才是王道 7", "傻逼才是王道 8", "傻逼才是王道 9", "傻逼才是王道 10", "傻逼才是王道 11",
			"傻逼才是王道 12", "傻逼才是王道 13", "傻逼才是王道 14", "傻逼才是王道 1", "傻逼才是王道 2", "傻逼才是王道 3",
			"傻逼才是王道 4", "傻逼才是王道 5", "傻逼才是王道 6", "傻逼才是王道 7", "傻逼才是王道 8", "傻逼才是王道 9",
			"傻逼才是王道 10", "傻逼才是王道 11", "傻逼才是王道 12", "傻逼才是王道 13", "傻逼才是王道 14" };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		initView();
	}

	private void initView() {
		listView = (RefreshableView) findViewById(R.id.listview);
		listView.setIReflashLinster(this);
		Adapter = new ArrayAdapter(this,
				android.R.layout.simple_list_item_1, str);
		listView.setAdapter(Adapter);
	}

	@Override
	public void reflash() {
		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {

			@Override
			public void run() {
				
			}
		}, 3000);
	}
}

以上變可完成一個自定義的listview的自定義和使用,希望對大家有所幫助,我寫的不好,大家請勿怪。

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved