版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中怎么利用ListView实现下拉加载功能
Android中怎么利用ListView实现下拉加载功能,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、MyListView.Javapublic
class
MyListView
extends
ListView
implements
OnScrollListener
{
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;
//
ListView头部下拉刷新的布局
private
LinearLayout
headerView;
private
TextView
lvHeaderTipsTv;
private
TextView
lvHeaderLastUpdatedTv;
private
ImageView
lvHeaderArrowIv;
private
ProgressBar
lvHeaderProgressBar;
//
定义头部下拉刷新的布局的高度
private
int
headerContentHeight;
private
RotateAnimation
animation;
private
RotateAnimation
reverseAnimation;
private
int
startY;
private
int
state;
private
boolean
isBack;
//
用于保证startY的值在一个完整的touch事件中只被记录一次
private
boolean
isRecored;
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)
{
inflater
=
LayoutInflater.from(context);
headerView
=
(LinearLayout)
inflater.inflate(R.layout.lv_header,
null);
lvHeaderTipsTv
=
(TextView)
headerView
.findViewById(R.id.lvHeaderTipsTv);
lvHeaderLastUpdatedTv
=
(TextView)
headerView
.findViewById(R.id.lvHeaderLastUpdatedTv);
lvHeaderArrowIv
=
(ImageView)
headerView
.findViewById(R.id.lvHeaderArrowIv);
//
设置下拉刷新图标的最小高度和宽度
lvHeaderArrowIv.setMinimumWidth(70);
lvHeaderArrowIv.setMinimumHeight(50);
lvHeaderProgressBar
=
(ProgressBar)
headerView
.findViewById(R.id.lvHeaderProgressBar);
measureView(headerView);
headerContentHeight
=
headerView.getMeasuredHeight();
//
设置内边距,正好距离顶部为一个负的整个布局的高度,正好把头部隐藏
headerView.setPadding(0,
-1
*
headerContentHeight,
0,
0);
//
重绘一下
headerView.invalidate();
//
将下拉刷新的布局加入ListView的顶部
addHeaderView(headerView,
null,
false);
//
设置滚动监听事件
setOnScrollListener(this);
//
设置旋转动画事件
animation
=
new
RotateAnimation(0,
-180,
RotateAnimation.RELATIVE_TO_SELF,
0.5f,
RotateAnimation.RELATIVE_TO_SELF,
0.5f);
animation.setInterpolator(new
LinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);
reverseAnimation
=
new
RotateAnimation(-180,
0,
RotateAnimation.RELATIVE_TO_SELF,
0.5f,
RotateAnimation.RELATIVE_TO_SELF,
0.5f);
reverseAnimation.setInterpolator(new
LinearInterpolator());
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);
//
一开始的状态就是下拉刷新完的状态,所以为DONE
state
=
DONE;
//
是否正在刷新
isRefreshable
=
false;
}
@Override
public
void
onScrollStateChanged(AbsListView
view,
int
scrollState)
{
}
@Override
public
void
onScroll(AbsListView
view,
int
firstVisibleItem,
int
visibleItemCount,
int
totalItemCount)
{
if
(firstVisibleItem
==
0)
{
isRefreshable
=
true;
}
else
{
isRefreshable
=
false;
}
}
@Override
public
boolean
onTouchEvent(MotionEvent
ev)
{
if
(isRefreshable)
{
switch
(ev.getAction())
{
case
MotionEvent.ACTION_DOWN:
if
(!isRecored)
{
isRecored
=
true;
startY
=
(int)
ev.getY();//
手指按下时记录当前位置
}
break;
case
MotionEvent.ACTION_UP:
if
(state
!=
REFRESHING
&&
state
!=
LOADING)
{
if
(state
==
PULL_To_REFRESH)
{
state
=
DONE;
changeHeaderViewByState();
}
if
(state
==
RELEASE_To_REFRESH)
{
state
=
REFRESHING;
changeHeaderViewByState();
onLvRefresh();
}
}
isRecored
=
false;
isBack
=
false;
break;
case
MotionEvent.ACTION_MOVE:
int
tempY
=
(int)
ev.getY();
if
(!isRecored)
{
isRecored
=
true;
startY
=
tempY;
}
if
(state
!=
REFRESHING
&&
isRecored
&&
state
!=
LOADING)
{
//
保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动
//
可以松手去刷新了
if
(state
==
RELEASE_To_REFRESH)
{
setSelection(0);
//
往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
if
(((tempY
-
startY)
/
RATIO
<
headerContentHeight)//
由松开刷新状态转变到下拉刷新状态
&&
(tempY
-
startY)
>
0)
{
state
=
PULL_To_REFRESH;
changeHeaderViewByState();
}
//
一下子推到顶了
else
if
(tempY
-
startY
<=
0)
{//
由松开刷新状态转变到done状态
state
=
DONE;
changeHeaderViewByState();
}
}
//
还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
if
(state
==
PULL_To_REFRESH)
{
setSelection(0);
//
下拉到可以进入RELEASE_TO_REFRESH的状态
if
((tempY
-
startY)
/
RATIO
>=
headerContentHeight)
{//
由done或者下拉刷新状态转变到松开刷新
state
=
RELEASE_To_REFRESH;
isBack
=
true;
changeHeaderViewByState();
}
//
上推到顶了
else
if
(tempY
-
startY
<=
0)
{//
由DOne或者下拉刷新状态转变到done状态
state
=
DONE;
changeHeaderViewByState();
}
}
//
done状态下
if
(state
==
DONE)
{
if
(tempY
-
startY
>
0)
{
state
=
PULL_To_REFRESH;
changeHeaderViewByState();
}
}
//
更新headView的size
if
(state
==
PULL_To_REFRESH)
{
headerView.setPadding(0,
-1
*
headerContentHeight
+
(tempY
-
startY)
/
RATIO,
0,
0);
}
//
更新headView的paddingTop
if
(state
==
RELEASE_To_REFRESH)
{
headerView.setPadding(0,
(tempY
-
startY)
/
RATIO
-
headerContentHeight,
0,
0);
}
}
break;
default:
break;
}
}
return
super.onTouchEvent(ev);
}
//
当状态改变时候,调用该方法,以更新界面
private
void
changeHeaderViewByState()
{
switch
(state)
{
case
RELEASE_To_REFRESH:
lvHeaderArrowIv.setVisibility(View.VISIBLE);
lvHeaderProgressBar.setVisibility(View.GONE);
lvHeaderTipsTv.setVisibility(View.VISIBLE);
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
lvHeaderArrowIv.clearAnimation();//
清除动画
lvHeaderArrowIv.startAnimation(animation);//
开始动画效果
lvHeaderTipsTv.setText("松开刷新");
break;
case
PULL_To_REFRESH:
lvHeaderProgressBar.setVisibility(View.GONE);
lvHeaderTipsTv.setVisibility(View.VISIBLE);
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.setVisibility(View.VISIBLE);
//
是由RELEASE_To_REFRESH状态转变来的
if
(isBack)
{
isBack
=
false;
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.startAnimation(reverseAnimation);
lvHeaderTipsTv.setText("下拉刷新");
}
else
{
lvHeaderTipsTv.setText("下拉刷新");
}
break;
case
REFRESHING:
headerView.setPadding(0,
0,
0,
0);
lvHeaderProgressBar.setVisibility(View.VISIBLE);
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.setVisibility(View.GONE);
lvHeaderTipsTv.setText("正在刷新...");
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
break;
case
DONE:
headerView.setPadding(0,
-1
*
headerContentHeight,
0,
0);
lvHeaderProgressBar.setVisibility(View.GONE);
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.setImageResource(R.drawable.arrow);
lvHeaderTipsTv.setText("下拉刷新");
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
break;
}
}
//
此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height
private
void
measureView(View
child)
{
ViewGroup.LayoutParams
params
=
child.getLayoutParams();
if
(params
==
null)
{
params
=
new
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int
childWidthSpec
=
ViewGroup.getChildMeasureSpec(0,
0
+
0,
params.width);
int
lpHeight
=
params.height;
int
childHeightSpec;
if
(lpHeight
>
0)
{
childHeightSpec
=
MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
}
else
{
childHeightSpec
=
MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec,
childHeightSpec);
}
public
void
setonRefreshListener(OnRefreshListener
refreshListener)
{
this.refreshListener
=
refreshListener;
isRefreshable
=
true;
}
public
interface
OnRefreshListener
{
public
void
onRefresh();
}
public
void
onRefreshComplete()
{
state
=
DONE;
lvHeaderLastUpdatedTv.setText("最近更新:"
+
new
Date().toLocaleString());
changeHeaderViewByState();
}
private
void
onLvRefresh()
{
if
(refreshListener
!=
null)
{
refreshListener.onRefresh();
}
}
public
void
setAdapter(LvAdapter
adapter)
{
lvHeaderLastUpdatedTv.setText("最近更新:"
+
new
Date().toLocaleString());
super.setAdapter(adapter);
}
}2、MainActivity.javapublic
class
MainActivity
extends
Activity
{
private
List<String>
list;
private
MyListView
lv;
private
LvAdapter
adapter;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv
=
(MyListView)
findViewById(R.id.lv);
list
=
new
ArrayList<String>();
list.add("loonggg");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
list.add("我们都是开发者");
adapter
=
new
LvAdapter(list,
this);
lv.setAdapter(adapter);
lv.setonRefreshListener(new
OnRefreshListener()
{
@Override
public
void
onRefresh()
{
new
AsyncTask<Void,
Void,
Void>()
{
protected
Void
doInBackground(Void...
params)
{
try
{
Thread.sleep(1000);
}
catch
(Exception
e)
{
e.printStackTrace();
}
list.add("刷新后添加的内容");
return
null;
}
@Override
protected
void
onPostExecute(Void
result)
{
adapter.notifyDataSetChanged();
lv.onRefreshComplete();
}
}.execute(null,
null,
null);
}
});
}
}3、LvAdapterpublicclassLvAdapterextendsBaseAdapter{
privateList<String>list;
privateContextcontext;
publicLvAdapter(List<String>list,Contextcontext){
this.list=list;
this.context=context;
}
@Override
publicintgetCount(){
returnlist.size();
}
@Override
publicObjectgetItem(intposition){
returnlist.get(position);
}
@Override
publiclonggetItemId(intposition){
returnposition;
}
@Override
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
TextViewtv=newTextView(context.getApplicationContext());
tv.setText(list.get(position));
returntv;
}
}
4、lv_header.xml[html]viewplaincopy<LinearLayoutxmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000">
<!--内容-->
<RelativeLayout
android:id="@+id/head_contentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp">
<!--箭头图像、进度条-->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true">
<!--箭头-->
<ImageView
android:id="@+id/lvHeaderArrowIv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/arrow"/>
<!--进度条-->
<ProgressBar
android:id="@+id/lvHeaderProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
</FrameLayout>
<!--提示、最近更新-->
<LinearLayout
android:l
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《高等数学基础知识》课件
- 湖南省名校联考联合体2024-2025学年高三上学期第四次联考历史试题(含答案)
- 巨大胎儿的健康宣教
- 亚急性皮肤红斑狼疮的健康宣教
- 药物性鼻炎的健康宣教
- 家族性进行性色素沉着的临床护理
- 家族性黏液血管纤维瘤的临床护理
- 1.4.2用空间向量研究夹角问题第2课时(教学课件)高二数学选择性必修第一册(人教A版2019)
- JJF(陕) 056-2021 等电位测试仪校准规范
- 金融行业品牌推广策略计划
- 九年级下册孔乙己课文原文及解读
- 英汉汉英口译智慧树知到答案2024年山东科技大学
- DB63T 2318-2024 办公用房维修管理规范
- 2024年人教版小学四年级科学(下册)期末试卷及答案
- 人教版数学九年级上册说课稿22.1.4《二次函数y=ax2+bx+c的图象和性质》
- 移动电子商务在流动货摊零售中的机会
- 操作规程与保养作业指导书-注塑机
- 绿化养护服务投标方案(技术标)
- 中职语文基础模块上册-第一次月考卷(1)【知识范围:1-2单元】解析版
- 国开本科《城市管理学》期末考试题库及答案
- 进修骨科汇报课件
评论
0/150
提交评论