Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android listview上拉加載,下拉刷新

android listview上拉加載,下拉刷新

編輯:關於Android編程

listview是開發中必見的功能應用,各種需求也不盡相同,今天給大家一個帶來一個簡單方便的自定義listview,希望對大家有幫助,閒話不說,先上幾張效果圖
1、功能示例圖

效果就是這樣
2、這個是頭部的xml,名稱listview_header如下




    <framelayout android:layout_height="wrap_content" android:layout_margin="10dip" android:layout_width="wrap_content">

        

        
    </framelayout>

    

        

        
    

**這個是底部的xml,名稱是listview_foote




    

        

        
    

自定義的進度條 common_progress




    
        
    

3、下面是調用的例子**

package com.example.administrator.mymenu.refresh;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.administrator.mymenu.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016-11-9.
 */
public class RefreshTestActivity extends Activity implements OnRefreshListener{
    private List textList;
    private MyAdapter adapter;
    private RefreshListView rListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.refuri);

        rListView = (RefreshListView) findViewById(R.id.refreshlistview);
        textList = new ArrayList();
        for (int i = 0; i < 15; i++) {
            textList.add("列表" + i);
        }
        adapter = new MyAdapter();
        rListView.setAdapter(adapter);
        rListView.setOnRefreshListener(this);
    }

    private class MyAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return textList.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return textList.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            TextView textView = new TextView(RefreshTestActivity.this);
            textView.setText(textList.get(position));
            textView.setTextColor(Color.BLACK);
            textView.setTextSize(18.0f);
            return textView;
        }

    }
    /**
     * 下拉刷新
     */
    @Override
    public void onDownPullRefresh() {
        new AsyncTask() {

            @Override
            protected Void doInBackground(Void... params) {
                SystemClock.sleep(1000);
                for (int i = 5; i > 0; i--) {
                    textList.add(0, "刷新數據" + i);
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                adapter.notifyDataSetChanged();
                rListView.hideHeaderView();
            }
        }.execute(new Void[]{});
    }
    /**
     * 上拉加載更多
     */
    @Override
    public void onLoadingMore() {
        new AsyncTask() {

            @Override
            protected Void doInBackground(Void... params) {
                SystemClock.sleep(2000);

                for (int i = 0; i < 5; i++) {
                    textList.add("更多數據" + i);
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                adapter.notifyDataSetChanged();
                // 控制腳布局隱藏
                rListView.hideFooterView();
            }
        }.execute(new Void[]{});
    }
}

4自定義listview類,可以直接用

package com.example.administrator.mymenu.refresh;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.administrator.mymenu.R;

import java.text.SimpleDateFormat;

/**
 * Created by Administrator on 2016-11-9.
 */
public class RefreshListView extends ListView implements AbsListView.OnScrollListener{
    private static final String TAG = "RefreshListView";
    private int firstVisibleItemPosition; // 屏幕顯示在第一個的item的索引
    private int downY; // 按下時y軸的偏移量
    private int headerViewHeight; // 頭布局的高度
    private View headerView; // 頭布局的對象

    private final int DOWN_PULL_REFRESH = 0; // 下拉刷新狀態
    private final int RELEASE_REFRESH = 1; // 松開刷新
    private final int REFRESHING = 2; // 正在刷新中
    private int currentState = DOWN_PULL_REFRESH; // 頭布局的狀態: 默認為下拉刷新狀態

    private Animation upAnimation; // 向上旋轉的動畫
    private Animation downAnimation; // 向下旋轉的動畫

    private ImageView ivArrow; // 頭布局的剪頭
    private ProgressBar mProgressBar; // 頭布局的進度條
    private TextView tvState; // 頭布局的狀態
    private TextView tvLastUpdateTime; // 頭布局的最後更新時間

    private OnRefreshListener mOnRefershListener;
    private boolean isScrollToBottom; // 是否滑動到底部
    private View footerView; // 腳布局的對象
    private int footerViewHeight; // 腳布局的高度
    private boolean isLoadingMore = false; // 是否正在加載更多中

    public RefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initHeaderView();
        initFooterView();
        this.setOnScrollListener(this);
    }

    /**
     * 初始化腳布局
     */
    private void initFooterView() {
        footerView = View.inflate(getContext(), R.layout.listview_footer, null);
        footerView.measure(0, 0);
        footerViewHeight = footerView.getMeasuredHeight();
        footerView.setPadding(0, -footerViewHeight, 0, 0);
        this.addFooterView(footerView);
    }

    /**
     * 初始化頭布局
     */
    private void initHeaderView() {
        headerView = View.inflate(getContext(), R.layout.listview_header, null);
        ivArrow = (ImageView) headerView
                .findViewById(R.id.iv_listview_header_arrow);
        mProgressBar = (ProgressBar) headerView
                .findViewById(R.id.pb_listview_header);
        tvState = (TextView) headerView
                .findViewById(R.id.tv_listview_header_state);
        tvLastUpdateTime = (TextView) headerView
                .findViewById(R.id.tv_listview_header_last_update_time);

        // 設置最後刷新時間
        tvLastUpdateTime.setText("更新於: " + getLastUpdateTime());

        headerView.measure(0, 0); // 系統會幫我們測量出headerView的高度
        headerViewHeight = headerView.getMeasuredHeight();
        headerView.setPadding(0, -headerViewHeight, 0, 0);
        this.addHeaderView(headerView); // 向ListView的頂部添加一個view對象
        initAnimation();
    }

    /**
     * 獲得系統的最新時間
     *
     * @return
     */
    private String getLastUpdateTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(System.currentTimeMillis());
    }

    /**
     * 初始化動畫
     */
    private void initAnimation() {
        upAnimation = new RotateAnimation(0f, -180f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        upAnimation.setDuration(500);
        upAnimation.setFillAfter(true); // 動畫結束後, 停留在結束的位置上

        downAnimation = new RotateAnimation(-180f, -360f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        downAnimation.setDuration(500);
        downAnimation.setFillAfter(true); // 動畫結束後, 停留在結束的位置上
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN :
                downY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE :
                int moveY = (int) ev.getY();
                // 移動中的y - 按下的y = 間距.
                int diff = (moveY - downY) / 2;
                // -頭布局的高度 + 間距 = paddingTop
                int paddingTop = -headerViewHeight + diff;
                // 如果: -頭布局的高度 > paddingTop的值 執行super.onTouchEvent(ev);
                if (firstVisibleItemPosition == 0
                        && -headerViewHeight < paddingTop) {
                    if (paddingTop > 0 && currentState == DOWN_PULL_REFRESH) { // 完全顯示了.
                        Log.i(TAG, "松開刷新");
                        currentState = RELEASE_REFRESH;
                        refreshHeaderView();
                    } else if (paddingTop < 0
                            && currentState == RELEASE_REFRESH) { // 沒有顯示完全
                        Log.i(TAG, "下拉刷新");
                        currentState = DOWN_PULL_REFRESH;
                        refreshHeaderView();
                    }
                    // 下拉頭布局
                    headerView.setPadding(0, paddingTop, 0, 0);
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP :
                // 判斷當前的狀態是松開刷新還是下拉刷新
                if (currentState == RELEASE_REFRESH) {
                    Log.i(TAG, "刷新數據.");
                    // 把頭布局設置為完全顯示狀態
                    headerView.setPadding(0, 0, 0, 0);
                    // 進入到正在刷新中狀態
                    currentState = REFRESHING;
                    refreshHeaderView();

                    if (mOnRefershListener != null) {
                        mOnRefershListener.onDownPullRefresh(); // 調用使用者的監聽方法
                    }
                } else if (currentState == DOWN_PULL_REFRESH) {
                    // 隱藏頭布局
                    headerView.setPadding(0, -headerViewHeight, 0, 0);
                }
                break;
            default :
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 根據currentState刷新頭布局的狀態
     */
    private void refreshHeaderView() {
        switch (currentState) {
            case DOWN_PULL_REFRESH : // 下拉刷新狀態
                tvState.setText("下拉刷新");
                ivArrow.startAnimation(downAnimation); // 執行向下旋轉
                break;
            case RELEASE_REFRESH : // 松開刷新狀態
                tvState.setText("松開刷新");
                ivArrow.startAnimation(upAnimation); // 執行向上旋轉
                break;
            case REFRESHING : // 正在刷新中狀態
                ivArrow.clearAnimation();
                ivArrow.setVisibility(View.GONE);
                mProgressBar.setVisibility(View.VISIBLE);
                tvState.setText("正在刷新中...");
                break;
            default :
                break;
        }
    }

    /**
     * 當滾動狀態改變時回調
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

        if (scrollState == SCROLL_STATE_IDLE
                || scrollState == SCROLL_STATE_FLING) {
            // 判斷當前是否已經到了底部
            if (isScrollToBottom && !isLoadingMore) {
                isLoadingMore = true;
                // 當前到底部
                Log.i(TAG, "加載更多數據");
                footerView.setPadding(0, 0, 0, 0);
                this.setSelection(this.getCount());

                if (mOnRefershListener != null) {
                    mOnRefershListener.onLoadingMore();
                }
            }
        }
    }

    /**
     * 當滾動時調用
     *
     * @param firstVisibleItem
     *            當前屏幕顯示在頂部的item的position
     * @param visibleItemCount
     *            當前屏幕顯示了多少個條目的總數
     * @param totalItemCount
     *            ListView的總條目的總數
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        firstVisibleItemPosition = firstVisibleItem;

        if (getLastVisiblePosition() == (totalItemCount - 1)) {
            isScrollToBottom = true;
        } else {
            isScrollToBottom = false;
        }
    }

    /**
     * 設置刷新監聽事件
     *
     * @param listener
     */
    public void setOnRefreshListener(OnRefreshListener listener) {
        mOnRefershListener = listener;
    }

    /**
     * 隱藏頭布局
     */
    public void hideHeaderView() {
        headerView.setPadding(0, -headerViewHeight, 0, 0);
        ivArrow.setVisibility(View.VISIBLE);
        mProgressBar.setVisibility(View.GONE);
        tvState.setText("下拉刷新");
        tvLastUpdateTime.setText("更新於: " + getLastUpdateTime());
        currentState = DOWN_PULL_REFRESH;
    }

    /**
     * 隱藏腳布局
     */
    public void hideFooterView() {
        footerView.setPadding(0, -footerViewHeight, 0, 0);
        isLoadingMore = false;
    }
}

自此結束,歡迎大家多多交流

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved