亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

android下拉刷新ListView的介紹和實現代碼

2020-04-11 12:27:48
字體:
來源:轉載
供稿:網友

    大致上,我們發現,下拉刷新的列表和一般列表的區別是,當滾動條在頂端的時候,再往下拉動就會把整個列表拉下來,顯示出松開刷新的提示。由此可以看出,在構建這個下拉刷新的組件的時候,只用繼承ListView,然后重寫onTouchEvent就能實現。還有就是要能在xml布局文件中引用,還需要一個參數為Context,AttributeSet的構造函數。

  表面上的功能大概就這些了。另一方面,刷新的行為似乎還沒有定義,在刷新前做什么,刷新時要做什么,刷新完成后要做什么,這些行為寫入一個接口中,然后讓組件去實現。

  在整個組件的實現中,主體部分自然是onTouchEvent的部分。這里需要做一些說明,在ListView中,數據的滾動和ListView.scrollTo的行為是不一樣的。數據的滾動是大概適配器的事。所以在不滿足下拉整個列表的條件下,onTouchEvent 應該返回super.onTouchEvent(ev),讓ListView組件原本的OnTouchEvent去處理。

  考慮到組件的id和表頭的布局需要事先定義,同時我想把這個組件應用于多個項目里,所以就把這個組件作為一個Library去實現。

     下面就是具體的實現代碼。

  首先來看一下表頭的布局文件chenzong_push_refresh_header.xml:

復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dip"
       >
    <ImageView
        android:layout_width="30dip"
        android:layout_height="40dip"
        android:background="@drawable/arrow_down"
           android:layout_alignParentLeft="true"
        android:id="@+id/push_refresh_header_img"
        android:layout_marginLeft="10dip"
        />
    <ProgressBar
        android:layout_width="40dip"
        android:layout_height="40dip"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="10dip"
        android:id="@+id/push_refresh_header_pb"
        style="@android:style/Widget.ProgressBar.Inverse"
        android:visibility="gone"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="最近一次更新在:"
            android:textColor="#000000"
            />
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:id="@+id/push_refresh_header_date"
            android:textColor="#000000"
            android:text="2013-03-04 08:03:38"/>
    </LinearLayout>
</RelativeLayout>

       箭頭、processBar和最近的一次刷新時間,表頭文件就這三個元素。

       刷新的行為接口RefreshOperation的代碼:

復制代碼 代碼如下:

public interface RefreshOperation {
    public void OnRefreshStart();
    public void OnRefreshing();
    public void OnRefreshEnd();
}

     列表拉下來時,箭頭翻轉的動畫arrow_rotate.xml:

復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:fromDegrees="0"
    android:toDegrees="180"
    android:duration="300"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fillAfter="true"
    android:repeatCount="0">

</rotate>

      這些文件和一些資源文件備齊了之后,接下來就是下拉刷新列表PushRefreshList的具體實現:

復制代碼 代碼如下:

package com.chenzong;

import java.util.Calendar;

import com.doall.pushrefreshlist.R;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.TextView;


public class PushRefreshList extends ListView implements RefreshOperation{

    private int header_layout=R.layout.chenzong_push_refresh_header;
    //表頭文件
    private int arrow_down=R.drawable.arrow_down;
    //箭頭往下的資源
    private int arrow_up=R.drawable.arrow_up;
    //箭頭往上的資源
    private int img=R.id.push_refresh_header_img;
    //顯示箭頭的控件id
    private int pb=R.id.push_refresh_header_pb;
    //刷新時的進度條
    private int startPoint=0;
    //觸摸的起始點
    private RefreshOperation refresh;
    //刷新行為的對象
    private Animation animation=null;
    private Context context;
    private View headerView;
    private int minPushHeight;

   
    private final String TAG="pushRefresh";

    public PushRefreshList(Context cotext, AttributeSet attrs) {
        super(context, attrs);
        View empty=new View(context);
        //判斷是否到列表的頂端,通常要用到this.getFirstVisiblePosition(),這里創建一個高度的為零View,加到headerView和數據之間
        this.addHeaderView(empty);
        LayoutInflater inflater=LayoutInflater.from(context);
        headerView=inflater.inflate(header_layout, null);
        this.addHeaderView(headerView);
        this.setRefreshOperation(this);
        this.context=context;

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        this.minPushHeight=headerView.getMeasuredHeight();
        //獲取下拉刷新的觸發高度
        super.onLayout(changed, l, t, r, b);
    }

    private boolean canHandleEvent(int dy)
    {
        return (dy<0&&this.getFirstVisiblePosition()==0&&!isPbVisible());
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int action=ev.getAction();
        switch(action)
        {
        case MotionEvent.ACTION_DOWN:
            startPoint=(int)ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            int dy=startPoint-(int)ev.getY();
            if(canHandleEvent(dy))
            {
                if(animation==null)
                {
                    if(Math.abs(this.getScrollY())>=this.minPushHeight)
                    {   
                        animation=AnimationUtils.loadAnimation(context, R.anim.arrow_rotate);
                        View mView=headerView.findViewById(img);
                        mView.startAnimation(animation);
                        this.setScrollbarFadingEnabled(true);
                    }
                }
                this.scrollTo(0,dy/2);   
                return true;
            }
            break;
        case MotionEvent.ACTION_UP:

                this.setScrollbarFadingEnabled(false);
                if(animation!=null)
                {
                    setImgBackgroundUp();
                    switchCompent(View.INVISIBLE,View.VISIBLE);
                    this.scrollTo(0,-minPushHeight);
                    PushRefreshList.this.refresh.OnRefreshStart();
                    new Thread(mRunnable).start();
                    animation=null;
                }
                else
                    this.scrollTo(0,0);
            break;
        }
        return super.onTouchEvent(ev);
    }

    private Runnable mRunnable=new Runnable()
    {

        @Override
        public void run() {
            PushRefreshList.this.refresh.OnRefreshing();
            mHandler.obtainMessage().sendToTarget();
        }
    };

    private Handler mHandler=new Handler()
    {
        @Override
        public void handleMessage(Message msg) {
            PushRefreshList.this.refresh.OnRefreshEnd();
            PushRefreshList.this.scrollTo(0, 0);
            PushRefreshList.this.setImgBackgroundDown();
            PushRefreshList.this.switchCompent(View.VISIBLE, View.GONE);
            TextView tv=(TextView)headerView.findViewById(R.id.push_refresh_header_date);
            tv.setText(this.getDateStr());
        }

        private String getDateStr()
        {
            Calendar ca=Calendar.getInstance();
            int year=ca.get(Calendar.YEAR);
            int month=ca.get(Calendar.MONTH);
            int date=ca.get(Calendar.DATE);
            int hour=ca.get(Calendar.HOUR);
            int mintes=ca.get(Calendar.MINUTE);
            int second=ca.get(Calendar.SECOND);
            return year+"-"+(month+1)+"-"+date+" "+hour+":"+mintes+":"+second;
        }
    };

    private void switchCompent(int imgStatus,int pbStatus)
    {
        View img=headerView.findViewById(R.id.push_refresh_header_img);
        img.clearAnimation();
        //執行了動畫的控件如果不調用clearAnimation,setVisibility(View.GONE)會失效
        img.setVisibility(imgStatus);
        headerView.findViewById(R.id.push_refresh_header_pb).setVisibility(pbStatus);
    }

    private boolean isPbVisible()
    {
        return View.VISIBLE==headerView.findViewById(R.id.push_refresh_header_pb).getVisibility();
    }

    private void setImgBackgroundUp()
    {
        View mView=headerView.findViewById(this.img);
        mView.setBackgroundResource(arrow_up);
    }

    private void setImgBackgroundDown()
    {
        View mView=headerView.findViewById(this.img);
        mView.setBackgroundResource(arrow_down);
    }

    public void setRefreshOperation(RefreshOperation refresh)
    {
        this.refresh=refresh;
    }

    @Override
    public void OnRefreshStart() {

    }

    @Override
    public void OnRefreshing() {

    }

    @Override
    public void OnRefreshEnd() {
    }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人av资源在线播放| 一区二区三区动漫| 欧美激情一区二区三区高清视频| 亚洲欧洲日产国产网站| 欧美疯狂做受xxxx高潮| 亚洲iv一区二区三区| 精品亚洲一区二区三区四区五区| 2019中文在线观看| 中文亚洲视频在线| 日韩电影网在线| 欧美日韩午夜激情| 欧美裸体xxxx极品少妇软件| 欧美在线欧美在线| 97人人做人人爱| 亚洲精品97久久| 精品露脸国产偷人在视频| 91人成网站www| 国产精品久久久av久久久| 国产午夜精品视频免费不卡69堂| 91久久精品国产91性色| 91视频-88av| 精品国产欧美一区二区五十路| 成人午夜在线影院| 欧美福利视频在线观看| 久久久精品2019中文字幕神马| 精品国偷自产在线视频| 国产日韩欧美在线视频观看| 欧美一级成年大片在线观看| 亚洲人成网站999久久久综合| 国产九九精品视频| 欧美激情视频播放| 亚洲人成在线电影| 懂色av影视一区二区三区| 日韩在线视频免费观看高清中文| 5566成人精品视频免费| 69国产精品成人在线播放| 精品久久久久久久久久久久| 亚洲精品美女免费| 精品中文字幕在线观看| 亚洲一区二区在线播放| 亚洲精品自在久久| 国产日韩在线精品av| 亚洲男人天堂网| 国产成人中文字幕| 国产日韩欧美成人| 日韩在线视频免费观看| 国产日韩精品在线| 欧美猛交ⅹxxx乱大交视频| 国产91精品黑色丝袜高跟鞋| 国产婷婷97碰碰久久人人蜜臀| 国产精品专区一| 成人黄色片在线| 亚洲视频综合网| 国产精品福利观看| 国产精品福利久久久| 亚洲男人天堂九九视频| 亚洲国产欧美自拍| 欧美日韩国产一中文字不卡| 欧美成aaa人片免费看| 成人美女免费网站视频| 精品国产户外野外| 中文字幕亚洲一区在线观看| 欧美精品videosex极品1| 欧美一性一乱一交一视频| 国产69精品久久久| 一区二区亚洲欧洲国产日韩| 91免费版网站入口| 北条麻妃一区二区在线观看| 中文字幕视频在线免费欧美日韩综合在线看| 性亚洲最疯狂xxxx高清| 亚洲福利小视频| 亚洲成年网站在线观看| 欧美成人中文字幕在线| 91精品综合久久久久久五月天| 91久久精品国产91久久性色| 成人精品网站在线观看| 国产精品扒开腿爽爽爽视频| 欧美性xxxx极品高清hd直播| 45www国产精品网站| 亚洲一区二区三区毛片| 日韩中文字幕视频在线观看| 亚洲精品视频在线播放| 日韩福利伦理影院免费| 国产精品成人av性教育| 国产成人aa精品一区在线播放| 久久成年人视频| 日韩成人免费视频| 亚洲人成在线观看| 国产在线a不卡| 日韩欧美在线观看| 亚洲乱码国产乱码精品精| 欧美性黄网官网| 久久久久久久久久久亚洲| 日韩在线观看免费全集电视剧网站| 亚洲乱码国产乱码精品精天堂| 亚洲大胆美女视频| 中文字幕亚洲无线码a| 国产精品1234| 91极品视频在线| 一区二区三区视频免费| 中文字幕少妇一区二区三区| 久久久免费电影| yw.139尤物在线精品视频| 亚洲白拍色综合图区| 国精产品一区一区三区有限在线| 97精品国产aⅴ7777| 色七七影院综合| 欧美日在线观看| 久久av中文字幕| 97国产真实伦对白精彩视频8| 欧美亚洲国产日韩2020| 91探花福利精品国产自产在线| 欧美激情综合亚洲一二区| 精品国产91久久久久久| 国产999精品| 中文字幕欧美日韩在线| 欧美极品少妇xxxxⅹ免费视频| 欧美精品日韩www.p站| 日韩高清免费观看| 91久久精品久久国产性色也91| 久久99国产综合精品女同| 国产99久久久欧美黑人| 亚洲精品永久免费| 欧美成人第一页| 中文字幕av一区| 欧美国产视频一区二区| 精品久久久91| 亚洲精品资源美女情侣酒店| 亚洲国模精品私拍| 亚洲人成电影在线观看天堂色| 亚洲娇小xxxx欧美娇小| 97视频在线观看免费高清完整版在线观看| 国产精品香蕉国产| 啪一啪鲁一鲁2019在线视频| 欧美中文字幕视频| 日韩av资源在线播放| 国产精品极品美女粉嫩高清在线| 国产精品1区2区在线观看| 亚洲xxxx18| 在线视频欧美性高潮| 久久久精品在线观看| 欧美性生交xxxxx久久久| 2019中文字幕在线| 久久综合伊人77777尤物| 一区二区三区视频在线| 国产在线a不卡| 欧美日韩亚洲视频| 亚洲国产精品va在线| 国产精品自拍偷拍| 性色av一区二区三区| 岛国av一区二区| 亚洲精品在线91| 亚洲国产欧美日韩精品| 国产在线精品播放| 欧美精品videossex性护士| 国产+人+亚洲| 亚洲视频第一页| 欧美极品少妇xxxxⅹ免费视频| 在线日韩中文字幕| 欧美激情在线视频二区| www.日韩不卡电影av| 色琪琪综合男人的天堂aⅴ视频| 这里只有精品在线观看| 色久欧美在线视频观看|