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

ListView下拉刷新,listview下拉

編輯:關於android開發

ListView下拉刷新,listview下拉


下拉刷新-------
    1.addHeaderView必須在setAdapter之前調用
    2.將paddingTop設置一個headerView高度的負值去隱藏它
    
    getHeight()和getMeasuredHeight()的區別:
    getMeasuredHeight():獲取測量完的高度,只要在onMeasure方法執行完,就可以用
                        它獲取到寬高,在自定義控件內部多使用這個
                        使用view.measure(0,0)方法可以主動通知系統去測量,然後就
                        可以直接使用它獲取寬高
    getHeight():必須在onLayout方法執行完後,才能獲得寬高
                view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                    headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    int headerViewHeight = headerView.getHeight();
                    //直接可以獲取寬高
            }
        });
    3.setSelection(position);將對應位置的item放置到屏幕頂端

 

其中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:gravity="center_horizontal" android:orientation="horizontal" > <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" > <ImageView android:id="@+id/iv_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/indicator_arrow" android:contentDescription="@null" /> <ProgressBar android:id="@+id/pb_rotate" android:layout_width="30dp" android:layout_height="30dp" android:visibility="invisible" android:layout_centerInParent="true" android:indeterminateDrawable="@drawable/indeterminate_drawable" android:indeterminateDuration="2000" /> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:layout_marginLeft="15dp" android:layout_marginTop="10dp" android:gravity="center" android:orientation="vertical" > <TextView android:id="@+id/tv_state" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉刷新" android:textColor="#aa000000" android:textSize="20sp" /> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="最後刷新:" android:textColor="@android:color/darker_gray" android:textSize="14sp" /> </LinearLayout> </LinearLayout> View Code

其中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="center" android:orientation="horizontal" > <ProgressBar android:layout_width="30dp" android:layout_height="30dp" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:indeterminate="true" android:indeterminateDrawable="@drawable/indeterminate_drawable" android:indeterminateDuration="1000" /> <TextView android:layout_width="wrap_content" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:layout_height="wrap_content" android:textColor="#aa000000" android:layout_marginLeft="15dp" android:textSize="20sp" android:text="加載更多..."/> </LinearLayout> View Code

android:indeterminateDrawable="@drawable/indeterminate_drawable"

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:drawable="@drawable/indicate_rotate"
    android:toDegrees="360">
    

</rotate>

RefreshListView的主代碼

package com.demo.pullrefresh.view;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.demo.pullrefresh.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
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 android.widget.AbsListView.OnScrollListener;

public class RefreshListView extends ListView implements OnScrollListener {

    private View headerView;// headerView
    private ImageView iv_arrow;
    private ProgressBar pb_rotate;
    private TextView tv_state, tv_time;

    private int downY;// 按下時y的坐標
    private int headerViewHeight;// headerView高

    private View footerView;
    private int footerViewHeight;

    private final int PULL_REFRESH = 0;// 下拉刷新的狀態
    private final int RELEASE_REFRESH = 1;// 松開刷新的狀態
    private final int REFRESHING = 2;// 正在刷新的狀態
    private int currentState = PULL_REFRESH;// headerView的默認位置

    private RotateAnimation upAnimation, downAnimation;
    private boolean isLoadingMore = false;// 當前是否正在處於加載更多

    public RefreshListView(Context context) {
        super(context);
        init();
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        setOnScrollListener(this);
        initHeaderView();
        initFooterView();
        initRotateAnimation();
    }

    /**
     * 初始化headerView
     */
    private void initHeaderView() {
        headerView = View.inflate(getContext(), R.layout.layout_header, null);
        // headerView
        // =LayoutInflater.from(getContext()).inflate(R.layout.layout_header,
        // null);
        iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
        pb_rotate = (ProgressBar) headerView.findViewById(R.id.pb_rotate);
        tv_state = (TextView) headerView.findViewById(R.id.tv_state);
        tv_time = (TextView) headerView.findViewById(R.id.tv_time);
        // 第一種方法
        // headerView.getViewTreeObserver().addOnGlobalLayoutListener(new
        // OnGlobalLayoutListener() {
        // @Override
        // public void onGlobalLayout() {
        // headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        // int headerViewHeight = headerView.getHeight();
        //
        //
        // Log.e("MainActivity", "headerViewHeight: "+headerViewHeight);
        // headerView.setPadding(0, -headerViewHeight, 0, 0);
        // refreshListView.addHeaderView(headerView);//
        // }
        // });
        // 第二種方法
        headerView.measure(0, 0);// 主動通知系統去測量
        headerViewHeight = headerView.getMeasuredHeight();
        Log.e("MainActivity", "headerViewHeight: " + headerViewHeight);
        headerView.setPadding(0, -headerViewHeight, 0, 0);
        addHeaderView(headerView);//
    }

    /**
     * 初始化旋轉動畫
     */
    private void initRotateAnimation() {
        upAnimation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        upAnimation.setDuration(300);
        upAnimation.setFillAfter(true);
        downAnimation = new RotateAnimation(-180, -360,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        downAnimation.setDuration(300);
        downAnimation.setFillAfter(true);
    }

    /**
     * 初始化footerView
     */
    private void initFooterView() {
        footerView = View.inflate(getContext(), R.layout.layout_footer, null);
        footerView.measure(0, 0);// 主動通知系統去測量該View
        footerViewHeight = footerView.getMeasuredHeight();
        footerView.setPadding(0, -footerViewHeight, 0, 0);
        addFooterView(footerView);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downY = (int) ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:

            int deltaY = (int) (ev.getY() - downY);
            int paddingTop = -headerViewHeight + deltaY;
            if (paddingTop > -headerViewHeight
                    && getFirstVisiblePosition() == 0) {
                headerView.setPadding(0, paddingTop, 0, 0);
                Log.d("jiejie", "paddingtop" + paddingTop);

                if (paddingTop >= 0 && currentState == PULL_REFRESH) {
                    // 從下拉刷新進入松開刷新的狀態
                    currentState = RELEASE_REFRESH;
                    refreshHeaderView();
                } else if (paddingTop < 0 && currentState == RELEASE_REFRESH) {
                    // 進入下拉刷新的狀態
                    currentState = PULL_REFRESH;
                    refreshHeaderView();
                }
                return true;// 攔截TouchMove,不讓ListView處理該次move事件,不過會造成ListView無法滑動
            }
            break;
        case MotionEvent.ACTION_UP:
            if (currentState == PULL_REFRESH) {
                // 隱藏headerView
                headerView.setPadding(0, -headerViewHeight, 0, 0);
            } else if (currentState == RELEASE_REFRESH) {
                headerView.setPadding(0, 0, 0, 0);
                currentState = REFRESHING;
                refreshHeaderView();
                if (listener != null) {
                    listener.onPullRefersh();
                }
            }
            break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 根據currentState來更新headerView
     */
    private void refreshHeaderView() {
        switch (currentState) {

        case PULL_REFRESH:
            tv_state.setText("下拉刷新");
            iv_arrow.startAnimation(downAnimation);
            break;

        case RELEASE_REFRESH:
            tv_state.setText("松開刷新");
            iv_arrow.startAnimation(upAnimation);
            break;

        case REFRESHING:
            iv_arrow.clearAnimation();// 因為向上的旋轉動畫有可能沒有執行完
            iv_arrow.setVisibility(View.INVISIBLE);
            pb_rotate.setVisibility(View.VISIBLE);
            tv_state.setText("正在刷新...");
            break;
        }

    }

    /**
     * 完成刷新操作,重置狀態,在你獲取完數據並更新完adater之後,去在UI線程中調用該方法
     */
    public void completeRefresh() {
        if (isLoadingMore) {
            // 重置footerView狀態
            footerView.setPadding(0, -footerViewHeight, 0, 0);
            isLoadingMore = false;
        } else {
            // 重置headerView狀態
            headerView.setPadding(0, -headerViewHeight, 0, 0);
            currentState = PULL_REFRESH;
            pb_rotate.setVisibility(View.INVISIBLE);
            iv_arrow.setVisibility(View.VISIBLE);
            tv_state.setText("下拉刷新");
            tv_time.setText("最後刷新:" + getCurrentTime());
        }
    }

    /**
     * 取得當前系統的時間,並格式化
     */
    @SuppressLint("SimpleDateFormat")
    private String getCurrentTime() {
        SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
        return format.format(new Date());
    }

    private OnRefreshListener listener;

    public void setOnRefreshListener(OnRefreshListener listener) {
        this.listener = listener;
    }

    public interface OnRefreshListener {
        void onPullRefersh();

        void onLoadingMore();
    }

    /**
     * SCROLL_STATE_IDLE:閒置狀態,就是手指松開 SCROLL_STATE_TOUCH_SCROLL:手指觸摸滑動,就是按著來滑動
     * SCROLL_STATE_FLING:快速滑動後松開
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
                && getLastVisiblePosition() == (getCount() - 1)
                && !isLoadingMore) {
            isLoadingMore = true;
            footerView.setPadding(0, 0, 0, 0);// 顯示footerView
            setSelection(getCount());// 讓ListView的最後一條顯示出來
            if (listener != null) {
                listener.onLoadingMore();
            }
        }
    }
}

MainActivity的主代碼

package com.demo.pullrefresh;

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

import com.demo.pullrefresh.view.RefreshListView;
import com.demo.pullrefresh.view.RefreshListView.OnRefreshListener;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnItemClickListener {
    private RefreshListView refreshListView;
    private MyAdapter adapter;

    private List<String> list ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        initView();
        initData();
    }

    private void initView() {
        // TODO Auto-generated method stub
        // requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.mainactivity);
        refreshListView = (RefreshListView) findViewById(R.id.rf_mainlistview);
    }

    private void initData() {
        list = new ArrayList<String>();
        for (int i = 0; i < 30; i++) {
            list.add("ListView原來的數據——   " + i);
        }

        adapter = new MyAdapter();
        refreshListView.setAdapter(adapter);
        refreshListView.setOnRefreshListener(new OnRefreshListener() {

            @Override
            public void onPullRefersh() {
                // TODO Auto-generated method stub
                // 需要聯網請求服務器的數據,然後更新UI
                requestDataFromServer(false);
            }

            @Override
            public void onLoadingMore() {
                // TODO Auto-generated method stub
                requestDataFromServer(true);
            }
        });
        refreshListView.setOnItemClickListener(this);
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // 跟新UI
            adapter.notifyDataSetChanged();
            refreshListView.completeRefresh();
        }

    };

    /**
     * 模擬向服務器請求數據
     * 
     * @param isLoadingMore
     */
    private void requestDataFromServer(final boolean isLoadingMore) {
        new Thread() {
            public void run() {
                SystemClock.sleep(3000);// 模擬請求服務器的一個時間長度
                Log.d("jiejie", isLoadingMore + "");
                if (isLoadingMore) {
                    list.add("加載了更多的數據  ————1");
                    list.add("加載了更多的數據  ————2");
                    list.add("加載了更多的數據  ————3");
                } else {

                }
                handler.sendEmptyMessage(0);
            };
        }.start();
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        // TODO Auto-generated method stub
        Toast.makeText(MainActivity.this, "第" + arg2 + "個條目== " + list.get(arg2-1),
                Toast.LENGTH_SHORT).show();

    }

    private class MyAdapter extends BaseAdapter {

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

        @Override
        public Object getItem(int arg0) {
            // TODO Auto-generated method stub
            return null;
        }

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

        @Override
        public View getView(int arg0, View arg1, ViewGroup arg2) {
            // TODO Auto-generated method stub
            TextView textView = new TextView(MainActivity.this);
            textView.setPadding(20, 20, 20, 20);
            textView.setTextSize(18);
            textView.setText(list.get(arg0));
            return textView;
        }

    }

}

 

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