Android实现下拉刷新、上拉加载功能
首页 > Android   作者:  2016年9月12日 8:45 星期一  热度:88°  字号:   评论:0 条
时间:2016-9-12 8:45   热度:88°  评论:0 条 

实现下拉刷新和上拉加载的功能,先看看实现后的效果图 


1.png2.png3.png4.png5.png

 源码地址:http://pan.baidu.com/s/1eR3xQD0

 

ListView的头布局和脚布局:

头布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:paddingBottom="15dp"
                android:paddingTop="10dp">
    <!--圆形进度条-->
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/pull_to_refresh_progress"
        style="@android:style/Widget.ProgressBar.Small"
        android:layout_centerVertical="true"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:indeterminate="false"
        android:visibility="gone"/>
    <!-- 箭头图标-->
    <ImageView
        android:id="@+id/pull_to_refresh_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="20dp"
        android:src="@drawable/ic_pulltorefresh_arrow"
        android:visibility="visible"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pull_to_refresh_text"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="5dp"
        android:text="下拉可刷新!"
        android:layout_marginTop="18dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pull_to_refresh_updated_at"
        android:layout_below="@id/pull_to_refresh_text"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="5dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
       android:visibility="gone"/>
</RelativeLayout>



<p style="text-indent:2em;">
 <br />
<p>
 &nbsp;
</p>
</p>
<p style="text-indent:2em;">
 <strong><span style="font-size:14px;">脚布局:</span></strong> 
</p>
<p style="text-indent:2em;">
 <strong></strong>&nbsp;
</p>
<p style="text-indent:2em;">
 <strong></strong>&nbsp;
</p>
<p>
 <strong>
</p>
<p style="text-indent:2em;">
 <p style="text-indent:2em;">
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingBottom="15dp"
                android:paddingTop="10dp">
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/loadmode_progress"
        style="@android:style/Widget.ProgressBar.Small"
        android:layout_centerVertical="true"
        android:layout_marginLeft="60dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:indeterminate="true"
        android:visibility="visible"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/loadmode_text"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="5dp"
        android:text="@string/loadmore_label"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"/>
</RelativeLayout>
自定义Item视图:
 
<p>
 <span style="font-size:14px;"></span>
</p>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:text="我是List"
        android:id="@+id/name"
        android:textSize="20dp"/>
</LinearLayout>
主视图:
<LinearLayout
    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"
    android:orientation="vertical"
    tools:context="com.learn.listviewrefresh.MainActivity">
    <com.learn.listviewrefresh.PullToRefreshListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/wibolist"
        android:fastScrollEnabled="true"
        android:cacheColorHint="#000000"/>
</LinearLayout>
    

 

自定义ListView:

 

/**
 * 自定义ListView
 */
public class PullToRefreshListView extends ListView implements AbsListView.OnScrollListener {
    /**
     * 当前的操作状态为——正常状态
     */
    private static final int NORMAL = 0;
    /**
     * 当前的操作状态为——提示下拉可以刷新的状态
     */
    private static final int PULL = 1;
    /**
     * 当前的操作状态为——松开可以刷新的状态
     */
    private static final int RELEASE = 2;
    /**
     * 当前的操作状态为——正在刷新状态
     */
    private static final int REFRESHING = 3;
    private OnScrollListener mOnScrollListener;         //列表滚动监听器
    private LayoutInflater mLayoutInflater;                 //用于加载布局文件
    private RelativeLayout mRefreshHeaderView; //刷新视图(顶部刷新动画)
    private TextView mRefreshHeaderText; //刷新顶部文字
    private ImageView mRefreshHeaderImage; //刷新顶部箭头
    private ProgressBar mRefreshHeaderProgerss;//刷新顶部进度条
    private RelativeLayout mLoadMoreFooterView; //加载更多
    private TextView mTextLoadMore;//提示文本
    private ProgressBar mLoadMoreProgress;//加载更多进度条
    private int mRefreshViewHeight;                            // 刷新视图高度
    int totalItemCount;// 总数量;
    int lastVisibleItem;// 最后一个可见的item;
    boolean isLoading;// 正在加载;
    /**
     * ListView当前滚动状态
     */
    private int scrollState = 0;
    /**
     * ListView当前屏幕可见的第一个item的位置
     */
    private int firstVisibleItem = 0;
    /**
     * 标识是否是在ListView的首个item出现在屏幕最顶端时手指按下
     */
    private boolean isRemark = false;
    /**
     * 当前屏幕中,ListViwe显示的第一个item是首个item时,手指按下时的Y轴坐标
     */
    private int startY = 0;
    /**
     * 当前的操作状态
     */
    private int currentState = 0;
    /**
     * 数据刷新接口
     */
    IReflashListener iReflashListener;//刷新数据的接口
    public PullToRefreshListView(Context context) {
        super(context);
        init(context);
    }
    public PullToRefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }
    //初始化布局
    private void init(Context context) {
        // 获取LayoutInflater实例对象
        mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mRefreshHeaderView = (RelativeLayout) mLayoutInflater.inflate(R.layout.pull_to_refresh_header, this, false);
        //绑定控件
        mLoadMoreFooterView = (RelativeLayout) mLayoutInflater.inflate(R.layout.loadmore_footer, this, false);
        mTextLoadMore = (TextView) mLoadMoreFooterView.findViewById(R.id.loadmode_text);
        mLoadMoreProgress = (ProgressBar) mLoadMoreFooterView.findViewById(R.id.loadmode_progress);
            //设置底部视图不可见
        mLoadMoreFooterView.setVisibility(GONE);
        measureView(mRefreshHeaderView);
        mRefreshViewHeight = mRefreshHeaderView.getMeasuredHeight(); //得到视图的高度
        paddingTop(-mRefreshViewHeight);
        addHeaderView(mRefreshHeaderView);  //增加头部视图
        addFooterView(mLoadMoreFooterView); //增加顶部视图
        super.setOnScrollListener(this); //滑屏分页显示数据
    }
    public void setOnScrollListener(AbsListView.OnScrollListener l) {
        mOnScrollListener = l;
    }
    //触摸事件
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:  //手指按下
                if (0 == firstVisibleItem) {
                    isRemark = true;
                    startY = (int) event.getY();
                    Log.v("手指按下", "手指按下" + startY);
                }
                break;
            case MotionEvent.ACTION_MOVE:  ////手指移动
                onMove(event);
                break;
            case MotionEvent.ACTION_UP:   //手指抬起
                if (currentState == RELEASE) { // 提示“松开可以刷新”,那么就刷新数据
                    currentState = REFRESHING;
                    refreshListViewByCurrentState();
                    if (iReflashListener != null) {
                        iReflashListener.onRefresh();
                    }
                } else if (currentState == PULL) { // 提示“下拉可以刷新”,那么就复位
                    currentState = NORMAL;
                    isRemark = false;
                    refreshListViewByCurrentState();
                }
                break;
        }
        return super.onTouchEvent(event);
    }
    /**
     * 根据当前状态,来改变界面显示
     */
    private void refreshListViewByCurrentState() {
        // 加载下拉刷新的头部视图  绑定控件
        mRefreshHeaderImage = (ImageView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_image);
        mRefreshHeaderProgerss = (ProgressBar) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_progress);
        mRefreshHeaderText = (TextView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_text);
        // 箭头从上到下旋转180度的动画
        RotateAnimation upTodown = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        upTodown.setDuration(500);
        upTodown.setFillAfter(true);
        // 箭头从下到上旋转180度的动画
        RotateAnimation downToup = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        downToup.setDuration(500);
        downToup.setFillAfter(true);
        switch (currentState) {
            case NORMAL:
                mRefreshHeaderImage.clearAnimation();
                paddingTop(-mRefreshViewHeight);
                break;
            case PULL:
                mRefreshHeaderImage.setVisibility(View.VISIBLE);
                mRefreshHeaderText.setText("下拉可以刷新");
                mRefreshHeaderImage.clearAnimation();
                mRefreshHeaderImage.startAnimation(downToup);
                break;
            case RELEASE:
                mRefreshHeaderImage.setVisibility(View.VISIBLE);
                mRefreshHeaderProgerss.setVisibility(View.GONE);
                mRefreshHeaderText.setText("松开可以刷新");
                mRefreshHeaderImage.clearAnimation();
                mRefreshHeaderImage.startAnimation(upTodown);
                break;
            case REFRESHING:
                paddingTop(50);
                mRefreshHeaderImage.setVisibility(View.GONE);
                mRefreshHeaderProgerss.setVisibility(View.VISIBLE);
                mRefreshHeaderText.setText("刷新中...");
                mRefreshHeaderImage.clearAnimation();
                break;
        }
    }
    //判断移动过程
    private void onMove(MotionEvent event) {
        if (!isRemark) {
            return;
             /*
             * 如果不是手指在ListView的首个item出现在顶部时按下,并滑动的操作,
             * 说明用户不是在做下拉刷新的操作,那么就不需要做任何操作,方法直接放回
             */
        }
        int currentY = (int) event.getY(); // 当前手指移动到哪个位置
        int space = currentY - startY;    // 移动的距离是多少
        int paddingTop = space - mRefreshViewHeight;
        switch (currentState) {
            case NORMAL:
                if (space > 0) {
                    currentState = PULL;
                    refreshListViewByCurrentState();
                }
                break;
            case PULL:
                paddingTop(paddingTop);
                if (space - mRefreshViewHeight > 30
                        && scrollState == SCROLL_STATE_TOUCH_SCROLL) { // 移动距离大于一定高度,并且正在滚动
                    currentState = RELEASE;
                    refreshListViewByCurrentState();
                }
                break;
            case RELEASE:
                paddingTop(paddingTop);
                if (space - mRefreshViewHeight < 30) { // 如果小于一定的高度
                    currentState = PULL;
                    refreshListViewByCurrentState();
                }
                break;
        }
    }
    //获取视图大小
    private void measureView(View child) {
        ViewGroup.LayoutParams params = child.getLayoutParams();
        if (params == null) {
            params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int width = ViewGroup.getChildMeasureSpec(0, 0, params.width);
        int hight = 0;
        int tempHight = params.height;
        if (tempHight > 0) {
            hight = MeasureSpec.makeMeasureSpec(tempHight, MeasureSpec.EXACTLY);
        } else {
            hight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(width, hight);
    }
    /**
     * 设置顶部布局的上内边距
     */
    private void paddingTop(int paddingTop) {
        mRefreshHeaderView.setPadding(mRefreshHeaderView.getPaddingLeft(), paddingTop, getListPaddingRight(), getListPaddingBottom());
        mRefreshHeaderView.invalidate();
    }
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
        if (totalItemCount == lastVisibleItem && scrollState == SCROLL_STATE_IDLE && currentState == NORMAL) {
            if (!isLoading) {
                isLoading = true;
                mLoadMoreFooterView.setVisibility(VISIBLE);
                //加载更多
                iReflashListener.onRefresh2();
            }
        }
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem; //第一个item
        this.lastVisibleItem = firstVisibleItem + visibleItemCount; //最后一个item = 第一个item + 可见的item
        this.totalItemCount = totalItemCount;
    }
    //加载完成
    public void reflashComplete() {
        currentState = NORMAL;
        isRemark = false;
        refreshListViewByCurrentState();
        isLoading = false;
        mLoadMoreFooterView.setVisibility(GONE);
    }
    public void setInterface(IReflashListener iReflashListener) {
        this.iReflashListener = iReflashListener;
    }
    /**
     * 数据刷新接口
     */
    public interface IReflashListener {
        public void onRefresh();
        public void onRefresh2();
    }
}
 <p>
   &nbsp;
  </p>
  <p>
   自定义Adapt:
  </p>
public class MyAdapter extends BaseAdapter {
    ArrayList<MyEntity> arrayList;
    LayoutInflater inflater;
    public MyAdapter(Context context,ArrayList<MyEntity> arrayList){
        this.arrayList = arrayList;
        this.inflater = LayoutInflater.from(context);
    }
    public void onDataChange(ArrayList<MyEntity> arrayList){
        this.arrayList = arrayList;
        this.notifyDataSetChanged();
    }
    @Override
    public int getCount() {
        return arrayList.size();
    }
    @Override
    public Object getItem(int position) {
        return arrayList.get(position);
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        MyEntity entity = arrayList.get(position);
        ViewHolder holder;
        if (convertView==null){
            holder=new ViewHolder();
            convertView = inflater.inflate(R.layout.item_layout,null);
            holder.name = (TextView) convertView.findViewById(R.id.name);
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.name.setText(entity.getName());
        return convertView;
    }
    class ViewHolder{
        TextView name;
    }
}
 <p>
   &nbsp;
  </p>
  <p>
   &nbsp;
  </p>
MyEntity.java
public class MyEntity {
    private String name;
    private String des;
    private String info;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
}
 
 MainActivity.java
public class MainActivity extends Activity implements PullToRefreshListView.IReflashListener {
    ArrayList<MyEntity> arrayList = new ArrayList<MyEntity>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getData();
        showList(arrayList);
    }
    MyAdapter adapter;
    PullToRefreshListView listView;
    private void showList(ArrayList<MyEntity> arrayList) {
        if (adapter == null) {
            listView = (PullToRefreshListView) findViewById(R.id.wibolist);
            listView.setInterface(this);
            adapter = new MyAdapter(this, arrayList);
            listView.setAdapter(adapter);
        } else {
            adapter.onDataChange(arrayList);
        }
    }
    private void getData() {
        for (int i = 0; i < 10; i++) {
            MyEntity entity = new MyEntity();
            entity.setName("数据");
            arrayList.add(entity);
        }
    }
    private void RefreshMoreData() {
        for (int i = 0; i < 2; i++) {
            MyEntity entity = new MyEntity();
            entity.setName("刷新的数据");
            arrayList.add(0,entity);
        }
    }
    private void LoadMoreData() {
        for (int i = 0; i < 2; i++) {
            MyEntity entity = new MyEntity();
            entity.setName("加载更多的数据");
            arrayList.add(entity);
        }
    }
    public void onLoad() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //加载更多数据
                RefreshMoreData();
                //更新ListView
                showList(arrayList);
                //通知ListView加载完成
                listView.reflashComplete();
            }
        }, 2000);
    }
    public void onLoadNext() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //加载更多数据
                LoadMoreData();
                //更新ListView
                showList(arrayList);
                //通知ListView加载完成
                listView.reflashComplete();
            }
        }, 2000);
    }
    @Override
    public void onRefresh() {
        onLoad();
        showList(arrayList);
    }
    @Override
    public void onRefresh2() {
        onLoadNext();
        showList(arrayList);
    }
}
 
 
<p>
 <br />
</p>

<p>
 <br />
</p>
 
 <p>
   <br />
  </p>
  <p style="text-indent:2em;">
   <br />
  </p>
  <p style="text-indent:2em;">
   </strong>
  </p>
  <p>
   </strong>
  </p>
  <p style="text-indent:2em;">
   <br />
<p>
 &nbsp;
</p>
 </p>
 您阅读这篇文章共花了: 
二维码加载中...
本文作者:      文章标题: Android实现下拉刷新、上拉加载功能
本文地址:http://www.zhangmaoqin.cn/post-27.html
版权声明:若无注明,本文皆为“Remember”原创,转载请保留文章出处。
  • blogger

发表吐槽

你肿么看?

你还可以输入 250 / 250 个字

嘻嘻 大笑 可怜 吃惊 害羞 调皮 鄙视 示爱 大哭 开心 偷笑 嘘 奸笑 委屈 抱抱 愤怒 思考 日了狗

评论信息框


既然没有吐槽,那就赶紧抢沙发吧!
返回顶部    首页    手气不错    QQ邮箱:1085911874@qq.com后花园   
版权所有:Remember    站长:                 sitemap