這個(gè)博客好想不能提供下載代碼啊, 我只能把代碼貼出來了...
為滁州等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及滁州網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、滁州網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
其實(shí)你只需看用法, 不用關(guān)心具體實(shí)現(xiàn),demo非常容易看懂
public class CustomListViewActivity extends Activity {
private CustomListView listview;
private ArrayList<String> data;
private BaseAdapter adapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
setListener();
}
private void init(){
data = new ArrayList<String>();
//虛擬一些數(shù)據(jù)
data.add("a");
data.add("b");
data.add("c");
data.add("e");
data.add("f");
data.add("g");
data.add("h");
data.add("i");
data.add("j");
data.add("k");
data.add("L");
data.add("M");
data.add("L");
data.add("N");
data.add("O");
data.add("P");
data.add("Q");
listview = (CustomListView) findViewById(R.id.listview);
adapter = new BaseAdapter(){
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(getApplicationContext());
textView.setHeight(100);
textView.setTextSize(20);
textView.setGravity(Gravity.CENTER);
textView.setBackgroundColor(0x66666666);
textView.setTextColor(0xaaffffff);
textView.setText(data.get(position));
return textView;
}
};
listview.setAdapter(adapter);
}
private void setListener(){
listview.setOnRefreshListner(new OnRefreshListner() {
@Override
public void onRefresh() {
new AsyncTask<Void, Void, ArrayList<String>>(){
@Override
protected ArrayList<String> doInBackground(Void... params) {
try {
//模擬從服務(wù)器獲取數(shù)據(jù)的過程
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
ArrayList<String> virtualData = new ArrayList<String>();
virtualData.add("Head刷新后的新數(shù)據(jù)1");
virtualData.add("Head刷新后的新數(shù)據(jù)2");
virtualData.add("Head刷新后的新數(shù)據(jù)3");
virtualData.add("Head刷新后的新數(shù)據(jù)4");
virtualData.add("Head刷新后的新數(shù)據(jù)5");
virtualData.add("Head刷新后的新數(shù)據(jù)6");
return virtualData;
}
//更新UI的方法,系統(tǒng)自動(dòng)實(shí)現(xiàn)
@Override
protected void onPostExecute(ArrayList<String> result) {
data.addAll(0,result);//注意是往前添加數(shù)據(jù)
adapter.notifyDataSetChanged();
listview.onRefreshComplete();//完成下拉刷新,這個(gè)方法要調(diào)用
super.onPostExecute(result);
}
}.execute();
}
});
//創(chuàng)建FootView
final View footer = View.inflate(CustomListViewActivity.this, R.layout.footer, null);
listview.setOnAddFootListener(new OnAddFootListener() {
@Override
public void addFoot() {
listview.addFooterView(footer);
}
});
listview.setOnFootLoadingListener(new OnFootLoadingListener() {
@Override
public void onFootLoading() {
new AsyncTask<Void, Void, ArrayList<String>>(){
@Override
protected ArrayList<String> doInBackground(Void... params) {
try {
//模擬從服務(wù)器獲取數(shù)據(jù)的過程
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ArrayList<String> virtualData = new ArrayList<String>();
virtualData.add("Foot刷新后的新數(shù)據(jù)1");
virtualData.add("Foot刷新后的新數(shù)據(jù)2");
virtualData.add("Foot刷新后的新數(shù)據(jù)3");
virtualData.add("Foot刷新后的新數(shù)據(jù)4");
virtualData.add("Foot刷新后的新數(shù)據(jù)5");
virtualData.add("Foot刷新后的新數(shù)據(jù)6");
return virtualData;
}
//在doInBackground后面執(zhí)行
@Override
protected void onPostExecute(ArrayList<String> result) {
data.addAll(result);//這個(gè)是往后添加數(shù)據(jù)
adapter.notifyDataSetChanged();
listview.onFootLoadingComplete();//完成上拉刷新,就是底部加載完畢,這個(gè)方法要調(diào)用
//移除footer,這個(gè)動(dòng)作不能少
listview.removeFooterView(footer);
super.onPostExecute(result);
}
}.execute();
}
});
}
}下面上listview的代碼,有點(diǎn)長...
/**
* 支持下拉刷新和上拉刷新
* 可自定義上啦和下拉過程的操作,推薦使用AsyncTask
* 需自定義Foot的View,然后只需在addFoot方法中添加即可
* @author lxj
*
*/
public class CustomListView extends ListView implements OnScrollListener {
private static final int DONE = 0;
private static final int PULL_TO_REFRESH = 1;
private static final int RELEASE_TO_REFRESH = 2;
private static final int REFRESHING = 3;
private static final float RATIO = 3;// 用來設(shè)置實(shí)際間距和上邊距之間的比例
private int state;// 當(dāng)前下拉刷新的狀態(tài)
private int firstVisibleIndex;// 在listview中第一個(gè)可以看見的item
private View headView;
private ImageView headArrow;
private ProgressBar progressBar;
private TextView headTitle;
private TextView headLastUpdate;
private int headContentWidth;
private int headContentHeight;
private Animation animation;
private Animation reverseAnimation;
private OnRefreshListner refreshListner;// 刷新監(jiān)聽器
private boolean isRefreshable;
private boolean isRecored = false;// 用來記錄第一次按下坐標(biāo)點(diǎn),在整個(gè)滑動(dòng)的過程中 只記錄一次
private float startY;
private boolean isBack = false;// 是從 松開刷新狀態(tài) 來到的 下拉刷新狀態(tài)
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
// listview 設(shè)置滑動(dòng)時(shí)緩沖背景色
setCacheColorHint(0x00000000);
headView = View.inflate(context, R.layout.head, null);
headArrow = (ImageView) headView.findViewById(R.id.head_arrow);
progressBar = (ProgressBar) headView.findViewById(R.id.progressbar);
headTitle = (TextView) headView.findViewById(R.id.head_title);
headLastUpdate = (TextView) headView
.findViewById(R.id.head_last_update);
headArrow.setMinimumWidth(50);
headArrow.setMinimumHeight(70);
MeasureView(headView);
headContentWidth = headView.getMeasuredWidth();
headContentHeight = headView.getMeasuredHeight();
headView.setPadding(0, -1*headContentHeight, 0, 0);
// 為listView加入頂部View
addHeaderView(headView);
setOnScrollListener(this);
animation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(250);
animation.setFillAfter(true);// 設(shè)定動(dòng)畫結(jié)束時(shí),停留在動(dòng)畫結(jié)束位置 (保留動(dòng)畫效果)
animation.setInterpolator(new LinearInterpolator());// 勻速變化
reverseAnimation = new RotateAnimation(0, -180,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);// 設(shè)定動(dòng)畫結(jié)束時(shí),停留在動(dòng)畫結(jié)束位置 (保留動(dòng)畫效果)
reverseAnimation.setInterpolator(new LinearInterpolator());// 勻速變化
// 設(shè)置當(dāng)前headView的狀態(tài)
state = DONE;
// 設(shè)置當(dāng)前下拉刷新是否可用
isRefreshable = false;
}
/**
* 測量headView的 寬高
*
* @param child
*/
private void MeasureView(View child) {
ViewGroup.LayoutParams lp = child.getLayoutParams();
if (null == lp) {
lp = new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
}
int measureChildWidth = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
int measureChildHeight;
if (lp.height > 0) {
measureChildHeight = MeasureSpec.makeMeasureSpec(lp.height,
MeasureSpec.EXACTLY);
} else {
measureChildHeight = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(measureChildWidth, measureChildHeight);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleIndex == 0 && !isRecored) {
startY = event.getY();
isRecored = true;
}
break;
case MotionEvent.ACTION_MOVE:
float tempY = event.getY();
if (firstVisibleIndex == 0 && !isRecored) {
startY = tempY;
isRecored = true;
}
if (state != REFRESHING) {
if (state == PULL_TO_REFRESH) {
// 向下拉了 從下拉刷新的狀態(tài) 來到 松開刷新的狀態(tài)
if ((tempY - startY) / RATIO >= headContentHeight
&& (tempY - startY) > 0) {
state = RELEASE_TO_REFRESH;
changeHeadViewOfState();
}
// 向上推了 從下拉刷新的狀態(tài) 來到 刷新完成的狀態(tài)
else if ((tempY - startY) <= 0) {
state = DONE;
changeHeadViewOfState();
}
} else if (state == RELEASE_TO_REFRESH) {
// 向上推了 還沒有完全將HEADVIEW 隱藏掉(可以看到一部分)
// 從松開刷新的狀態(tài) 來到 下拉刷新的狀態(tài)
if ((tempY - startY) / RATIO < headContentHeight
&& (tempY - startY) > 0) {
state = PULL_TO_REFRESH;
changeHeadViewOfState();
isBack = true;
}
// 向上推了 一下子推到了最上面 從松開刷新的狀態(tài) 來到 刷新完成的狀態(tài) (數(shù)據(jù)不刷新的)
else if ((tempY - startY) <= 0) {
state = DONE;
changeHeadViewOfState();
}
} else if (state == DONE) {
// 刷新完成的狀態(tài) 來到 下拉刷新的狀態(tài)
if ((tempY - startY) > 0) {
state = PULL_TO_REFRESH;
changeHeadViewOfState();
}
}
if (state == PULL_TO_REFRESH) {
headView.setPadding(
0,
(int) ((tempY - startY) / RATIO - headContentHeight),
0, 0);
}
if (state == RELEASE_TO_REFRESH) {
headView.setPadding(
0,
(int) ((tempY - startY) / RATIO - headContentHeight),
0, 0);
}
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING) {
if (state == PULL_TO_REFRESH) {
// 松手
state = DONE;
changeHeadViewOfState();
}
else if (state == RELEASE_TO_REFRESH) {
// 松手
state = REFRESHING;
changeHeadViewOfState();
// 執(zhí)行數(shù)據(jù)刷新方法
onRefresh();
}
}
isRecored = false;
isBack = false;
break;
}
return super.onTouchEvent(event);
}
/**
* 執(zhí)行下拉刷新
*/
private void onRefresh() {
if (refreshListner != null) {
refreshListner.onRefresh();
}
}
/**
* HeadView的狀態(tài)變化效果
*/
private void changeHeadViewOfState() {
//
switch (state) {
case PULL_TO_REFRESH:
headArrow.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
headTitle.setVisibility(View.VISIBLE);
headLastUpdate.setVisibility(View.VISIBLE);
headArrow.clearAnimation();
headTitle.setText("下拉可以刷新");
//由 松開刷新 到 下拉刷新
if(isBack){
headArrow.startAnimation(animation);
isBack = false;
}
break;
case RELEASE_TO_REFRESH:
headArrow.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
headTitle.setVisibility(View.VISIBLE);
headLastUpdate.setVisibility(View.VISIBLE);
headArrow.clearAnimation();
headArrow.startAnimation(reverseAnimation);
headTitle.setText("松開可以刷新");
break;
case REFRESHING:
headArrow.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
headTitle.setVisibility(View.VISIBLE);
headLastUpdate.setVisibility(View.VISIBLE);
headArrow.clearAnimation();
headTitle.setText("正在刷新...");
headView.setPadding(0, 0, 0, 0);
break;
case DONE:
headArrow.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
headTitle.setVisibility(View.VISIBLE);
headLastUpdate.setVisibility(View.VISIBLE);
headArrow.clearAnimation();
headTitle.setText("下拉可以刷新");
headView.setPadding(0, -1 * headContentHeight, 0, 0);
break;
}
}
private int lastPos;//最后一個(gè)可見的item的位置
private int count;//item總數(shù),注意不是當(dāng)前可見的item總數(shù)
private boolean hasFoot = false;//是否有了Foot
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
firstVisibleIndex = firstVisibleItem;
lastPos = getLastVisiblePosition();
count = totalItemCount;
//因?yàn)閯傔M(jìn)入的時(shí)候,lastPos=-1,count=0,這個(gè)時(shí)候不能讓它執(zhí)行onAddFoot方法
if(lastPos==count-1 && !hasFoot && lastPos != -1){
hasFoot = true;
onAddFoot();
Log.d("addFoot================","執(zhí)行添加Foot....");
}
Log.d("count================", count+"");
Log.d("lastPos================", lastPos+"");
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(isFootLoading)
return;
if(hasFoot && scrollState==SCROLL_STATE_IDLE){
isFootLoading = true;
onFootLoading();
}
}
/**
* 設(shè)置下拉刷新監(jiān)聽
*
* @param listener
*/
public void setOnRefreshListner(OnRefreshListner listener) {
// 設(shè)置下拉刷新可用
isRefreshable = true;
refreshListner = listener;
}
//執(zhí)行底部加載
public void onFootLoading(){
if(footLoadingListener!=null && isFootLoading)
footLoadingListener.onFootLoading();
}
public void setOnAddFootListener(OnAddFootListener addFootListener){
onAddFootListener = addFootListener;
}
//執(zhí)行添加foot
public void onAddFoot(){
if(onAddFootListener!=null && hasFoot)
onAddFootListener.addFoot();
}
//是否添加Foot的監(jiān)聽器,如果寫在OnFootLoadingListener中會(huì)有延遲,效果不好
//應(yīng)該是先進(jìn)入添加Foot的狀態(tài),再進(jìn)入FootLoading的狀態(tài)
public OnAddFootListener onAddFootListener;
//是否進(jìn)入從底部加載數(shù)據(jù)的狀態(tài)的監(jiān)聽器
public OnFootLoadingListener footLoadingListener;
//正在加載底部數(shù)據(jù)
private boolean isFootLoading = false;
public void setOnFootLoadingListener(OnFootLoadingListener footLoading){
footLoadingListener = footLoading;
}
/**
* 下拉刷新監(jiān)聽器
* @author lxj
*
*/
public interface OnRefreshListner {
/**
* 下拉刷新的時(shí)候,在這里執(zhí)行獲取數(shù)據(jù)的過程
*/
void onRefresh();
}
/**
* 上拉刷新監(jiān)聽器
* @author lxj
*
*/
public interface OnFootLoadingListener{
/**
* 這里是執(zhí)行后臺(tái)獲取數(shù)據(jù)的過程
*/
void onFootLoading();
}
/**
* 添加Foot的監(jiān)聽器
* @author lxj
*
*/
public interface OnAddFootListener{
/**
* 這里是用戶addFootView的操作
*/
void addFoot();
}
/**
* 底部數(shù)據(jù)加載完成,用戶需要加入一個(gè)removeFootView的操作
*/
public void onFootLoadingComplete(){
hasFoot = false;
isFootLoading = false;
}
/**
* 上拉刷新完成時(shí) 所執(zhí)行的操作,更改狀態(tài),隱藏head
*/
public void onRefreshComplete() {
state = DONE;
changeHeadViewOfState();
headLastUpdate.setText("最后刷新時(shí)間: " + new Date().toLocaleString());
}
@Override
public void setAdapter(ListAdapter adapter) {
headLastUpdate.setText("最后刷新時(shí)間: " + new Date().toLocaleString());
super.setAdapter(adapter);
}
}下面是布局文件:
main.xml
<?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="fill_parent" android:orientation="vertical" > <com.test.custom.CustomListView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/listview" /> </LinearLayout>
head.xml
<?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:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true" >
<ImageView
android:id="@+id/head_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/arrow" />
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:id="@+id/head_title"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉可以刷新" android:textColor="#666666" android:textSize="20sp" /> <TextView android:id="@+id/head_last_update" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:text="最后更新時(shí)間:" android:textColor="#666666" android:textSize="10sp" /> </LinearLayout> </RelativeLayout> </LinearLayout>
footer.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:gravity="center" > <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="10dip" android:text="正在加載中..." android:textSize="20sp"/> </LinearLayout>
本著一條龍服務(wù)的原則, 下面連箭頭圖片都給你搞上...
箭頭就在前面那個(gè)空格區(qū)域(3個(gè)點(diǎn)的后面),暈啊,
箭頭是白色的看不到,,,你在那里用鼠標(biāo)拖一下就出來了,或者到我空間相冊下載....
文章名稱:自定義listview,支持上拉下拉刷新,自帶demo.
網(wǎng)頁URL:http://chinadenli.net/article14/gsjede.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站、Google、營銷型網(wǎng)站建設(shè)、全網(wǎng)營銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)