Android中自定义ListView控件实现下拉刷新,简单实用效果好(原创)

Android中自定义ListView控件实现下拉刷新,简单实用效果好(原创)

2023年7月15日发(作者:)

花了一天时间写出了这个类来实现下拉刷新。

首先这是一个自定义的listView控件类,我在许多项目中都用到了它,效果很稳定。实现也很简单。用的时候其他功能都和系统提供的ListView一样,就只是多了一个下拉刷新监听。用这个类替代系统提供的ListView,下拉刷新再也不会烦恼了。(^o^)/~

希望对大家有用。

我写的自定义ListView的代码:

import ;

import t;

import uteSet;

import ;

import Inflater;

import Event;

import ;

import oup;

import Interpolator;

import Animation;

import tView;

import apter;

import iew;

import Layout;

import ew;

import llListener;

import ssBar;

import ew;

public class MyListView extends ListView implements OnScrollListener

{

private static final String TAG = "listview";

private final static int RELEASE_To_REFRESH = 0;

private final static int PULL_To_REFRESH = 1;

private final static int REFRESHING = 2;

private final static int DONE = 3;

private final static int LOADING = 4;

// 实际的padding的距离与界面上偏移距离的比例

private final static int RATIO = 3;

private LayoutInflater inflater;

private LinearLayout headView;

private TextView tipsTextview;

private TextView lastUpdatedTextView;

private ImageView arrowImageView;

private ProgressBar progressBar;

private RotateAnimation animation;

private RotateAnimation reverseAnimation;

// 用于保证startY的值在一个完整的touch事件中只被记录一次

private boolean isRecored;

private int headContentWidth;

private int headContentHeight;

private int startY;

private int firstItemIndex;

private int state;

private boolean isBack;

private OnRefreshListener refreshListener;

private boolean isRefreshable;

public MyListView(Context context) {

super(context);

init(context);

}

public MyListView(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

private void init(Context context) {

setCacheColorHint(ources().getColor(arent));

inflater = (context);

headView = (LinearLayout) e(,

null);

arrowImageView = (ImageView) headView

.findViewById(_arrowImageView);

imumWidth(70);

imumHeight(50);

progressBar = (ProgressBar) headView

.findViewById(_progressBar);

tipsTextview = (TextView)

ewById(_tipsTextView);

lastUpdatedTextView = (TextView) headView .findViewById(_lastUpdatedTextView);

measureView(headView);

headContentHeight = suredHeight();

headContentWidth = suredWidth();

ding(0, -1 * headContentHeight, 0, 0);

date();

Log.v("size", "width:" + headContentWidth + " height:"

+ headContentHeight);

addHeaderView(headView, null, false);

setOnScrollListener(this);

animation = new RotateAnimation(0, -180,

VE_TO_SELF, 0.5f,

VE_TO_SELF, 0.5f);

erpolator(new LinearInterpolator());

ation(250);

lAfter(true);

reverseAnimation = new RotateAnimation(-180, 0,

VE_TO_SELF, 0.5f,

VE_TO_SELF, 0.5f);

erpolator(new LinearInterpolator());

ation(200);

lAfter(true);

state = DONE;

isRefreshable = false;

}

public void onScroll(AbsListView arg0, int firstVisiableItem, int

arg2,

int arg3) {

firstItemIndex = firstVisiableItem;

}

public void onScrollStateChanged(AbsListView arg0, int arg1) {

}

public boolean onTouchEvent(MotionEvent event) {

if (isRefreshable) {

switch (ion()) {

case _DOWN:

if (firstItemIndex == 0 && !isRecored) {

isRecored = true;

startY = (int) ();

Log.v(TAG, "在down时候记录当前位置‘");

}

break;

case _UP:

if (state != REFRESHING && state != LOADING) {

if (state == DONE) {

// 什么都不做

}

if (state == PULL_To_REFRESH) {

state = DONE;

changeHeaderViewByState();

Log.v(TAG, "由下拉刷新状态,到done状态");

}

if (state == RELEASE_To_REFRESH) {

state = REFRESHING;

changeHeaderViewByState();

onRefresh();

Log.v(TAG, "由松开刷新状态,到done状态");

}

}

isRecored = false;

isBack = false;

break;

case _MOVE:

int tempY = (int) ();

if (!isRecored && firstItemIndex == 0) {

Log.v(TAG, "在move时候记录下位置");

isRecored = true;

startY = tempY;

}

{

if (state != REFRESHING && isRecored && state != LOADING)

// 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动

// 可以松手去刷新了

if (state == RELEASE_To_REFRESH) {

setSelection(0);

// 往上推了,推到了屏幕足够掩盖head的程度,但是还没有if

(((tempY - startY) / RATIO <

推到全部掩盖的地步

headContentHeight)

&& (tempY - startY) > 0) {

state = PULL_To_REFRESH;

changeHeaderViewByState();

Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");

}

// 一下子推到顶了

else if (tempY - startY <= 0) {

state = DONE;

changeHeaderViewByState();

Log.v(TAG, "由松开刷新状态转变到done状态");

}

// 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步

else {

// 不用进行特别的操作,只用更新paddingTop的值就行

}

}

// 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态

if (state == PULL_To_REFRESH) {

setSelection(0);

{

// 下拉到可以进入RELEASE_TO_REFRESH的状态

if ((tempY - startY) / RATIO >= headContentHeight)

");

态");

}

state = RELEASE_To_REFRESH;

isBack = true;

changeHeaderViewByState();

Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新 }

// 上推到顶了

else if (tempY - startY <= 0) {

state = DONE;

changeHeaderViewByState();

Log.v(TAG, "由DOne或者下拉刷新状态转变到done状 }

}

// done状态下

if (state == DONE) {

if (tempY - startY > 0) {

state = PULL_To_REFRESH;

changeHeaderViewByState();

}

}

// 更新headView的size

if (state == PULL_To_REFRESH) {

ding(0, -1 * headContentHeight

+ (tempY - startY) / RATIO, 0, 0);

}

// 更新headView的paddingTop

if (state == RELEASE_To_REFRESH) {

ding(0, (tempY - startY) / RATIO

- headContentHeight, 0, 0);

}

}

break;

}

return hEvent(event);

}

// 当状态改变时候,调用该方法,以更新界面

private void changeHeaderViewByState() {

switch (state) {

case RELEASE_To_REFRESH:

ibility(E);

ibility();

ibility(E);

ibility(E);

nimation();

nimation(animation);

t("松开刷新");

Log.v(TAG, "当前状态,松开刷新");

break;

case PULL_To_REFRESH:

ibility();

ibility(E);

ibility(E);

nimation();

ibility(E);

// 是由RELEASE_To_REFRESH状态转变来的

if (isBack) {

isBack = false;

nimation();

nimation(reverseAnimation);

t("下拉刷新");

} else {

t("下拉刷新");

}

Log.v(TAG, "当前状态,下拉刷新");

break;

case REFRESHING:

ding(0, 0, 0, 0);

ibility(E);

nimation();

ibility();

t("正在刷新...");

ibility(E);

Log.v(TAG, "当前状态,正在刷新...");

break;

case DONE:

ding(0, -1 * headContentHeight, 0, 0);

ibility();

nimation();

geResource();

t("下拉刷新");

ibility(E);

Log.v(TAG, "当前状态,done");

break;

}

}

public void setonRefreshListener(OnRefreshListener

refreshListener) {

hListener = refreshListener;

isRefreshable = true;

}

public interface OnRefreshListener {

public void onRefresh();

}

public void onRefreshComplete() {

state = DONE;

t("最Date().toLocaleString());

changeHeaderViewByState();

}

private void onRefresh() {

if (refreshListener != null) {

esh();

}

}

近更新:" + new

// 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height

private void measureView(View child) {

Params p = outParams();

if (p == null) {

p = new

Params(_PARENT,

_CONTENT);

}

int childWidthSpec = ldMeasureSpec(0, 0 + 0,

);

int lpHeight = ;

int childHeightSpec;

if (lpHeight > 0) {

childHeightSpec = asureSpec(lpHeight,

Y);

} else {

childHeightSpec = asureSpec(0,

IFIED);

}

e(childWidthSpec, childHeightSpec);

}

public void setAdapter(BaseAdapter adapter) {

t("Date().toLocaleString());

pter(adapter);

}

}

最近更新:" + new

这个类到此结束了,你可以在项目中建一个类把此类拷贝进去,作为你自定义的listView使用就可以了。我是把此类命名为MyListView.

下面就是在布局文件中使用这个自定义的ListView了。上代码:

xmlns:android="/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@drawable/inner_bg"

>

android:layout_width="fill_parent" android:layout_alignParentTop="true"

layout="@layout/layout_topbar_personalletter" />

android:layout_below="@+id/topbar"

android:id="@+id/list_View"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@null" android:divider="#00acacac"

android:listSelector="@drawable/scholarnews_listitem_color"

android:dividerHeight="1dp"

android:cacheColorHint="#00000000"/>

android:layout_width="fill_parent"

layout="@layout/collection_detailcontent" />

android:layout_width="fill_parent"

layout="@layout/layout_reply" />

android:layout_width="fill_parent"

layout="@layout/layout_webload" />

其中的View控件就是引用我自定义的这个ListView作为布局的。包名+类名。

在Activity类中拿到这个listView后,就要设置对他进行下拉刷新监听,方法很简单。

// 下拉后松开刷新时就会调用这个方法

efreshListener(new

eshListener() {

@Override

public void onRefresh() {

//里面执行你要实现的操作

}

});

等你把想要加载的数据加载完成后只需要调用一个方法告诉这个ListView你刷新完成就行了。就是下面这个方法:

eshComplete();

到此 所有的工作都做完了,希望这个对你有帮助。

谢谢!

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689427316a246422.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信