Android自定义控件开发实战之实现ListView下拉刷新实例代码

Android自定义控件开发实战之实现ListView下拉刷新实例代码,第1张

概述这篇博客为大家介绍一个android常见的功能――ListView下拉刷新:首先下拉未松手时候手机显示这样的界面:

这篇博客为大家介绍一个androID常见的功能――ListVIEw下拉刷新:

首先下拉未松手时候手机显示这样的界面:


下面的代码是自定的扎样的控件:

<span >package com.dhsr.smartID.vIEw;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.example.sirelinkscanapp.R;/*** 自定义控件,完成下拉时候ListVIEw显示“图标及提示正在刷新……”的布局* * @author cyf* */public class XListVIEwheader 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 XListVIEwheader(Context context) {super(context);initVIEw(context);}/*** @param context* @param attrs*/public XListVIEwheader(Context context,AttributeSet attrs) {super(context,attrs);initVIEw(context);}/*** “ 松开即可刷新……正在刷新……”的布局* * @param context*/private voID initVIEw(Context context) {// 初始情况,设置下拉刷新vIEw高度为0linearLayout.LayoutParams lp = new linearLayout.LayoutParams(LayoutParams.MATCH_PARENT,0);mContainer = (linearLayout) LayoutInflater.from(context).inflate(R.layout.xListvIEw_header,null);// 加载视图addVIEw(mContainer,lp);// 居中方式setGravity(Gravity.BottOM);// 初始化控件mArrowImageVIEw = (ImageVIEw) findVIEwByID(R.ID.xListvIEw_header_arrow);mHintTextVIEw = (TextVIEw) findVIEwByID(R.ID.xListvIEw_header_hint_textvIEw);mProgressbar = (Progressbar) findVIEwByID(R.ID.xListvIEw_header_progressbar);// 设置动画mRotateUpAnim = new RotateAnimation(0.0f,-180.0f,Animation.relative_TO_SELF,0.5f,0.5f);mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);mRotateUpAnim.setFillAfter(true);mRotateDownAnim = new RotateAnimation(-180.0f,0.0f,0.5f);mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);mRotateDownAnim.setFillAfter(true);}/*** 根据下拉状态执行相应的功能,开始以及停止相应的动画* * @param state*/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.xListvIEw_header_hint_normal);break;case STATE_READY:if (mState != STATE_READY) {mArrowImageVIEw.clearanimation();mArrowImageVIEw.startAnimation(mRotateUpAnim);mHintTextVIEw.setText(R.string.xListvIEw_header_hint_ready);}break;case STATE_REFRESHING:mHintTextVIEw.setText(R.string.xListvIEw_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();}}</span> 

接下来需要自定义自己的ListVIEw继承与androID本身的ListVIEw,方便自己添加新的方法。

<span >package com.dhsr.smartID.vIEw;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.listadapter;import androID.Widget.ListVIEw;import androID.Widget.relativeLayout;import androID.Widget.Scroller;import androID.Widget.TextVIEw;import com.example.sirelinkscanapp.R;/*** 自定义ListVIEw* * @author cyf* */public class XListVIEw extends ListVIEw implements OnScrollListener {private final String TAG = "XListVIEw";private float mLastY = -1;private Scroller mScroller;// 滑动private OnScrollListener mScrollListener;// 为外界创建监听private IXListVIEwListener mListVIEwListener;// 刚才定义的自定义控件private XListVIEwheader mheaderVIEw;private relativeLayout mheaderVIEwContent;private TextVIEw mheaderTimeVIEw;private int mheaderVIEwHeight; // header vIEw's heightprivate boolean mEnablePullRefresh = true;private boolean mpullRefreshing = false; // is refreashing.private boolean mEnablePullLoad;private boolean mpullLoading;private boolean mIsFooterReady = false;// total List items,used to detect is at the bottom of ListvIEw.private int mTotalitemCount;// for mScroller,scroll back from header or footer.private int mScrollBack;private final static int SCRolLBACK_header = 0;private final static int SCRolLBACK_FOOTER = 1;private final static int SCRolL_DURATION = 400; // scroll back durationprivate final static int PulL_LOAD_MORE_DELTA = 50; // when pull up >= 50px// at bottom,trigger// load more.private final static float OFFSET_RAdio = 1.8f; // support iOS like pull// feature./*** @param context*/public XListVIEw(Context context) {super(context);initWithContext(context);}public XListVIEw(Context context,attrs);initWithContext(context);}public XListVIEw(Context context,AttributeSet attrs,int defStyle) {super(context,attrs,defStyle);initWithContext(context);}/*** 初始化控件* * @param context*/private voID initWithContext(Context context) {mScroller = new Scroller(context,new DecelerateInterpolator());super.setonScrollListener(this);mheaderVIEw = new XListVIEwheader(context);mheaderVIEwContent = (relativeLayout) mheaderVIEw.findVIEwByID(R.ID.xListvIEw_header_content);mheaderTimeVIEw = (TextVIEw) mheaderVIEw.findVIEwByID(R.ID.xListvIEw_header_time);addheaderVIEw(mheaderVIEw,null,false);mheaderVIEw.getVIEwTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@OverrIDepublic voID onGlobalLayout() {mheaderVIEwHeight = mheaderVIEwContent.getHeight();getVIEwTreeObserver().removeGlobalOnLayoutListener(this);}});}@OverrIDepublic voID setAdapter(listadapter adapter) {// make sure XListVIEwFooter is the last footer vIEw,and only add once.if (mIsFooterReady == false) {if (mEnablePullLoad) {mIsFooterReady = true;// addFooterVIEw(mFooterVIEw);}}super.setAdapter(adapter);}public voID setPullRefreshEnable(boolean enable) {mEnablePullRefresh = enable;if (!mEnablePullRefresh) { // disable,hIDe the contentmheaderVIEwContent.setVisibility(VIEw.INVISIBLE);} else {mheaderVIEwContent.setVisibility(VIEw.VISIBLE);}}/*** 停止刷新*/public voID stopRefresh() {if (mpullRefreshing == true) {mpullRefreshing = false;resetheaderHeight();}}// 可使进入Activity时便执行下拉刷新public voID startRefresh() {if (mpullRefreshing == false) {mpullRefreshing = true;mheaderVIEw.setState(XListVIEwheader.STATE_REFRESHING);mheaderVIEw.setVisiableHeight(90);if (mListVIEwListener != null) {mListVIEwListener.onRefresh();}}}/*** stop load more,reset footer vIEw.*/public voID stopLoadMore() {if (mpullLoading == true) {mpullLoading = false;}}/*** set last refresh time* * @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(XListVIEwheader.STATE_READY);} else {mheaderVIEw.setState(XListVIEwheader.STATE_norMAL);}if (mpullLoading) { // disable,hIDe the contentmheaderVIEwContent.setVisibility(VIEw.INVISIBLE);} else {mheaderVIEwContent.setVisibility(VIEw.VISIBLE);}}setSelection(0); // scroll to top each time}/*** reset header vIEw's height.*/private voID resetheaderHeight() {int height = mheaderVIEw.getVisiableHeight();if (height == 0) // not visible.return;// refreshing and header isn't shown fully. do nothing.if (mpullRefreshing && height <= mheaderVIEwHeight) {return;}int finalHeight = 0; // default: scroll back to dismiss header.// is refreshing,just scroll back to show all the header.if (mpullRefreshing && height > mheaderVIEwHeight) {finalHeight = mheaderVIEwHeight;}mScrollBack = SCRolLBACK_header;mScroller.startScroll(0,height,finalHeight - height,SCRolL_DURATION);// trigger computeScrollinvalIDate();}/*** 触屏监听*/@OverrIDepublic 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;// DLog.i(TAG,"deltaY is " + deltaY);mLastY = ev.getRawY();if (getFirstVisibleposition() == 0&& (mheaderVIEw.getVisiableHeight() > 0 || deltaY > 0)) {// the first item is showing,header has shown or pull down.updateheaderHeight(deltaY / OFFSET_RAdio);invokeOnScrolling();} else if (getLastVisibleposition() == mTotalitemCount - 1) {// last item,already pulled up or want to pull up.}break;default:mLastY = -1; // resetif (getFirstVisibleposition() == 0) {// invoke refreshif (!mpullRefreshing && mEnablePullRefresh && !mpullLoading&& mheaderVIEw.getVisiableHeight() > mheaderVIEwHeight) {mpullRefreshing = true;mheaderVIEw.setState(XListVIEwheader.STATE_REFRESHING);// DLog.i(TAG,"invoke refresh");if (mListVIEwListener != null) {// 此时执行刷刷新的方法mListVIEwListener.onRefresh();}}resetheaderHeight();} else if (getLastVisibleposition() == mTotalitemCount - 1) {// invoke load more.if (!mpullLoading && mEnablePullLoad && !mpullRefreshing) {// DLog.i(TAG,"invoke load more");}}break;}return super.ontouchEvent(ev);}@OverrIDepublic voID computeScroll() {if (mScroller.computeScrollOffset()) {if (mScrollBack == SCRolLBACK_header) {mheaderVIEw.setVisiableHeight(mScroller.getCurrY());} else {}postInvalIDate();invokeOnScrolling();}super.computeScroll();}@OverrIDepublic voID setonScrollListener(OnScrollListener l) {mScrollListener = l;}/*** 在滚动时回调,回调2-3次,手指没抛开则回调2次,scrollState = 2的这次不回调 第1次:scrollState =* SCRolL_STATE_touch_SCRolL(1) 正在滚动 第2次:scrollState =* SCRolL_STATE_FliNG(2)手指做了抛的动作(手指离开屏幕前,用力滑了一下) 第3次:scrollState =* SCRolL_STATE_IDLE(0) 停止滚动*/@OverrIDepublic voID onScrollStateChanged(AbsListVIEw vIEw,int scrollState) {if (mScrollListener != null) {mScrollListener.onScrollStateChanged(vIEw,scrollState);}// 滑到底部时,自动加载更多。 也可以禁用此逻辑if (getLastVisibleposition() == mTotalitemCount - 1&& scrollState == SCRolL_STATE_IDLE) {if (!mpullLoading && mEnablePullLoad && !mpullRefreshing) {// DLog.i(TAG,"invoke load more");}}}/*** 正在滚动的时候回调,停止滚动时才停止回调,单击时回调一次*/@OverrIDepublic voID onScroll(AbsListVIEw vIEw,int firstVisibleItem,int visibleItemCount,int totalitemCount) {// send to user's ListenermTotalitemCount = totalitemCount;if (mScrollListener != null) {mScrollListener.onScroll(vIEw,firstVisibleItem,visibleItemCount,totalitemCount);}}public voID setXListVIEwListener(IXListVIEwListener l) {mListVIEwListener = l;}/*** 监听ListVIEw的滑动事件* * @author cyf* */public interface OnXScrollListener extends OnScrollListener {public voID onXScrolling(VIEw vIEw);}/*** 自定义接口*/public interface IXListVIEwListener {// 下拉刷新时候执行的方法public voID onRefresh();// 上拉加载时候执行的方法public voID onLoadMore();}}</span> 

MainActivity的xml文件中的ListVIEw就不要用androID的ListVIEw了,用上面自定义的ListVIEw(加包名)

<span >package com.test.andy;import java.util.ArrayList;import com.test.andy.vIEw.XListVIEw;import com.test.andy.vIEw.XListVIEw.IXListVIEwListener;import com.test.andy.R;import androID.app.Activity;import androID.os.Bundle;import androID.os.Handler;import androID.Widget.ArrayAdapter;/*** XListVIEwActivity* 实现IXListVIEwListener接口是为了实现其中的下拉刷新等方法* @author cyf**/public class XListVIEwActivity extends Activity implements IXListVIEwListener {//自定义的ListVIEwprivate XListVIEw mListVIEw;private ArrayAdapter<String> mAdapter;private ArrayList<String> items = new ArrayList<String>();private Handler mHandler;private int start = 0;private int refreshCnt = 0;/** Called when the activity is first created. */@OverrIDepublic voID onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentVIEw(R.layout.main);//初始化的时候加载20条数据geneItems();mListVIEw = (XListVIEw) findVIEwByID(R.ID.xListVIEw);mListVIEw.setPullLoadEnable(true);mAdapter = new ArrayAdapter<String>(this,R.layout.List_item,items);mListVIEw.setAdapter(mAdapter);// mListVIEw.setPullRefreshEnable(false);mListVIEw.setXListVIEwListener(this);mHandler = new Handler();mListVIEw.startRefresh();}private voID geneItems() {for (int i = 0; i != 20; ++i) {items.add("refresh cnt " + (++start));}}private voID onLoad() {mListVIEw.stopRefresh();mListVIEw.stopLoadMore();mListVIEw.setRefreshTime("刚刚");}@OverrIDepublic voID onRefresh() {mHandler.postDelayed(new Runnable() {@OverrIDepublic voID run() {start = ++refreshCnt;items.clear();geneItems();// mAdapter.notifyDataSetChanged();mAdapter = new ArrayAdapter<String>(XListVIEwActivity.this,items);mListVIEw.setAdapter(mAdapter);onLoad();}},2000);}@OverrIDepublic voID onLoadMore() {mHandler.postDelayed(new Runnable() {@OverrIDepublic voID run() {geneItems();mAdapter.notifyDataSetChanged();onLoad();}},2000);}}</span> 

重要的代码都总结在这了,希望给大家带来帮助,谢谢。

总结

以上是内存溢出为你收集整理的Android自定义控件开发实战之实现ListView下拉刷新实例代码全部内容,希望文章能够帮你解决Android自定义控件开发实战之实现ListView下拉刷新实例代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1141605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存