仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解



先看效果

分别是我的效果和今日头条的效果: 
仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解_第1张图片仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解_第2张图片

以上效果包括: 
1.如果下拉的高度超过search view的高度的3/4,但是小于head view高度,则松开手时search view自动出现 
2.如果下拉的高度小于search view的高度的1/4,则松开手时search view自动回弹消失 
3.如果下拉的高度超过head view的总高度,则松手进行刷新 
4.刷新完成自动隐藏search view

实现原理讲解

参考了 github开源项目:[https://github.com/vivian8725118/SearchListView ] 
提示: 这个效果是基于PullToRefreshListView实现的,如果对下拉刷新listview实现不明白的,可以先看这篇博客[http://blog.csdn.net/u010335298/article/details/51098755] 
原理讲解 
仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解_第3张图片 
如图,将搜索部分的view放进ListView的头view中,在触摸事件中处理search view 的显示和隐藏。

1.我给listview定义了五种状态

    public static final int STATE_NONE  = 0;
    public static final int STATE_PULL_TO_SHOW_SEARCH_VIEW  = 1; // 下拉去展示search_view
    public static final int STATE_PULL_TO_REFRESH = 2; //下拉去刷新
    public static final int STATE_RELEASE_TO_REFRESH = 3; // 释放进行刷新
    public static final int STATE_REFRESHING = 4; // 正在刷新
  • 1
  • 2
  • 3
  • 4
  • 5

稍微讲解以下这几种状态: 
STATE_PULL_TO_SHOW_SEARCH_VIEW 指的是search view出现了一部分但是没有完全出现的时候 
STATE_PULL_TO_REFRESH 指的是search view完全出现,但是head view没有完全出现的时候 
STATE_RELEASE_TO_REFRESH 指的是head view完全出现的时候

2.添加search view

 private void initHeaderView() {
        headerView =  View.inflate(getContext(), R.layout.search_header_listview, null);
        searchContainer = (RelativeLayout) headerView.findViewById(R.id.search_container);
        headerTv = (TextView) headerView.findViewById(R.id.tvHead);
        headerView.measure(0, 0); // 系统会帮我们测量出headerView的高度
        headerHeight = refreshHeight = headerView.getMeasuredHeight();
        Log.d("zyr", "--------------------headerHeight :" + headerHeight);
        headerView.setPadding(0, -headerHeight, 0, 0);
        invalidate();
        Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
        super.addHeaderView(headerView, null, false);
    }

    private void addSearchView() {
        searchView = LayoutInflater.from(getContext()).inflate(R.layout.search_view, null);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        searchContainer.addView(searchView , layoutParams);
        searchContainer.measure(0, 0);
        searchContainerHeight = searchContainer.getMeasuredHeight();
        Log.d("zyr", "--------------------searchContainerHeight :" + searchContainerHeight);
        headerHeight = searchContainerHeight + headerHeight ;
        headerView.setPadding(0, - headerHeight, 0, 0);
        invalidate();
        Log.d("zyr", "--------------------headerHeight :" + headerHeight);
        Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

3.触摸事件的处理:我详细的写了注释

/***************************    Touch***************************************/
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN :
                downY = lastMoveY = (int) ev.getY();
                downX = (int) ev.getX();
                break;
            case MotionEvent.ACTION_MOVE :
                moveY = (int) ev.getY();
                moveDiff = (moveY - lastMoveY)/2 ;
                lastMoveY = moveY ;
                diff = moveY - downY;
                //计算移动后的paddingTop
                int paddingTop =   headerView.getPaddingTop() + moveDiff ;
                // 如果: 第一个可见
                if(getFirstVisiblePosition() == 0 && Math.abs(diff) > 50){
                    switch (state){
                        case STATE_NONE :
                        //当状态是none的时候,向下拉才做处理
                            if(diff > 0){
                                state = STATE_PULL_TO_SHOW_SEARCH_VIEW;
                                headerView.setPadding(0, paddingTop, 0, 0);
                                Log.d("zyr", "--------------paddingTop:" + paddingTop);
                                return true;
                            }
                            break;
                        case STATE_PULL_TO_SHOW_SEARCH_VIEW:
                        case STATE_PULL_TO_REFRESH:
                        case STATE_RELEASE_TO_REFRESH:
                            if (paddingTop >= 0 ) { // 完全显示了.
                                Log.i("zyr", "ACTION_MOVE 松开刷新");
                                state = STATE_RELEASE_TO_REFRESH;
                                refreshHeaderView();
                            } else if (paddingTop < 0 && Math.abs(paddingTop) <= refreshHeight) {//search view完全显示了,head view没有完全显示
                                Log.i("zyr", "ACTION_MOVE 下拉刷新");
                                state = STATE_PULL_TO_REFRESH;
                                refreshHeaderView();
                            }  else if(paddingTop < 0 && Math.abs(paddingTop) > refreshHeight) {//search view没有完全显示
                                Log.i("zyr", "ACTION_MOVE 下拉显示Search View");
                                state = STATE_PULL_TO_SHOW_SEARCH_VIEW;
                                refreshHeaderView();
                            }  else if ( paddingTop == 0){
                                state = STATE_NONE;
                                break;
                            }
                            // 下拉头布局
                            Log.d("zyr","--------------paddingTop:" + paddingTop);
                            headerView.setPadding(0, paddingTop, 0, 0);
                            return true;
                        default:
                            break;
                    }
                }
                break;
            case MotionEvent.ACTION_UP :
                upY = (int)ev.getY();
                upX = (int)ev.getX();
                // 判读是不是点击事件
                if(Math.abs(upY - downY) < 50 && Math.abs(upX - downX) < 50){
                    super.onTouchEvent(ev);
                }

                int headPaddingTop = headerView.getPaddingTop();
                Log.d("zyr","--------------MotionEvent.ACTION_UP paddingTop:" + headPaddingTop);
                Log.d("zyr","--------------MotionEvent.ACTION_UP state:" + state);
                // 判断当前的状态
                switch (state){
                    case STATE_PULL_TO_SHOW_SEARCH_VIEW:
                        if ( headerHeight - Math.abs(headPaddingTop) <= searchContainerHeight * 0.25){
                            Log.i("zyr", "下拉高度小于Search View * 0.25,隐藏search view");
                            // 隐藏头布局
                            mScroller.startScroll(0,headPaddingTop,0,- headerHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_NONE;
                        } else if( headerHeight - Math.abs(headPaddingTop) >= searchContainerHeight * 0.75) {
                            Log.i("zyr", "下拉高度大于Search View * 0.75,显示search view");
                            // 显示 search view
                            mScroller.startScroll(0,headPaddingTop,0,- refreshHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_PULL_TO_REFRESH;
                        } else if ( moveDiff > 0){
                            Log.i("zyr", "下拉高度在Search View * 0.25 - 0.75,下拉,显示search view");
                            // 显示 search view
                            mScroller.startScroll(0,headPaddingTop,0,- refreshHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_PULL_TO_REFRESH;
                        } else {
                            Log.i("zyr", "下拉高度在Search View * 0.25 - 0.75,上滑,隐藏search view");
                            // 隐藏头布局
                            mScroller.startScroll(0,headPaddingTop,0,- headerHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_NONE;
                        }
                        return true;
                    case STATE_PULL_TO_REFRESH:
                        Log.i("zyr", "ACTION_UP 下拉刷新数据");
                        // 显示search view
                        mScroller.startScroll(0,headerView.getPaddingTop(),0,- refreshHeight - headerView.getPaddingTop(),DURATION);
                        postInvalidate();
                        return true;
                    case STATE_RELEASE_TO_REFRESH:
                        Log.i("zyr", "ACTION_UP 释放刷新数据");
                        // 把头布局设置为完全显示状态
                        mScroller.startScroll(0,headerView.getPaddingTop(),0,-headerView.getPaddingTop(),DURATION);
                        postInvalidate();
                        // 进入到正在刷新中状态
                        state = STATE_REFRESHING;
                        refreshHeaderView();

                        if (mOnRefreshListener != null) {
                            mOnRefreshListener.onDownPullRefresh(); // 调用使用者的监听方法
                        }
                        return true;
                }
                break;
            default :
                break;
        }
        return super.onTouchEvent(ev);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121

详细代码

CustomSearchListView

package com.example.myapp.view;

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.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;

import com.example.myapp.R;

/**
 * Created by zyr
 * DATE: 16-4-8
 * Time: 下午7:09
 * Email: [email protected]
 *
 * 通过listview addHeaderView来实现下拉刷新
 */
public class CustomSearchListView extends ListView implements AbsListView.OnScrollListener {
    private Context mContext;

    private View headerView;

    private TextView headerTv;

    private View searchView;

    private RelativeLayout searchContainer;

    private int headerHeight ;

    private int refreshHeight ;

    private int searchContainerHeight;

    private Scroller mScroller;

    public static final int STATE_NONE  = 0;
    public static final int STATE_PULL_TO_SHOW_SEARCH_VIEW  = 1; // 下拉去展示search_view
    public static final int STATE_PULL_TO_REFRESH = 2; //下拉去刷新
    public static final int STATE_RELEASE_TO_REFRESH = 3; // 释放进行刷新
    public static final int STATE_REFRESHING = 4; // 正在刷新

    private int state = STATE_NONE;
    private int downX , downY , moveY , lastMoveY , upY , upX;
    private int diff , moveDiff;

    public static final int DURATION = 500;
    private OnRefreshListener mOnRefreshListener;

    public interface OnRefreshListener{
        void onDownPullRefresh();
    }

    /************************   构造****************************************/

    public CustomSearchListView(Context context) {
        this(context, null);
    }

    public CustomSearchListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomSearchListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;

        initScroller();
        initHeaderView();
        addSearchView();
        setOnScrollListener(this);
    }

    private void initScroller() {
        mScroller = new Scroller(getContext(), new DecelerateInterpolator());
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mScroller.computeScrollOffset()){
            Log.d("zyr" , "-----------computeScroll mScroller.getCurrY():" + mScroller.getCurrY());
            headerView.setPadding(0, mScroller.getCurrY(), 0, 0);
        }
    }

    private void initHeaderView() {
        headerView =  View.inflate(getContext(), R.layout.search_header_listview, null);
        searchContainer = (RelativeLayout) headerView.findViewById(R.id.search_container);
        headerTv = (TextView) headerView.findViewById(R.id.tvHead);
        headerView.measure(0, 0); // 系统会帮我们测量出headerView的高度
        headerHeight = refreshHeight = headerView.getMeasuredHeight();
        Log.d("zyr", "--------------------headerHeight :" + headerHeight);
        headerView.setPadding(0, -headerHeight, 0, 0);
        invalidate();
        Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
        super.addHeaderView(headerView, null, false);
    }

    private void addSearchView() {
        searchView = LayoutInflater.from(getContext()).inflate(R.layout.search_view, null);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        searchContainer.addView(searchView , layoutParams);
        searchContainer.measure(0, 0);
        searchContainerHeight = searchContainer.getMeasuredHeight();
        Log.d("zyr", "--------------------searchContainerHeight :" + searchContainerHeight);
        headerHeight = searchContainerHeight + headerHeight ;
        headerView.setPadding(0, - headerHeight, 0, 0);
        invalidate();
        Log.d("zyr", "--------------------headerHeight :" + headerHeight);
        Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
    }

    /**************************     Scroll******************************/
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    }

    /***************************    Touch***************************************/
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN :
                downY = lastMoveY = (int) ev.getY();
                downX = (int) ev.getX();
                break;
            case MotionEvent.ACTION_MOVE :
                moveY = (int) ev.getY();
                moveDiff = (moveY - lastMoveY)/2 ;
                lastMoveY = moveY ;
                diff = moveY - downY;
                //
                int paddingTop =   headerView.getPaddingTop() + moveDiff ;
                // 如果: 第一个可见
                if(getFirstVisiblePosition() == 0 && Math.abs(diff) > 50){
                    switch (state){
                        case STATE_NONE :
                            if(diff > 0){
                                state = STATE_PULL_TO_SHOW_SEARCH_VIEW;
                                headerView.setPadding(0, paddingTop, 0, 0);
                                Log.d("zyr", "--------------paddingTop:" + paddingTop);
                                return true;
                            }
                            break;
                        case STATE_PULL_TO_SHOW_SEARCH_VIEW:
                        case STATE_PULL_TO_REFRESH:
                        case STATE_RELEASE_TO_REFRESH:
                            if (paddingTop >= 0 ) { // 完全显示了.
                                Log.i("zyr", "ACTION_MOVE 松开刷新");
                                state = STATE_RELEASE_TO_REFRESH;
                                refreshHeaderView();
                            } else if (paddingTop < 0 && Math.abs(paddingTop) <= refreshHeight) {
                                Log.i("zyr", "ACTION_MOVE 下拉刷新");
                                state = STATE_PULL_TO_REFRESH;
                                refreshHeaderView();
                            }  else if(paddingTop < 0 && Math.abs(paddingTop) > refreshHeight) {
                                Log.i("zyr", "ACTION_MOVE 下拉显示Search View");
                                state = STATE_PULL_TO_SHOW_SEARCH_VIEW;
                                refreshHeaderView();
                            }  else if ( paddingTop == 0){
                                state = STATE_NONE;
                                break;
                            }
                            // 下拉头布局
                            Log.d("zyr","--------------paddingTop:" + paddingTop);
                            headerView.setPadding(0, paddingTop, 0, 0);
                            return true;
                        default:
                            break;
                    }
                }
                break;
            case MotionEvent.ACTION_UP :
                upY = (int)ev.getY();
                upX = (int)ev.getX();
                // 判读是不是点击事件
                if(Math.abs(upY - downY) < 50 && Math.abs(upX - downX) < 50){
                    super.onTouchEvent(ev);
                }
                // 判断当前的状态
                int headPaddingTop = headerView.getPaddingTop();
                Log.d("zyr","--------------MotionEvent.ACTION_UP paddingTop:" + headPaddingTop);
                Log.d("zyr","--------------MotionEvent.ACTION_UP state:" + state);
                switch (state){
                    case STATE_PULL_TO_SHOW_SEARCH_VIEW:
                        if ( headerHeight - Math.abs(headPaddingTop) <= searchContainerHeight * 0.25){
                            Log.i("zyr", "下拉高度小于Search View * 0.25,隐藏search view");
                            // 隐藏头布局
                            mScroller.startScroll(0,headPaddingTop,0,- headerHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_NONE;
                        } else if( headerHeight - Math.abs(headPaddingTop) >= searchContainerHeight * 0.75) {
                            Log.i("zyr", "下拉高度大于Search View * 0.75,显示search view");
                            // 显示 search view
                            mScroller.startScroll(0,headPaddingTop,0,- refreshHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_PULL_TO_REFRESH;
                        } else if ( moveDiff > 0){
                            Log.i("zyr", "下拉高度在Search View * 0.25 - 0.75,下拉,显示search view");
                            // 显示 search view
                            mScroller.startScroll(0,headPaddingTop,0,- refreshHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_PULL_TO_REFRESH;
                        } else {
                            Log.i("zyr", "下拉高度在Search View * 0.25 - 0.75,上滑,隐藏search view");
                            // 隐藏头布局
                            mScroller.startScroll(0,headPaddingTop,0,- headerHeight - headPaddingTop , DURATION);
                            postInvalidate();
                            state = STATE_NONE;
                        }
                        return true;
                    case STATE_PULL_TO_REFRESH:
                        Log.i("zyr", "ACTION_UP 下拉刷新数据");
                        // 显示search view
                        mScroller.startScroll(0,headerView.getPaddingTop(),0,- refreshHeight - headerView.getPaddingTop(),DURATION);
                        postInvalidate();
                        return true;
                    case STATE_RELEASE_TO_REFRESH:
                        Log.i("zyr", "ACTION_UP 释放刷新数据");
                        // 把头布局设置为完全显示状态
                        mScroller.startScroll(0,headerView.getPaddingTop(),0,-headerView.getPaddingTop(),DURATION);
                        postInvalidate();
                        // 进入到正在刷新中状态
                        state = STATE_REFRESHING;
                        refreshHeaderView();

                        if (mOnRefreshListener != null) {
                            mOnRefreshListener.onDownPullRefresh(); // 调用使用者的监听方法
                        }
                        return true;
                }
                break;
            default :
                break;
        }
        return super.onTouchEvent(ev);
    }
    /**
     * 根据currentState刷新头布局的状态
     */
    private void refreshHeaderView() {
        switch (state) {
            case STATE_PULL_TO_REFRESH : // 下拉刷新状态
            case STATE_PULL_TO_SHOW_SEARCH_VIEW:
                headerTv.setText("下拉刷新");
                break;
            case STATE_RELEASE_TO_REFRESH : // 松开刷新状态
                headerTv.setText("松开刷新");
                break;
            case STATE_REFRESHING : // 正在刷新中状态
                headerTv.setText("正在刷新中...");
                break;
            default :
                break;
        }
    }

    /**
     * 隐藏头布局
     */
    public void hideHeaderView() {
        post(new Runnable() {
            @Override
            public void run() {
                mScroller.startScroll(0,headerView.getPaddingTop(),0,- headerHeight -headerView.getPaddingTop(),DURATION);
                postInvalidate();
                headerTv.setText("下拉刷新");
                state = STATE_NONE;
            }
        });
    }

    /**
     * 设置刷新监听事件
     *
     * @param listener
     */
    public void setOnRefreshListener(OnRefreshListener listener) {
        mOnRefreshListener = listener;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296

search_header_listview.xml


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

    

    <RelativeLayout
        android:id="@+id/head_contentLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center">
        <RelativeLayout android:id="@+id/refresh_container"
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:gravity="center">
            <TextView
                android:id="@+id/tvHead"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/pull_to_refresh_pull_label"
                android:textColor="@color/black"
                android:textSize="15.5sp"
                android:textStyle="bold" />
        RelativeLayout>

        <RelativeLayout android:id="@+id/search_container"
            android:layout_below="@+id/refresh_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        RelativeLayout>
    RelativeLayout>

LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

search_view.xml


<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="30dp"
        android:text="Search"
        android:gravity="center"
        android:background="@drawable/common_bg2"
        android:layout_margin="5dp"
        android:textSize="15sp"/>
LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

CustomSearchListViewTestActivity

package com.example.myapp.activity;

import android.view.View;
import android.widget.AdapterView;
import android.widget.FrameLayout;

import com.example.myapp.R;
import com.example.myapp.adapter.CommonAdapter;
import com.example.myapp.util.Methods;
import com.example.myapp.view.CustomPullToRefreshListView2;
import com.example.myapp.view.CustomSearchListView;

import java.util.ArrayList;

/**
 * Created by zyr
 * DATE: 16-4-6
 * Time: 下午4:05
 * Email: [email protected]
 */
public class CustomSearchListViewTestActivity extends BaseActivity {
    private FrameLayout headRoot;
    private FrameLayout headContainer;
    private CustomSearchListView listView;
//    private PullToRefreshListView listView;

    private CommonAdapter commonAdapter;
    private ArrayList strings  = new ArrayList<>();

    @Override
    protected void initView() {
        listView = (CustomSearchListView) findViewById(R.id.listview);
        for(int i=0;i<20;i++){
            strings.add("zyr" + i);
        }
        commonAdapter = new CommonAdapter(this,strings);
        listView.setAdapter(commonAdapter);
        listView.setOnRefreshListener(new CustomSearchListView.OnRefreshListener() {
            @Override
            public void onDownPullRefresh() {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        listView.hideHeaderView();
                    }
                }).start();
            }
        });
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                Methods.toast(CustomSearchListViewTestActivity.this,id+"");
            }
        });
    }

    @Override
    protected int onSetContainerViewId() {
        return R.layout.activity_custom_search_listview;
    }

    @Override
    public void initListener() {

    }

    @Override
    public void onClick(View v) {

    }
}

你可能感兴趣的:(android,ui,android进阶之路)