效果图


赵雅智_名片夹(3)_下拉刷新载入很多其它_ide赵雅智_名片夹(3)_下拉刷新载入很多其它_回滚_02


新建刷新的头部布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="bottom"

>

<RelativeLayout
android:id="@+id/listview_header_content"
android:layout_width="fill_parent"
android:layout_height="60dp"
>

<LinearLayout
android:id="@+id/listview_header_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical" >

<TextView
android:id="@+id/listview_header_hint_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/listview_header_hint_normal"
android:textColor="@color/tvcolor"/>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/listview_header_last_time"
android:textSize="12sp"
android:textColor="@color/tvcolor"/>

<TextView
android:id="@+id/listview_header_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="@color/tvcolor" />
</LinearLayout>
</LinearLayout>
<ImageView
android:id="@+id/listview_header_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/listview_header_text"
android:layout_centerVertical="true"
android:layout_marginLeft="-35dp"
android:src="@drawable/listview_arrow" />

<ProgressBar
android:id="@+id/listview_header_progressbar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignLeft="@id/listview_header_text"
android:layout_centerVertical="true"
android:layout_marginLeft="-40dp"
android:visibility="invisible" />
</RelativeLayout>

</LinearLayout>



在工具包下自己定义头部信息

PullListViewHeader.java

package com.cards.basic.util;

import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.cards.R;

/**
*
* @explaination 下拉载入很多其它
* @author yazhizhao
* @time 2014-8-1上午11:30:35
*/
public class PullListViewHeader extends LinearLayout {
private LinearLayout mContainer;
private ImageView mArrowImageView;
private ProgressBar mProgressBar;
private TextView mHintTextView;
private int mState = STATE_NORMAL;
private Animation mRotateUpAnim;
private Animation mRotateDownAnim;

private final int ROTATE_ANIM_DURATION = 180;

public final static int STATE_NORMAL = 0;
public final static int STATE_READY = 1;
public final static int STATE_REFRESHING = 2;

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

/**
* @param context
* @param attrs
*/
public PullListViewHeader(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}

private void initView(Context context) {
// 初始情况,设置下拉刷新view高度为0
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, 0);
mContainer = (LinearLayout) LayoutInflater.from(context).inflate(
R.layout.listview_header, null);
addView(mContainer, lp);
setGravity(Gravity.BOTTOM);

mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow);
mHintTextView = (TextView)findViewById(R.id.listview_header_hint_textview);
mProgressBar = (ProgressBar)findViewById(R.id.listview_header_progressbar);

mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateUpAnim.setFillAfter(true);
mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateDownAnim.setFillAfter(true);
}

public void setState(int state) {
if (state == mState) return ;

if (state == STATE_REFRESHING) { // 显示运行进度
mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
} else { // 显示箭头图片
mArrowImageView.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
}

switch(state){
case STATE_NORMAL:
if (mState == STATE_READY) {
mArrowImageView.startAnimation(mRotateDownAnim);
}
if (mState == STATE_REFRESHING) {
mArrowImageView.clearAnimation();
}
mHintTextView.setText(R.string.listview_header_hint_normal);
break;
case STATE_READY:
if (mState != STATE_READY) {
mArrowImageView.clearAnimation();
mArrowImageView.startAnimation(mRotateUpAnim);
mHintTextView.setText(R.string.listview_header_hint_ready);
}
break;
case STATE_REFRESHING:
mHintTextView.setText(R.string.listview_header_hint_loading);
break;
default:
}

mState = state;
}

public void setVisiableHeight(int height) {
if (height < 0)
height = 0;
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContainer
.getLayoutParams();
lp.height = height;
mContainer.setLayoutParams(lp);
}

public int getVisiableHeight() {
return mContainer.getHeight();
}

}


在工具包下创建listview的自己定义文件


PullListView.java

package com.cards.basic.util;


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;

import com.cards.R;
/**
*
* @explaination 下拉载入很多其它
* @author yazhizhao
* @time 2014-8-1上午11:30:45
*/
public class PullListView extends ListView implements OnScrollListener {

private float mLastY = -1; // y
private Scroller mScroller; // 用于回滚
private OnScrollListener mScrollListener; // 回滚监听
// 接口触发刷新和负载很多其它
private IXListViewListener mListViewListener;
//
private PullListViewHeader mHeaderView;
// 整个头部布局
private RelativeLayout mHeaderViewContent;
// 上次刷新的时间布局
private TextView mHeaderTimeView;
// 头部的高度
private int mHeaderViewHeight;
private boolean mEnablePullRefresh = true;
// 是否刷新
private boolean mPullRefreshing = false;

// 总共的条数
private int mTotalItemCount;

// 对于照片卷轴,卷轴回来页眉或页脚。
private int mScrollBack;
private final static int SCROLLBACK_HEADER = 0;

private final static int SCROLL_DURATION = 400; // scroll back duration

private final static float OFFSET_RADIO = 1.8f; // support iOS like pull
// feature.

/**
* @param context
*/
public PullListView(Context context) {
super(context);
initWithContext(context);
}

public PullListView(Context context, AttributeSet attrs) {
super(context, attrs);
initWithContext(context);
}

public PullListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initWithContext(context);
}

// ListView须要滚动事件,它将调度事件,用户的侦听器(作为一个代理
private void initWithContext(Context context) {
mScroller = new Scroller(context, new DecelerateInterpolator());
super.setOnScrollListener(this);
// 初始化控件
mHeaderView = new PullListViewHeader(context);
mHeaderViewContent = (RelativeLayout) mHeaderView
.findViewById(R.id.listview_header_content);
mHeaderTimeView = (TextView) mHeaderView
.findViewById(R.id.listview_header_time);
addHeaderView(mHeaderView);

// 初始化头部信息
mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mHeaderViewHeight = mHeaderViewContent.getHeight();
getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
});
}

/**
* 启用或禁用拉刷新功能
*
* @param enable
*/
public void setPullRefreshEnable(boolean enable) {
// 是否刷新
mEnablePullRefresh = enable;
// 假设不是刷新
if (!mEnablePullRefresh) {
mHeaderViewContent.setVisibility(View.INVISIBLE);
} else {
// 假设是刷新
mHeaderViewContent.setVisibility(View.VISIBLE);
}
}

/**
* 停止刷新,复位标题视图
*/
public void stopRefresh() {
if (mPullRefreshing == true) {
mPullRefreshing = false;
resetHeaderHeight();
}
}

/**
* 设置最后刷新时间
*
* @param time
*/
public void setRefreshTime(String time) {
mHeaderTimeView.setText(time);
}

private void invokeOnScrolling() {
if (mScrollListener instanceof OnXScrollListener) {
OnXScrollListener l = (OnXScrollListener) mScrollListener;
l.onXScrolling(this);
}
}

private void updateHeaderHeight(float delta) {
mHeaderView.setVisiableHeight((int) delta
+ mHeaderView.getVisiableHeight());
if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头
if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {
mHeaderView.setState(PullListViewHeader.STATE_READY);
} else {
mHeaderView.setState(PullListViewHeader.STATE_NORMAL);
}
}
setSelection(0); // 滚动到顶部每一个时间
}

/**
* 重置头的高度
*/
private void resetHeaderHeight() {
int height = mHeaderView.getVisiableHeight();
if (height == 0) // 不显示
return;
// 刷新而且头部不全然显示,而且什么也不做
if (mPullRefreshing && height <= mHeaderViewHeight) {
return;
}
int finalHeight = 0; // 默认值:滚动回驳回头.
// 刷新。回滚显示全部的头部信息
if (mPullRefreshing && height > mHeaderViewHeight) {
finalHeight = mHeaderViewHeight;
}
mScrollBack = SCROLLBACK_HEADER;
mScroller.startScroll(0, height, 0, finalHeight - height,
SCROLL_DURATION);
invalidate();
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mLastY == -1) {
mLastY = ev.getRawY();
}

switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastY = ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
final float deltaY = ev.getRawY() - mLastY;
mLastY = ev.getRawY();
if (getFirstVisiblePosition() == 0
&& (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {
// 第一项是显示,标题显示或拉下来
updateHeaderHeight(deltaY / OFFSET_RADIO);
invokeOnScrolling();
}
break;
default:
mLastY = -1; // 重置
if (getFirstVisiblePosition() == 0) {
// 调用刷新
if (mEnablePullRefresh
&& mHeaderView.getVisiableHeight() > mHeaderViewHeight) {
mPullRefreshing = true;
mHeaderView.setState(PullListViewHeader.STATE_REFRESHING);
if (mListViewListener != null) {
mListViewListener.onRefresh();
}
}
resetHeaderHeight();
}
break;
}
return super.onTouchEvent(ev);
}

@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
if (mScrollBack == SCROLLBACK_HEADER) {
mHeaderView.setVisiableHeight(mScroller.getCurrY());
}
postInvalidate();
invokeOnScrolling();
}
super.computeScroll();
}

@Override
public void setOnScrollListener(OnScrollListener l) {
mScrollListener = l;
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mScrollListener != null) {
mScrollListener.onScrollStateChanged(view, scrollState);
}
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// 发送到用户的侦听器
mTotalItemCount = totalItemCount;
if (mScrollListener != null) {
mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,
totalItemCount);
}
}

public void setXListViewListener(IXListViewListener l) {
mListViewListener = l;
}

/**
* 你能够听列表视图。OnScrollListener或这一个。它将调用onXScrolling当标题/页脚滚动回。

*/
public interface OnXScrollListener extends OnScrollListener {
public void onXScrolling(View view);
}

/**
* 实现这个接口获取/负载很多其它的事件,刷新
*/
public interface IXListViewListener {
public void onRefresh();

public void onLoadMore();
}
}


在布局文件里使用自己定义的PullListView文件

<com.cards.basic.util.PullListView
android:id="@+id/lv_changelist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/titlebar_above"
android:layout_margin="10dp"
android:cacheColorHint="#00000000"
android:divider="#00000000"
android:fadingEdge="none"
android:listSelector="#00000000" >
</com.cards.basic.util.PullListView>


在相应的activity类实现IXListViewListener接口,并继承onRefresh和onLoadMore方法

package com.cards.activity;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.cards.R;
import com.cards.adapter.ChangeCardAdapter;
import com.cards.basic.util.PullListView;
import com.cards.basic.util.PullListView.IXListViewListener;
import com.cards.commom.Common;
import com.cards.commom.MyApp;
import com.cards.entity.Findf;
import com.cards.manager.ChangeMgr;

/**
* @explaination 交换名片
* @author yazhizhao
* @time 2014-7-8上午9:30:59
*/
public class ChangeCardAct extends Activity implements IXListViewListener {

private ChangeCardAdapter adapter;
private Handler mHandler;
private PullListView pointList;
private List<Findf> list;
private ChangeMgr changeMgr;
private Button btnRegistered;
private MessageThread messageThread;
private SharedPreferences sp;
private int size;
private ImageView imageView1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_change_card);
// 用于安全退出
MyApp.getInstance().addActivity(this);

// 设置标题
TextView tvTitleCommenCenter = (TextView) findViewById(R.id.tv_title);
tvTitleCommenCenter.setText("发现");

// 查看交换请求
btnRegistered = (Button) findViewById(R.id.btn_right_title);
btnRegistered.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
startActivity(new Intent().setClass(ChangeCardAct.this, ChangeReqAct.class));
}
});


// 开启线程
messageThread = new MessageThread();
messageThread.start();
// 获取附近人
changeMgr = new ChangeMgr(ChangeCardAct.this, handler);
changeMgr.findF();
mHandler = new Handler();
//是否收到交换信息
changeHint();
}

/**
*
* @explaination 是否收到交换信息
* @author yazhizhao
* @time 2014-8-22上午10:19:39
*/
private void changeHint() {
sp = getSharedPreferences("common_data", MODE_PRIVATE);
size = sp.getInt("Status_size", 0);
imageView1 = (ImageView) findViewById(R.id.imageView1);
if (size > 0) {
imageView1.setVisibility(View.VISIBLE);
} else if (size == 0) {
imageView1.setVisibility(View.GONE);
}
}

/**
*
* @explaination 新开启线程一直请求有没有人交换
* @author yazhizhao
* @time 2014-7-25下午5:20:36
*/
class MessageThread extends Thread {
public void run() {
while (true) {
try {
// 请求有没有人交换
changeMgr.friendInfo();
//是否收到交换信息
changeHint();
Thread.sleep(1000 * 6);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

/**
* 消息处理机制
*/
private Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {

Common.cancelLoading();
switch (msg.what) {
case 0:
Bundle bundle = msg.getData();
ArrayList arraylist = bundle.getParcelableArrayList("list");
list = (List<Findf>) arraylist.get(0);
pointList = (PullListView) findViewById(R.id.lv_changelist);
adapter = new ChangeCardAdapter(ChangeCardAct.this, list,
handler);
pointList.setAdapter(adapter);
pointList.setXListViewListener(ChangeCardAct.this);
break;

case 2:
pointList = (PullListView) findViewById(R.id.lv_changelist);
list = new ArrayList<Findf>();
adapter = new ChangeCardAdapter(ChangeCardAct.this, list,
handler);
pointList.setAdapter(adapter);
pointList.setXListViewListener(ChangeCardAct.this);
break;

}

}
};

@Override
protected void onStart() {
// 用于安全退出
MyApp.getInstance().addActivity(this);
super.onStart();
}

/**
*
* @explaination 下拉刷新设置上次时间
* @author yazhizhao
* @time 2014-7-28上午11:10:51
* @return
*/
private String getCurrentDate() {
SimpleDateFormat sdf = new java.text.SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String str = sdf.format(new java.util.Date());
return str;
}

/**
*
* @explaination 下拉刷新
* @author yazhizhao
* @time 2014-7-28上午11:10:51
*/
@Override
public void onRefresh() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
onReload();
changeHint();
onLoad();
}
}, 2000);

}
/**
*
* @explaination 载入很多其它
* @author yazhizhao
* @time 2014-7-28上午11:10:51
*/
@Override
public void onLoadMore() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {

}
}, 2000);
}

@Override
protected void onResume() {
// 把定位状态设置为第一次定位
changeMgr.findF();
changeHint();
super.onResume();
}

/**
*
* @explaination 停止刷新并设置时间
* @author yazhizhao
* @time 2014-8-22上午10:23:47
*/
private void onLoad() {
pointList.stopRefresh();
pointList.setRefreshTime(getCurrentDate());
}
/**
*
* @explaination 再次刷新
* @author yazhizhao
* @time 2014-8-22上午10:23:50
*/
public boolean onReload() {
boolean result = true;
changeMgr.findF();
return result;
}
}