android中怎么实现上拉刷新
3个回答
推荐于2016-05-06 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
向TA提问 私信TA
知道合伙人数码行家
采纳数:117538
获赞数:517165
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。
向TA提问 私信TA
关注
展开全部
这篇文章主要介绍了android实现listview下拉刷新和上拉刷新效果,Android的ListView上拉下拉刷新,原理都一样,在Touch事件中操作header/footer的paddingTop属性,需要的朋友可以参考下
public class PullToLoadListView extends ListView implements OnScrollListener {
private static final String TAG = PullToLoadListView.class.getSimpleName();
private static final int STATE_NON = 0;
private static final int STATE_PULL_TO_REFRESH = 1;
private static final int STATE_RELEASE_TO_REFRESH = 2;
private static final int STATE_REFRESHING = 3;
private int state;
private int firstVisibleItem;
private int lastVisisibleItem;
private float prevY = 0;
private View headerView;
private View footerView;
// header widgets
private ProgressBar headerProgressBar;
private ImageView headerImageArrow;
private TextView headerText;
private RotateAnimation headerArrowAnim;
private RotateAnimation headerArrowReverseAnim;
// footer widgets
private ProgressBar footerProgressBar;
private TextView footerText;
private boolean headerIsHanding = false;
private boolean footerIsHanding = false;
private int headerHeight;
private int footerHeight;
private ResetAnimation resetAnim;
private OnLoadingListener onLoadingListener;
private OnScrollListener onScrollListener;
public PullToLoadListView(Context context) {
super(context);
init(context);
}
public PullToLoadListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
state = STATE_NON;
firstVisibleItem = 0;
lastVisisibleItem = 0;
LayoutInflater inflater = LayoutInflater.from(context);
headerView = inflater.inflate(R.layout.view_pull_header, null);
footerView = inflater.inflate(R.layout.view_pull_footer, null);
headerProgressBar = (ProgressBar) headerView.findViewById(R.id.progressbar);
headerImageArrow = (ImageView) headerView.findViewById(R.id.arrow);
headerText = (TextView) headerView.findViewById(R.id.text);
headerArrowAnim = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
headerArrowAnim.setDuration(300);
headerArrowAnim.setFillAfter(true);
headerArrowReverseAnim = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
headerArrowReverseAnim.setDuration(300);
headerArrowReverseAnim.setFillAfter(true);
footerProgressBar = (ProgressBar) footerView.findViewById(R.id.progressbar);
footerText = (TextView) footerView.findViewById(R.id.text);
measureView(headerView);
measureView(footerView);
headerHeight = headerView.getMeasuredHeight();
footerHeight = footerView.getMeasuredHeight();
headerView.setPadding(0, -1 * headerView.getMeasuredHeight(), 0, 0);
footerView.setPadding(0, -1 * footerView.getMeasuredHeight(), 0, 0);
headerView.invalidate();
footerView.invalidate();
addHeaderView(headerView, null, false);
addFooterView(footerView, null, false);
super.setOnScrollListener(this);
}
private void measureView(View view) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
if(lp == null) {
lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
int childHeightSpec;
if(lp.height > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(childWidthSpec, childHeightSpec);
}
private void resetHeader() {
// headerView.setPadding(0, -1 * headerHeight, 0, 0);
resetAnim = new ResetAnimation(headerView, headerHeight, headerView.getPaddingTop());
resetAnim.start();
}
private void resetFooter() {
resetAnim = new ResetAnimation(footerView, footerHeight, footerView.getPaddingTop());
resetAnim.start();
}
private void changeHeaderViewByState(int state) {
if(this.state == state) {
return ;
}
int prevState = this.state;
this.state = state;
switch(state) {
case STATE_NON:
headerProgressBar.setVisibility(View.INVISIBLE);
headerImageArrow.setVisibility(View.VISIBLE);
headerImageArrow.clearAnimation();
headerText.setText("Pull Down To Refresh");
break;
case STATE_PULL_TO_REFRESH:
headerProgressBar.setVisibility(View.INVISIBLE);
headerImageArrow.setVisibility(View.VISIBLE);
headerText.setText("Pull Down To Refresh");
if(prevState == STATE_RELEASE_TO_REFRESH) {
headerImageArrow.startAnimation(headerArrowReverseAnim);
} else {
headerImageArrow.clearAnimation();
}
break;
case STATE_RELEASE_TO_REFRESH:
headerProgressBar.setVisibility(View.INVISIBLE);
headerImageArrow.setVisibility(View.VISIBLE);
headerImageArrow.startAnimation(headerArrowAnim);
headerText.setText("Release To Refresh");
break;
case STATE_REFRESHING:
headerProgressBar.setVisibility(View.VISIBLE);
headerImageArrow.setVisibility(View.INVISIBLE);
headerImageArrow.clearAnimation();
headerText.setText("Refreshing");
break;
default:
break;
}
}
private void changeFooterViewByState(int state) {
if(this.state == state) {
return ;
}
this.state = state;
switch(state) {
case STATE_NON:
footerProgressBar.setVisibility(View.INVISIBLE);
footerText.setText("Pull Up To Refresh");
break;
case STATE_PULL_TO_REFRESH:
footerProgressBar.setVisibility(View.INVISIBLE);
footerText.setText("Pull Up To Refresh");
break;
case STATE_RELEASE_TO_REFRESH:
footerProgressBar.setVisibility(View.INVISIBLE);
footerText.setText("Release To Refresh");
break;
case STATE_REFRESHING:
footerProgressBar.setVisibility(View.VISIBLE);
footerText.setText("Refreshing");
break;
default:
break;
}
}
@Override
public void setOnScrollListener(OnScrollListener l) {
this.onScrollListener = l;
}
public void setOnLoadingListener(OnLoadingListener onLoadingListener) {
this.onLoadingListener = onLoadingListener;
}
public void loadCompleted() {
if(headerIsHanding) {
changeHeaderViewByState(STATE_NON);
resetHeader();
headerIsHanding = false;
}
if(footerIsHanding) {
changeFooterViewByState(STATE_NON);
resetFooter();
footerIsHanding = false;
}
}
private void handleMoveHeaderEvent(MotionEvent ev) {
headerIsHanding = true;
float tempY = ev.getRawY();
float vector = tempY - prevY;
vector /= 2;
prevY = tempY;
if(vector > 0) {
int newPadding = (int) (headerView.getPaddingTop() + vector);
newPadding = Math.min(newPadding, headerHeight / 2);
headerView.setPadding(0, newPadding, 0, 0);
if(state != STATE_REFRESHING) {
if(newPadding > 0) {
changeHeaderViewByState(STATE_RELEASE_TO_REFRESH);
} else {
changeHeaderViewByState(STATE_PULL_TO_REFRESH);
}
}
} else {
if(state == STATE_RELEASE_TO_REFRESH || state == STATE_PULL_TO_REFRESH) {
int newPadding = (int) (headerView.getPaddingTop() + vector);
newPadding = Math.max(newPadding, -1 * headerHeight);
headerView.setPadding(0, newPadding, 0, 0);
if(newPadding <= -1 * headerHeight) {
changeHeaderViewByState(STATE_NON);
headerIsHanding = false;
} else if(newPadding <= 0) {
changeHeaderViewByState(STATE_PULL_TO_REFRESH);
} else {
}
}
}
}
private void handleMoveFooterEvent(MotionEvent ev) {
footerIsHanding = true;
float tempY = ev.getRawY();
float vector = tempY - prevY;
vector /= 2;
prevY = tempY;
if(vector < 0) {
int newPadding = (int) (footerView.getPaddingTop() - vector);
if(newPadding > 0) {
newPadding = 0;
}
footerView.setPadding(0, newPadding, 0, 0);
if(state != STATE_REFRESHING) {
if(newPadding < 0) {
changeFooterViewByState(STATE_PULL_TO_REFRESH);
} else {
changeFooterViewByState(STATE_RELEASE_TO_REFRESH);
}
}
} else {
int newPadding = (int) (footerView.getPaddingTop() - vector);
newPadding = Math.min(newPadding, footerHeight);
footerView.setPadding(0, newPadding, 0, 0);
if(newPadding <= -1 * footerHeight) {
changeFooterViewByState(STATE_NON);
footerIsHanding = false;
} else if(newPadding < 0) {
changeFooterViewByState(STATE_PULL_TO_REFRESH);
}
}
}
展开全部
android开发中,listview是最常用的控件之一,通常我们可以再微博、微信等很多应用里面都可以看到下拉刷新,以及上拉刷新,点击查看更多等功能。
上拉刷新其实和底部的“点击加载更多”的功能差不多。都是分页加载数据的一个实现。具体是去监听滚动条事件,下拉到底部时进行操作。可以通过以下代码实现上拉刷新功能:
package com.xzw.demo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
public class MainActivity extends Activity implements OnScrollListener {
private static final String TAG = "MainActivity";
private ListView listView;
private View moreView; //加载更多页面
private SimpleAdapter adapter;
private ArrayList<HashMap<String, String>> listData;
private int lastItem;
private int count;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
moreView = getLayoutInflater().inflate(R.layout.load, null);
listData = new ArrayList<HashMap<String,String>>();
prepareData(); //准备数据
count = listData.size();
adapter = new SimpleAdapter(this, listData,R.layout.item,
new String[]{"itemText"}, new int[]{R.id.itemText});
listView.addFooterView(moreView); //添加底部view,一定要在setAdapter之前添加,否则会报错。
listView.setAdapter(adapter); //设置adapter
listView.setOnScrollListener(this); //设置listview的滚动事件
}
private void prepareData(){ //准备数据
for(int i=0;i<10;i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("itemText", "测试数据"+i);
listData.add(map);
}
}
private void loadMoreData(){ //加载更多数据
count = adapter.getCount();
for(int i=count;i<count+5;i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("itemText", "测试数据"+i);
listData.add(map);
}
count = listData.size();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.i(TAG, "firstVisibleItem="+firstVisibleItem+"\nvisibleItemCount="+
visibleItemCount+"\ntotalItemCount"+totalItemCount);
lastItem = firstVisibleItem + visibleItemCount - 1; //减1是因为上面加了个addFooterView
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.i(TAG, "scrollState="+scrollState);
//下拉到空闲是,且最后一个item的数等于数据的总数时,进行更新
if(lastItem == count && scrollState == this.SCROLL_STATE_IDLE){
Log.i(TAG, "拉到最底部");
moreView.setVisibility(view.VISIBLE);
mHandler.sendEmptyMessage(0);
}
}
//声明Handler
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
loadMoreData(); //加载更多数据,这里可以使用异步加载
adapter.notifyDataSetChanged();
moreView.setVisibility(View.GONE);
if(count > 30){
Toast.makeText(MainActivity.this, "木有更多数据!", 3000).show();
listView.removeFooterView(moreView); //移除底部视图
}
Log.i(TAG, "加载更多数据");
break;
case 1:
break;
default:
break;
}
};
};
}
上拉刷新其实和底部的“点击加载更多”的功能差不多。都是分页加载数据的一个实现。具体是去监听滚动条事件,下拉到底部时进行操作。可以通过以下代码实现上拉刷新功能:
package com.xzw.demo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
public class MainActivity extends Activity implements OnScrollListener {
private static final String TAG = "MainActivity";
private ListView listView;
private View moreView; //加载更多页面
private SimpleAdapter adapter;
private ArrayList<HashMap<String, String>> listData;
private int lastItem;
private int count;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
moreView = getLayoutInflater().inflate(R.layout.load, null);
listData = new ArrayList<HashMap<String,String>>();
prepareData(); //准备数据
count = listData.size();
adapter = new SimpleAdapter(this, listData,R.layout.item,
new String[]{"itemText"}, new int[]{R.id.itemText});
listView.addFooterView(moreView); //添加底部view,一定要在setAdapter之前添加,否则会报错。
listView.setAdapter(adapter); //设置adapter
listView.setOnScrollListener(this); //设置listview的滚动事件
}
private void prepareData(){ //准备数据
for(int i=0;i<10;i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("itemText", "测试数据"+i);
listData.add(map);
}
}
private void loadMoreData(){ //加载更多数据
count = adapter.getCount();
for(int i=count;i<count+5;i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("itemText", "测试数据"+i);
listData.add(map);
}
count = listData.size();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.i(TAG, "firstVisibleItem="+firstVisibleItem+"\nvisibleItemCount="+
visibleItemCount+"\ntotalItemCount"+totalItemCount);
lastItem = firstVisibleItem + visibleItemCount - 1; //减1是因为上面加了个addFooterView
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.i(TAG, "scrollState="+scrollState);
//下拉到空闲是,且最后一个item的数等于数据的总数时,进行更新
if(lastItem == count && scrollState == this.SCROLL_STATE_IDLE){
Log.i(TAG, "拉到最底部");
moreView.setVisibility(view.VISIBLE);
mHandler.sendEmptyMessage(0);
}
}
//声明Handler
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
loadMoreData(); //加载更多数据,这里可以使用异步加载
adapter.notifyDataSetChanged();
moreView.setVisibility(View.GONE);
if(count > 30){
Toast.makeText(MainActivity.this, "木有更多数据!", 3000).show();
listView.removeFooterView(moreView); //移除底部视图
}
Log.i(TAG, "加载更多数据");
break;
case 1:
break;
default:
break;
}
};
};
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询