android 上拉刷新,下拉加载更多

package com.example.testrefreshlistview;

import java.util.Date;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.view.View.OnClickListener;  

public class DropRefreshListView extends ListView implements OnScrollListener,OnClickListener
{
    // 释放状态
    public final static int RELEASE_To_REFRESH = 0;

    // 下拉到刷新状态
    public final static int PULL_To_REFRESH = 1;

    // 正在刷新
    public final static int REFRESHING = 2;

    // 刷新完成
    public final static int DONE = 3;

    //上拉加载更多
    //普通状态
    public final static int MORE_DONE = 4;
    
    //刷新状态
    public final static int MORE_REFRESHING = 5;
    


    private final static int RATIO = 3;

    // 刷新箭头的宽度
    private static final int ARROW_IMAGE_WIDTH = 70;

    // 刷新箭头的高度
    private static final int ARROW_IMAGE_HEIGHT = 50;

    private LayoutInflater inflater;

    // head xml
    private LinearLayout headView;

    private TextView tipsTextview;

    private TextView lastUpdatedTextView;

    private ImageView arrowImageView;

    private ProgressBar progressBar;

    // foot xml
    private RelativeLayout footView;

    private TextView mLoadMoreTextView;

    private RelativeLayout mLoadMoreView;

    private LinearLayout mLoadingView;

    private RotateAnimation animation;

    private RotateAnimation reverseAnimation;

    private boolean isRecored;

    // private int headContentWidth;

    private int headContentHeight;

    private int startY;

    private int firstItemIndex;

    private int state;
    
    private int loadingMoreState;

    private boolean isBack;

    private OnRefreshListener refreshListener;

    private boolean isRefreshable;
    
    public static volatile boolean isPullRefresh = true;

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

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

    /**
     * 初始化ListView
     * 
     * @param context
     */
    private void init(Context context)
    {
        // setCacheColorHint(context.getResources().getColor(R.color.transparent));
        inflater = LayoutInflater.from(context);
        headView = (LinearLayout) inflater
                .inflate(R.layout.listview_head, null);
        arrowImageView = (ImageView) headView
                .findViewById(R.id.head_arrowImageView);
        progressBar = (ProgressBar) headView
                .findViewById(R.id.head_progressBar);
        tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
        lastUpdatedTextView = (TextView) headView
                .findViewById(R.id.head_lastUpdatedTextView);

        footView = (RelativeLayout) inflater.inflate(R.layout.footer, null);

        mLoadMoreTextView = (TextView) footView.findViewById(R.id.load_more_tv);
        mLoadMoreView = (RelativeLayout) footView
                .findViewById(R.id.load_more_view);

        mLoadingView = (LinearLayout) footView
                .findViewById(R.id.loading_layout);
         
        mLoadMoreView.setOnClickListener(this);
        
        addFooterView(footView);  

        // 设定箭头大小
        arrowImageView.setMinimumWidth(ARROW_IMAGE_WIDTH);
        arrowImageView.setMinimumHeight(ARROW_IMAGE_HEIGHT);

        measureView(headView);
        headContentHeight = headView.getMeasuredHeight();
        // headContentWidth = headView.getMeasuredWidth();
        headView.setPadding(0, -1 * headContentHeight, 0, 0);
        headView.invalidate();
        addHeaderView(headView, null, false);
        setOnScrollListener(this);

        animation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        animation.setInterpolator(new LinearInterpolator());
        animation.setDuration(250);
        animation.setFillAfter(true);

        reverseAnimation = new RotateAnimation(-180, 0,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        reverseAnimation.setInterpolator(new LinearInterpolator());
        reverseAnimation.setDuration(200);
        reverseAnimation.setFillAfter(true);

        state = DONE;
        isRefreshable = false;
        
        loadingMoreState = MORE_DONE;

    }

    public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,
            int arg3)
    {
        firstItemIndex = firstVisiableItem;
    }

    public void onScrollStateChanged(AbsListView arg0, int arg1)
    {
    }

    public boolean onTouchEvent(MotionEvent event)
    {

        if (!isRefreshable)
        {
            return super.onTouchEvent(event);
        }

        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                if (firstItemIndex == 0 && !isRecored)
                {
                    isRecored = true;
                    startY = (int) event.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (state != REFRESHING)
                {
                    /*
                     * if (state == DONE) { }
                     */
                    if (state == PULL_To_REFRESH)
                    {
                        state = DONE;
                        changeHeaderViewByState();
                    }
                    if (state == RELEASE_To_REFRESH)
                    {
                        state = REFRESHING;
                        changeHeaderViewByState();
                        isPullRefresh = true;
                        onRefresh();
                    }
                }
                isRecored = false;
                isBack = false;
                break;
            case MotionEvent.ACTION_MOVE:
                int tempY = (int) event.getY();
                if (!isRecored && firstItemIndex == 0)
                {
                    isRecored = true;
                    startY = tempY;
                }
                if (state != REFRESHING && isRecored)
                {
                    if (state == RELEASE_To_REFRESH)
                    {
                        setSelection(0);
                        if (((tempY - startY) / RATIO < headContentHeight)
                                && (tempY - startY) > 0)
                        {
                            state = PULL_To_REFRESH;
                            changeHeaderViewByState();
                        }
                        else if (tempY - startY <= 0)
                        {
                            state = DONE;
                            changeHeaderViewByState();
                        }
                    }
                    if (state == PULL_To_REFRESH)
                    {
                        setSelection(0);
                        if ((tempY - startY) / RATIO >= headContentHeight)
                        {
                            state = RELEASE_To_REFRESH;
                            isBack = true;
                            changeHeaderViewByState();
                        }
                        else if (tempY - startY <= 0)
                        {
                            state = DONE;
                            changeHeaderViewByState();
                        }
                    }
                    if (state == DONE)
                    {
                        if (tempY - startY > 0)
                        {
                            state = PULL_To_REFRESH;
                            changeHeaderViewByState();
                        }
                    }
                    if (state == PULL_To_REFRESH)
                    {
                        headView.setPadding(0, -1 * headContentHeight
                                + (tempY - startY) / RATIO, 0, 0);
                    }
                    if (state == RELEASE_To_REFRESH)
                    {
                        headView.setPadding(0, (tempY - startY) / RATIO
                                - headContentHeight, 0, 0);
                    }
                }
                break;

            default:
                break;
        }

        return super.onTouchEvent(event);
    }

    /**
     * 根据状�?改变下拉刷新的显�?
     */
    private void changeHeaderViewByState()
    {
        switch (state)
        {
            case RELEASE_To_REFRESH:
                arrowImageView.setVisibility(View.VISIBLE);
                progressBar.setVisibility(View.GONE);
                tipsTextview.setVisibility(View.VISIBLE);
                lastUpdatedTextView.setVisibility(View.VISIBLE);
                arrowImageView.clearAnimation();
                arrowImageView.startAnimation(animation);
                tipsTextview.setText(R.string.release_refresh);
                break;
            case PULL_To_REFRESH:
                progressBar.setVisibility(View.GONE);
                tipsTextview.setVisibility(View.VISIBLE);
                lastUpdatedTextView.setVisibility(View.VISIBLE);
                arrowImageView.clearAnimation();
                arrowImageView.setVisibility(View.VISIBLE);
                if (isBack)
                {
                    isBack = false;
                    arrowImageView.clearAnimation();
                    arrowImageView.startAnimation(reverseAnimation);
                    tipsTextview.setText(R.string.dropdown_refresh);
                }
                else
                {
                    tipsTextview.setText(R.string.dropdown_refresh);
                }
                break;
            case REFRESHING:
                headView.setPadding(0, 0, 0, 0);
                progressBar.setVisibility(View.VISIBLE);
                arrowImageView.clearAnimation();
                arrowImageView.setVisibility(View.GONE);
                tipsTextview.setText(R.string.loading);
                lastUpdatedTextView.setVisibility(View.VISIBLE);
                break;
            case DONE:
                headView.setPadding(0, -1 * headContentHeight, 0, 0);
                progressBar.setVisibility(View.GONE);
                arrowImageView.clearAnimation();
                arrowImageView.setImageResource(R.drawable.arrow);
                tipsTextview.setText(R.string.load_complete);
                lastUpdatedTextView.setVisibility(View.VISIBLE);
                break;
            default:
                break;
        }
    }

    public void setStateWithShow(int state)
    {
        this.state = state;
        changeHeaderViewByState();
    }

    public void setOnRefreshListener(OnRefreshListener refreshListener)
    {
        this.refreshListener = refreshListener;
        
        isRefreshable = true;
    }

    public interface OnRefreshListener
    {
        void onRefresh();
        void onLoadMore();
    }

    public void onRefreshComplete()
    {
        state = DONE;
        lastUpdatedTextView.setText(R.string.last_update);
        String temp = lastUpdatedTextView.getText().toString();
        lastUpdatedTextView.setText(temp + new Date().toLocaleString());
        changeHeaderViewByState();
    }

    private void onRefresh()
    {
        if (refreshListener != null)
        {
            refreshListener.onRefresh();
        }
    }

    private void measureView(View child)
    {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null)
        {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec = 0;
        if (lpHeight > 0)
        {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        }
        else
        {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    public void setAdapter(BaseAdapter adapter)
    {
        lastUpdatedTextView.setText("" + new Date().toLocaleString());
        super.setAdapter(adapter);
    }
    

    private void updateLoadMoreViewState(int state) {  
        switch (state) {  
        // 普通状态  
        case MORE_DONE:  
            mLoadingView.setVisibility(View.GONE);  
            mLoadMoreTextView.setVisibility(View.VISIBLE);  
            mLoadMoreTextView.setText("查看更多");  
            break;  
        // 加载中状态  
        case MORE_REFRESHING:  
            mLoadingView.setVisibility(View.VISIBLE);  
            mLoadMoreTextView.setVisibility(View.GONE);  
            break;  


        default:  
            break;  
        }  
        loadingMoreState = state;  
    }  
    
    public void onLoadMoreComplete() {  
        updateLoadMoreViewState(DropRefreshListView.MORE_DONE);
  
    }   

    @Override
    public void onClick(View v)
    {
        
        if (refreshListener != null  
                && loadingMoreState == DropRefreshListView.MORE_DONE) {  
            updateLoadMoreViewState(DropRefreshListView.MORE_REFRESHING); 
            isPullRefresh = false;
            refreshListener.onLoadMore();// 对外提供方法加载更多.  
        }  
        
    }
}

package com.example.testrefreshlistview;

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

import com.example.testrefreshlistview.DropRefreshListView.OnRefreshListener;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;

public class MainActivity extends Activity
{

    private final String TAG = "MainActivity";

    private DropRefreshListView dropRefreshListView;

    private TestAdapter textAdapter;

    private List<String> listString = new ArrayList<String>();

    private PullRefresh pullRefresh;

    private LoadMore loadMore;

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

        initViews();
        // handler.sendEmptyMessage(0);
        pullRefresh = new PullRefresh();
        pullRefresh.execute("");

    }

    private void initViews()
    {
        dropRefreshListView = (DropRefreshListView) findViewById(R.id.dropRefreshListView);
        dropRefreshListView.setStateWithShow(DropRefreshListView.REFRESHING);
        for (int i = 0; i < 10; i++)
        {

            listString.add("ABC");
        }
        textAdapter = new TestAdapter(this, dropRefreshListView, listString);
        dropRefreshListView.setAdapter(textAdapter);
        dropRefreshListView
                .setOnRefreshListener(new DropRefreshListView.OnRefreshListener()
                {

                    @Override
                    public void onRefresh()
                    {

                        pullRefresh = new PullRefresh();
                        pullRefresh.execute("");
                    }

                    @Override
                    public void onLoadMore()
                    {
                        loadMore = new LoadMore();
                        loadMore.execute("");

                    }

                });
    }

    private class PullRefresh extends AsyncTask<String, Integer, String>
    {

        @Override
        protected void onPreExecute()
        {
            Log.i(TAG, "PullRefresh onPreExecute");
        }

        // doInBackground方法内部执行后台任务,不可在此方法内修改UI
        @Override
        protected String doInBackground(String... params)
        {
            Log.i(TAG, "PullRefresh doInBackground(Params... params) called");
            for (int i = 0; i < 10; i--)
            {
//                if (DropRefreshListView.isPullRefresh)
//                {
//                    try
//                    {
//
//                        Thread.sleep(300);
                        Log.v("tag", Thread.currentThread().getId() + "");
//                    }
//                    catch (InterruptedException e)
//                    {
//
//                        e.printStackTrace();
//                    }
//                }
//                else
//                {
//                    break;
//                }

            }

            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... progresses)
        {

        }

        // onPostExecute方法用于在执行完后台任务后更新UI,显示结果
        @Override
        protected void onPostExecute(String result)
        {
            Log.i(TAG, "PullRefresh onPostExecute(Result result) called");
            // textView.setText(result);
            //
            // execute.setEnabled(true);
            // cancel.setEnabled(false);

            dropRefreshListView.onRefreshComplete();
            textAdapter.notifyDataSetChanged();

        }

        // onCancelled方法用于在取消执行中的任务时更改UI
        @Override
        protected void onCancelled()
        {
            Log.i(TAG, "PullRefresh onCancelled() called");
            // textView.setText("cancelled");
            // progressBar.setProgress(0);
            //
            // execute.setEnabled(true);
            // cancel.setEnabled(false);
        }
    }

    private class LoadMore extends AsyncTask<String, Integer, String>
    {

        @Override
        protected String doInBackground(String... params)
        {
            for (int i = 0; i < 10; i++)
            {
                if (!DropRefreshListView.isPullRefresh)
                {
                    try
                    {

                        Thread.sleep(300);
                        Log.v("tag", Thread.currentThread().getId() + "");
                    }
                    catch (InterruptedException e)
                    {

                        e.printStackTrace();
                    }
                }
                else
                {
                    break;
                }

            }
            return null;
        }

        @Override
        protected void onPostExecute(String result)
        {
            Log.i(TAG, "LoadMore onPostExecute(Result result) called");

            dropRefreshListView.onLoadMoreComplete();
            textAdapter.notifyDataSetChanged();

        }

    }

    @Override
    protected void onDestroy()
    {

        if(pullRefresh != null && pullRefresh.getStatus() != AsyncTask.Status.FINISHED)
            pullRefresh.cancel(true);
        super.onDestroy();
//        loadMore.cancel(true);
    }

}



package com.example.testrefreshlistview;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;


public class TestAdapter extends BaseAdapter
{
    
    private Context context;
    private DropRefreshListView dropRefreshListView;
    private List<String> listString;

    public TestAdapter(Context context,DropRefreshListView dropRefreshListView,List<String> listString)
    {
        this.context = context;
        this.dropRefreshListView = dropRefreshListView;
        this.listString = listString;
    }
    
    @Override
    public int getCount()
    {
        
        return listString.size();
    }

    @Override
    public Object getItem(int position)
    {
        
        return position;
    }

    @Override
    public long getItemId(int position)
    {
        
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder viewHolder = new ViewHolder();
        if(convertView == null)
        {
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            viewHolder.iv_photo = (ImageView)convertView.findViewById(R.id.iv_photo);
            viewHolder.tv_content = (TextView)convertView.findViewById(R.id.tv_content);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder)convertView.getTag();
        }
        viewHolder.tv_content.setText(listString.get(position));
        
        return convertView;
    }
    
    static class ViewHolder
    {
        ImageView iv_photo;
        TextView tv_content;
    }
   
}


//activity_main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    >

    <com.example.testrefreshlistview.DropRefreshListView 
        android:id="@+id/dropRefreshListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
    </com.example.testrefreshlistview.DropRefreshListView>

</RelativeLayout>

footer.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/load_more_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:minHeight="40dp" 
    >

    <TextView
        android:id="@+id/load_more_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="查看更多"
        android:textSize="20sp" 
        android:layout_centerVertical="true"/>

    <LinearLayout
        android:id="@+id/loading_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:orientation="horizontal"
        android:visibility="gone" 
        android:gravity="center">

        <ProgressBar
            style="?android:attr/progressBarStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp" 
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
           
            android:text="加载中..."            
            android:textSize="20sp" 
            />
    </LinearLayout>

</RelativeLayout>


//list_header
<?xml version="1.0" encoding="utf-8"?>
<!-- ListView的头部 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >

    <!-- 内容 -->

    <RelativeLayout
        android:id="@+id/head_contentLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="30dp" >

        <!-- 箭头图像、进度条 -->

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true" >

            <!-- 箭头 -->

            <ImageView
                android:id="@+id/head_arrowImageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:contentDescription="@string/app_name"
                android:src="@drawable/arrow" />

            <!-- 进度条 -->

            <ProgressBar
                android:id="@+id/head_progressBar"
                style="@android:style/Widget.ProgressBar.Small"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center" />
        </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_tipsTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/dropdown_refresh"
                
                android:textSize="20sp" />

            <!-- 最近更新 -->

            <TextView
                android:id="@+id/head_lastUpdatedTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/last_update"

                android:textSize="12sp" />
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>

item.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="match_parent"
    android:orientation="vertical" >
    
    <ImageView 
        android:id="@+id/iv_photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"/>
    
    <TextView 
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/iv_photo"/>

</RelativeLayout>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值