赵雅智_名片夹(3)_下拉刷新加载更多

转载请标明地址:http://blog.csdn.net/zhaoyazhi2129/article/details/38751681

效果图


新建刷新的头部布局

<?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;
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值