教你如何定制属于自己的listView。

以前实现listView的下拉刷新和上拉加载,都是用的开源项目,现在各大应用都有一套属于自己的下拉刷新样式,于是,自己就研究了下listView如何实现下拉刷新,结果很是让我兴奋。一直以为实现它会很困难。然而,却不是那样的。主要你敢尝试,其实并不困难。有时,我们只是被自己 吓到了而已。闲话不多说。


要实现下拉刷新,我们  需要写一个header布局,来实现下拉头。listView中有两个方法,是addHeaderView()和addFooteViewr();这两个方法的出现,相信你也会有些感触。

1、实现下拉刷新

写属于自己风格的header_layout.xml,,通过addheaderView将其加入listView之中,默认header布局是不显示的,我们设置其padding让它一开始偏移到屏幕外


  /**
     * 设置header布局上边距
     *
     * @param topPadding
     */
    private void topPadding(int topPadding) {

        headerView.setPadding(headerView.getPaddingLeft(), topPadding,
                headerView.getPaddingRight(), headerView.getPaddingBottom());
        headerView.invalidate();

    }


这里需要注意下,我们需要测量header的height, 直接headerView.getMeasuredHeight()是获取不到,你可测试下,会得到0,我们需要告诉
父布局它的一些参数

 private void measuerView(View headerView) {
        ViewGroup.LayoutParams lp = headerView.getLayoutParams();
        if (lp == null) {
            lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int with = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
        int height;
        int tempHeight = lp.height;
        if (tempHeight > 0) {
            height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
        } else {
            height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        headerView.measure(with, height);

    }


这样我们就设置好了header布局,我们需要实现onTouchEvent函数来判断当前的状态,动态的改变下拉头布局中的信息

 @Override
    public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:

                if (firstVisibleItem == 0) {
                    isHeaderPress = true;
                    startY = (int) ev.getY();
                }


                break;
            case MotionEvent.ACTION_MOVE:

                onMove(ev);

                break;
            case MotionEvent.ACTION_UP:

                if (state == RELEASE) {
                    state = REFRESHING;

                    //加载新数据
                    if (refreshListener != null) {
                        refreshListener.onRefresh();
                    }

                } else if (state == PULL) {
                    state = NONE;
                    isHeaderPress = false;

                }

                refreshHeaderView();

                break;
        }


        return super.onTouchEvent(ev);
    }

    private void onMove(MotionEvent ev) {

        if (!isHeaderPress)
            return;

        int tempY = (int) ev.getY();

        int offset = tempY - startY;
        int topPadding = offset - headerdHeight;

        switch (state) {
            case NONE:

                if (offset > 0)
                    state = PULL;
                break;
            case PULL:
                if (offset > headerdHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL)
                    state = RELEASE;
                break;
            case RELEASE:
                if (offset < headerdHeight + 30) {
                    state = PULL;
                } else if (offset <= 0) {
                    state = NONE;
                }

                break;
        }
        topPadding(topPadding);
        //根据状态,改变界面显示
        refreshHeaderView();


    }

2、实现加载更多

同样自定义Footer布局,通过addFooterView,将其加入其中,判断当前item是否滚动到最后,

  @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;

        if(!isLoading && scrollState==SCROLL_STATE_IDLE){
            isLoading=true;

            if(refreshListener!=null){

                footLayout.setVisibility(View.VISIBLE);
                //加载更多数据
                refreshListener.onLoading();
            }

        }


    }

    /**
     * Callback method to be invoked when the list or grid has been scrolled. This will be
     * called after the scroll has completed
     *
     * @param view             The view whose scroll state is being reported
     * @param firstVisibleItem the index of the first visible cell (ignore if
     *                         visibleItemCount == 0)
     * @param visibleItemCount the number of visible cells
     * @param totalItemCount   the number of items in the list adaptor
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
        this.totalItemCount=totalItemCount;
        this.lastVisibleItem=firstVisibleItem+visibleItemCount;
    }

    ;


3.实现监听回调函数


    /**
     * 刷新数据回调接口
     */
    public interface OnRefreshListener {
        /**
         * 下拉加载更多数据
         */
        void onRefresh();

        /**
         * 上拉加载更多数据
         */
        void onLoading();
    }


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

4.通知listView,数据已经加载完成,做相应布局的隐藏

   /**
     * 下拉获取完数据
     */
    public void refreshComplete() {
        state = NONE;
        isHeaderPress = false;
        refreshHeaderView();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        lastTime.setText(format.format(new Date()));

    }

    /**
     * 加载更多数据完成
     */
    public void loadComplete(){

        isLoading=false;
        footLayout.setVisibility(View.GONE);

    }
图片就不发放了,想看效果的下面有

5、源码下载地址  :http://download.csdn.net/user/qq_21840193   点击打开链接








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值