• ListView下拉刷新及上拉加载更多


    ①、定义HeaderView

    package com.exi.oa.activity.widget.list;
    
    import com.exi.oa.R;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.RotateAnimation;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    public class HeaderView extends LinearLayout{
        
        /*定义HeaderView状态*/
        public final static int STATE_NORMAL = 0;
        public final static int STATE_WILL_RELEASE = 1;
        public final static int STATE_REFRESHING = 2;
        private int defaultState = STATE_NORMAL;
        
        /*定义HeaderView需要的组件*/
        private View headerView = null;
        private ImageView ivArrow = null;
        private ProgressBar pBar = null;
        private TextView refreshTips = null;
        
        /*定义滑动动画*/
        private RotateAnimation upRa = null;
        private RotateAnimation downRa = null;
        private final static int ROTATE_DURATION = 250;
        
        public HeaderView(Context context){
            this(context,null);
        }
        
        public HeaderView(Context context, AttributeSet attrs){
            super(context, attrs);
            initHeaderView(context);
        }
        
        /*初始化HeaderView*/
        private void initHeaderView(Context context){
            LinearLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, 0);
            headerView = LayoutInflater.from(context).inflate(R.layout.refresh_header, null);
            addView(headerView,lp);
            setGravity(Gravity.BOTTOM);
            
            ivArrow = (ImageView)findViewById(R.id.ivArrow);
            pBar = (ProgressBar)findViewById(R.id.pbWaiting);
            refreshTips = (TextView)findViewById(R.id.refresh_tips);
            
            upRa = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            upRa.setDuration(ROTATE_DURATION);
            upRa.setFillAfter(true);
            
            downRa = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            downRa.setDuration(ROTATE_DURATION);
            downRa.setFillAfter(true);
        }
        
        /*设置HeaderView状态*/
        public void setHeaderState(int state){
            if(defaultState == state){
                return;
            }
            
            ivArrow.clearAnimation();
            if(state == STATE_REFRESHING){
                pBar.setVisibility(View.VISIBLE);
                ivArrow.setVisibility(View.GONE);
            }else{
                pBar.setVisibility(View.GONE);
                ivArrow.setVisibility(View.VISIBLE);
            }
            
            switch (state) {
            case STATE_NORMAL:
                ivArrow.startAnimation(downRa);
                refreshTips.setText(R.string.pull_down_for_refresh);
                break;
                
            case STATE_WILL_RELEASE:
                ivArrow.startAnimation(upRa);
                refreshTips.setText(R.string.release_for_refresh);
                break;
                
            case STATE_REFRESHING:
                refreshTips.setText(R.string.refreshing);
                break;
    
            default:
                break;
            }
            
            defaultState = state;
        }
        
        public int getCurrentState(){
            return defaultState;
        }
        
        public void setHeaderHeight(int height){
            if(height <= 0){
                height = 0;
            }
            LayoutParams lp = (LayoutParams)headerView.getLayoutParams();
            lp.height = height;
            headerView.setLayoutParams(lp);
        }
        
        public int getHeaderHeight(){
            return headerView.getHeight();
        }
        
    }

      

    HeaderView布局代码

    <?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="wrap_content"
        android:background="#ffffff"
        android:gravity="bottom">
        
        <RelativeLayout 
            android:id="@+id/header_content"
            android:layout_width="match_parent"
            android:layout_height="60dip">
            
            <LinearLayout 
                android:id="@+id/layoutTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:gravity="center"
                android:orientation="vertical">
                
                <TextView 
                    android:id="@+id/refresh_tips"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="15sp"
                    android:text="@string/pull_down_for_refresh"/>
                
                <LinearLayout 
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:layout_marginTop="4dip">
                    
                    <TextView 
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="12sp"
                        android:text="@string/label_update"/>
                    <TextView 
                        android:id="@+id/refresh_last_time"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="12sp"
                        android:text="@string/label_last_time"/>
                    
                </LinearLayout>
                
            </LinearLayout>
            
            <ImageView 
                android:id="@+id/ivArrow"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_toLeftOf="@id/layoutTitle"
                android:layout_centerInParent="true"
                android:layout_marginRight="30dip"
                android:contentDescription="@string/image_desc"
                android:src="@drawable/refresh_arrow_down"/>
            
            <ProgressBar 
                android:id="@+id/pbWaiting"
                android:visibility="gone"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_toLeftOf="@id/layoutTitle"
                android:layout_centerInParent="true"
                android:layout_marginRight="30dip"
                style="?android:attr/progressBarStyleSmall"/>
    
        </RelativeLayout>
    
    </LinearLayout>


    ②、定义FooterView

    package com.exi.oa.activity.widget.list;
    
    import com.exi.oa.R;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.RotateAnimation;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    public class FooterView extends LinearLayout{
        
        /*定义FooterView显示项*/
        public final static int FOOTER_OPTIONS_PULL = 0;
        public final static int FOOTER_OPTIONS_CLICK = 1;
        private static int defaultOptions = FOOTER_OPTIONS_CLICK;
        
        /*定义FooterView状态*/
        public final static int STATE_NORMAL = 0;
        public final static int STATE_WILL_RESEALE = 1;
        public final static int STATE_LOADING = 2;
        private static int defaultState = STATE_NORMAL;
        
        /*定义FooterView需要的组件*/
        private View footerView = null;
        private ImageView ivArrow = null;
        private ProgressBar pBar = null;
        private TextView loaderTips = null;
        
        /*定义上下拉动画*/
        private RotateAnimation upRa = null;
        private RotateAnimation downRa = null;
        private final static int ROTATE_DURATION = 250;
    
        public FooterView(Context context) {
            this(context,null);
        }
        
        public FooterView(Context context,AttributeSet atts){
            super(context,atts);
            initFooterView(context);
        }
        
        /*初始化视图*/
        private void initFooterView(Context context){
            LinearLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, 0);
            footerView = LayoutInflater.from(context).inflate(R.layout.loader_footer, null);
            this.addView(footerView,lp);
            
            ivArrow = (ImageView)footerView.findViewById(R.id.ivLoaderArrow);
            pBar = (ProgressBar)footerView.findViewById(R.id.pbLoaderWaiting);
            loaderTips = (TextView)footerView.findViewById(R.id.loader_tips);
            
            downRa = new RotateAnimation(0.0f, 180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            downRa.setDuration(ROTATE_DURATION);
            downRa.setFillAfter(true);
            
            upRa = new RotateAnimation(180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            upRa.setDuration(ROTATE_DURATION);
            upRa.setFillAfter(true);
            
            setFooterViewOptions(FOOTER_OPTIONS_CLICK);
        }
        
        /*设置footerView项*/
        public void setFooterViewOptions(int options){
            defaultOptions = options;
            
            switch (defaultOptions) {
            case FOOTER_OPTIONS_PULL:
                hide();
                break;
                
            case FOOTER_OPTIONS_CLICK:
                show();
                break;
    
            default:
                break;
            }
        }
        
        /*获取footerView的项*/
        public int getFooterViewOptions(){
            return defaultOptions;
        }
        
        /*设置footerview状态*/
        public void setFooterSate(int state){
            if(this.defaultState == state){
                return;
            }
            
            ivArrow.clearAnimation();
            if(state == STATE_LOADING){
                pBar.setVisibility(View.VISIBLE);
                ivArrow.setVisibility(View.GONE);
            }else{
                pBar.setVisibility(View.GONE);
                ivArrow.setVisibility(View.VISIBLE);
            }
            
            switch (state) {
            case STATE_NORMAL:
                ivArrow.startAnimation(upRa);
                loaderTips.setText(R.string.pull_up_for_more);
                break;
                
            case STATE_WILL_RESEALE:
                ivArrow.startAnimation(downRa);
                loaderTips.setText(R.string.release_for_more);
                break;
                
            case STATE_LOADING:
                loaderTips.setText(R.string.loading);
                break;
    
            default:
                break;
            }
            defaultState = state;
        }
        
        /*获取footerView当前状态*/
        public int getCurrentState(){
            return defaultState;
        }
        
        /*设置footerView的高度*/
        public void setFooterHeight(int height){
            if(height <= 0){
                height = 0;
            }
            
            LayoutParams lp = (LayoutParams)footerView.getLayoutParams();
            lp.height = height;
            footerView.setLayoutParams(lp);
        }
        
        /*获取footerView的高度*/
        public int getFooterHeight(){
            return footerView.getHeight();
        }
        
        /*隐藏*/
        public void hide(){
            ivArrow.clearAnimation();
            ivArrow.setVisibility(View.VISIBLE);
            loaderTips.setText(R.string.pull_up_for_more);
            setFooterHeight(0);
        }
        
        /*显示*/
        public void show(){
            ivArrow.clearAnimation();
            ivArrow.setVisibility(View.GONE);
            loaderTips.setText(R.string.click_for_more);
            
            LayoutParams lp = (LayoutParams)footerView.getLayoutParams();
            lp.height = LayoutParams.WRAP_CONTENT;
            footerView.setLayoutParams(lp);
        }
    }


    FooterView布局文件

    <?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="wrap_content"
        android:gravity="top"
        android:background="#ffffff" >
    
        <RelativeLayout
            android:id="@+id/footer_content"
            android:layout_width="match_parent"
            android:layout_height="60dip" >
    
            <TextView
                android:id="@+id/loader_tips"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="@string/pull_up_for_more"
                android:textSize="15sp" />
    
            <ImageView
                android:id="@+id/ivLoaderArrow"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginRight="30dip"
                android:layout_toLeftOf="@id/loader_tips"
                android:contentDescription="@string/image_desc"
                android:src="@drawable/refresh_arrow_up" />
    
            <ProgressBar
                android:id="@+id/pbLoaderWaiting"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginRight="30dip"
                android:layout_toLeftOf="@id/loader_tips"
                android:visibility="gone" />
        </RelativeLayout>
    
    </LinearLayout>


    ③、定义ListView

    package com.exi.oa.activity.widget.list;
    
    import com.exi.oa.R;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewTreeObserver.OnGlobalLayoutListener;
    import android.view.animation.DecelerateInterpolator;
    import android.widget.AbsListView;
    import android.widget.ListAdapter;
    import android.widget.ListView;
    import android.widget.RelativeLayout;
    import android.widget.Scroller;
    import android.widget.AbsListView.OnScrollListener;
    
    public class TaskListView extends ListView implements OnScrollListener{
        
        /*定义HeaderView*/
        private HeaderView headerView = null;
        private RelativeLayout headerContent = null;
        private int headerHeight = 0;
        
        /*定义FooterView*/
        private FooterView footerView = null;
        private RelativeLayout footerContent = null;
        private int footerHeight = 0;
        
        private final static int SCROLL_HEADER = 0;
        private final static int SCROLL_FOOTER = 1;
        private int defaultScrollWhich = SCROLL_FOOTER;
        
        private Scroller scroller = null;
        private final static float OFFSET_Y = 0.7F;
        private float iLastY = 0;
        private int totalNumber = 0;
        
        private OnLoaderListener loaderListener;
    
        public TaskListView(Context context) {
            this(context, null, 0);
        }
        
        public TaskListView(Context context,AttributeSet attrs){
            this(context, attrs, 0);
        }
        
        public TaskListView(Context context,AttributeSet attrs,int defStyle){
            super(context,attrs,defStyle);
            initView(context);
        }
        
        private void initView(Context context){
            scroller = new Scroller(context, new DecelerateInterpolator());
            super.setOnScrollListener(this);
            
            initFooterView(context);
            //initHeaderView(context);
        }
        
        /*重写设置适配器方法*/
        @Override
        public void setAdapter(ListAdapter adapter) {
            if(getFooterViewsCount() == 0){
                addFooterView(footerView);
            }
            super.setAdapter(adapter);
        }
        
        /*重写触屏事件的回调方法*/
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
            
            case MotionEvent.ACTION_DOWN:   //当屏幕被按下时
                iLastY = ev.getY();
                break;
                
            case MotionEvent.ACTION_MOVE:   //当在屏幕中滑动时
                float deltaY = ev.getY() - iLastY;
                iLastY = ev.getY();
                /*if(canHeaderPull() && getFirstVisiblePosition() == 0
                        && (deltaY > 0 || headerView.getHeaderHeight() > 0)){
                    updateHeaderState(deltaY * OFFSET_Y);
                }else if(canFooterPull() && getLastVisiblePosition() == totalNumber - 1
                        && (deltaY < 0 || footerView.getFooterHeight() > 0)){
                    updateFooterState(-deltaY * OFFSET_Y);
                }*/
                if(canFooterPull() && getLastVisiblePosition() == totalNumber - 1
                        && (deltaY < 0 || footerView.getFooterHeight() > 0)){
                    updateFooterState(-deltaY * OFFSET_Y);
                }
                break;
                
            case MotionEvent.ACTION_UP:   //当屏幕被抬起时、也就是手指离开屏幕是
                /*if(getFirstVisiblePosition() == 0){
                    if(headerView.getHeaderHeight() > headerHeight){
                        headerView.setHeaderState(HeaderView.STATE_REFRESHING);
                        if(footerView.getFooterViewOptions() == FooterView.FOOTER_OPTIONS_CLICK){
                            footerView.hide();
                        }
                    }
                    resetHeader();
                }else if(getLastVisiblePosition() == totalNumber - 1){
                    if(footerView.getFooterHeight() > footerHeight){
                        footerView.setFooterSate(FooterView.STATE_LOADING);
                    }
                    resetFooter();
                }*/
                if(getLastVisiblePosition() == totalNumber - 1){
                    if(footerView.getFooterHeight() > footerHeight){
                        footerView.setFooterSate(FooterView.STATE_LOADING);
                        loader();
                    }
                    resetFooter();
                }
                break;
    
            default:
                break;
            }
            return super.onTouchEvent(ev);
        }
        
        @Override
        public void computeScroll() {
            if(scroller.computeScrollOffset()){
                /*if(defaultScrollWhich == SCROLL_HEADER){
                    headerView.setHeaderHeight(scroller.getCurrY());
                }else */
                if(defaultScrollWhich == SCROLL_FOOTER){
                    footerView.setFooterHeight(scroller.getCurrY());
                }
            }
            super.computeScroll();
        }
        
        /*
         * 滑动时获取ListView有多少个item
         * 1. 在init中,需要设置super.setOnScrollListener;
         * 2. 重载以下两个函数;
         * 3. 在onScroll中取得totalItemCount即可;
         * */
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            //滑动时触发该方法
            totalNumber = totalItemCount;
        }
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            //滑动改变时触发该方法
        }
        
        public void setOnLoaderListener(OnLoaderListener listener){
            this.loaderListener = listener;
        }
        
        public void loader(){
            if(this.loaderListener != null){
                loaderListener.onLoader();
            }
        }
        
        /*========================================================================================*/
        private boolean canHeaderPull(){
            if(footerView.getCurrentState() == FooterView.STATE_NORMAL){
                return true;
            }
            return false;
        }
        
        public boolean canFooterPull(){
            //if(headerView.getCurrentState() == HeaderView.STATE_NORMAL){
                return true;
            //}
            //return false;
        }
    
        /*==================================================Footer=================================================*/
        /*返回FooterView*/
        public FooterView getFooterView(){
            return footerView;
        }
        
        /*设置Footer模型*/
        public void setFooterMode(int options){
            footerView.setFooterViewOptions(options);
        }
        
        /*停止加载*/
        public void stopLoad(){
            if(footerView.getCurrentState() == FooterView.STATE_LOADING){
                footerView.setFooterSate(FooterView.STATE_NORMAL);
                resetFooter();
            }
        }
        
        /*初始化footerView*/
        private void initFooterView(Context context){
            footerView = new FooterView(context);
            footerContent = (RelativeLayout)footerView.findViewById(R.id.footer_content);
            footerContent.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    if(footerView.getFooterViewOptions() == FooterView.FOOTER_OPTIONS_CLICK
                            && footerView.getCurrentState() == FooterView.STATE_NORMAL){
                        footerView.setFooterSate(FooterView.STATE_LOADING);
                        loader();
                    }
                }
            });
            footerView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                
                @Override
                public void onGlobalLayout() {
                    footerHeight = footerContent.getHeight();
                    getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
            });
        }
        
        /*更新FooterView状态*/
        private void updateFooterState(float delta){
            if(footerView.getFooterViewOptions() == FooterView.FOOTER_OPTIONS_CLICK){
                return;
            }
            
            footerView.setFooterHeight((int)(delta+footerView.getFooterHeight()));
            if(footerView.getCurrentState() != FooterView.STATE_LOADING){
                if(footerView.getFooterHeight() > footerHeight){
                    footerView.setFooterSate(FooterView.STATE_WILL_RESEALE);
                }else{
                    footerView.setFooterSate(FooterView.STATE_NORMAL);
                }
            }
        }
        
        /*重置Footer*/
        private void resetFooter(){
            int height = footerView.getFooterHeight();
            if(height == 0){
                return;
            }
            
            if(footerView.getFooterViewOptions() == FooterView.FOOTER_OPTIONS_CLICK){
                return;
            }
            
            int finalHeight = 0;
            if(height > footerHeight){
                finalHeight = footerHeight;
            }else if(footerView.getCurrentState() == FooterView.STATE_LOADING){
                return;
            }
            
            defaultScrollWhich = SCROLL_FOOTER;
            scroller.startScroll(0, height, finalHeight - height, 250);
            invalidate();
        }
        
        /*==========================================Header==========================================================*/
        /*返回HeaderView
        public HeaderView getHeaderView(){
            return headerView;
        }
        停止刷新
        public void stopRefresh(){
            if(headerView.getCurrentState() == HeaderView.STATE_REFRESHING){
                headerView.setHeaderState(HeaderView.STATE_NORMAL);
                resetHeader();
                if(footerView.getFooterViewOptions() == FooterView.FOOTER_OPTIONS_CLICK){
                    footerView.show();
                }
            }
        }
        
        初始化HeaderView
        private void initHeaderView(Context context){
            headerView = new HeaderView(context);
            headerContent = (RelativeLayout)headerView.findViewById(R.id.header_content);
            addHeaderView(headerView);
            headerView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                
                @Override
                public void onGlobalLayout() {
                    headerHeight = headerContent.getHeight();
                    getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
            });
        }
        
        更新Headerview状态
        private void updateHeaderState(float delta){
            headerView.setHeaderHeight((int)(delta + headerView.getHeaderHeight()));
            if(headerView.getCurrentState() != HeaderView.STATE_REFRESHING){
                if(headerView.getHeaderHeight() > headerHeight){
                    headerView.setHeaderState(HeaderView.STATE_WILL_RELEASE);
                }else{
                    headerView.setHeaderState(HeaderView.STATE_NORMAL);
                }
            }
            setSelection(0);
        }
        
        重置Header
        private void resetHeader(){
            int height = headerView.getHeaderHeight();
            if(height == 0){
                return;
            }
            int finalHeight = 0;
            if(height > headerHeight){
                
                 * 如果超过HeaderView高度,则回滚到HeaderView高度即可
                 
                finalHeight = headerHeight;
            }else if(headerView.getCurrentState() == HeaderView.STATE_REFRESHING){
                
                 * 如果HeaderView未完全显示
                 * 1. 处于正在刷新中,则不管;
                 * 2. 回滚HeaderView当前可视高度
                 
                return;
            }
            
            defaultScrollWhich = SCROLL_HEADER;
            scroller.startScroll(0, height, 0, finalHeight, 250);
            invalidate();
        }
    */
        
        private class OnClickLoaderListener implements OnClickListener{
    
            @Override
            public void onClick(View v) {
                loader();
            }
            
        }
        
        public interface OnLoaderListener{
            
            public void onLoader();
            
        }
    }


    在ListView中定义OnLoaderListener接口作为加载数据监听器、加载数据只需实现此监听器即可

  • 相关阅读:
    安卓虚拟机adb shell sqlite3数据库
    gridview安卓实现单行多列横向滚动
    安卓gridview 网格,多行多列实现
    安卓5.0 沉浸式状态栏
    Acionbar logo
    .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app
    导航抽屉图标+文字
    透明ActionBar
    去掉Actionbar下的shadow
    沉浸式导航栏
  • 原文地址:https://www.cnblogs.com/Yang2/p/3441037.html
Copyright © 2020-2023  润新知