实现ListView的弹性效果,下拉隐藏ToolBar(ActionBar),上拉显示ToolBar

来源:互联网 发布:php 多个图片合成一张 编辑:程序博客网 时间:2024/05/16 09:12

效果图,gif图片看起来略卡顿,实际很流畅

效果图

ToolBar要注意,如果不是5.0以上的话,需要在gradle中引入V7包

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.1.1'}

1、布局文件

<?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:background="#FFFFFF">    <com.dfhe.listviewdemo.MyListView        android:id="@+id/lv"        android:divider="#FF0000"        android:dividerHeight="1px"        android:layout_width="match_parent"        android:layout_height="match_parent"        />    <android.support.v7.widget.Toolbar        android:id="@+id/tool"        android:layout_width="match_parent"        android:layout_height="@dimen/abc_action_bar_default_height"        android:background="#465240"        ></android.support.v7.widget.Toolbar></RelativeLayout>

Item布局文件

<?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">    <TextView        android:id="@+id/tv_content"        android:layout_width="match_parent"        android:layout_height="50dp"        android:gravity="center"        android:text="测试数据"        android:textColor="#000000"        android:textSize="18sp"/></RelativeLayout>

主界面的代码实现

public class MainActivity extends ActionBarActivity implements AbsListView.OnScrollListener {    public ArrayList<String> data= new ArrayList<>();    ListView lv;    int lastVisibleItem;    int mTouchSlop;//获取系统认为的滑动的最小距离    float mFirstY;    float mCurrentY;    int direction;    boolean mShow;    private Toolbar toolbar;    Animator mAnimator;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化toolBar        toolbar = (Toolbar) findViewById(R.id.tool);        if(toolbar != null) {            setSupportActionBar(toolbar);        }        initLayout();    }    /**     * 初始化数据     */    private void initLayout() {        //模拟数据        for (int i = 0; i < 50; i++) {            data.add("测试数据"+i);        }        //获取系统认为的最低滑动距离        mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();        //对滑动时间进行判断        View.OnTouchListener myTouchListener = new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()){                    case MotionEvent.ACTION_DOWN:                        mFirstY = event.getY();                        break;                    case MotionEvent.ACTION_MOVE:                        mCurrentY = event.getY();                        if(mCurrentY - mFirstY  > mTouchSlop){                            direction = 0;//down                        }else if (mFirstY - mCurrentY > mTouchSlop){                            direction = 1;//up                        }                        if(direction == 1){                            if(mShow){                                toolbarAnimal(1);//隐藏toolBar                                mShow = !mShow;                            }                        }else if(direction == 0){                            if(!mShow){                                toolbarAnimal(0);//显示toolBar                                mShow = !mShow;                            }                        }                        break;                    case MotionEvent.ACTION_UP:                        break;                }                return false;            }        };        lv = (ListView) findViewById(R.id.lv);        View header = new View(this);        header.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,                (int)getResources().getDimension(R.dimen.abc_action_bar_default_height)));        lv.addHeaderView(header);        lv.setAdapter(new MyAdapter());        lv.setOnTouchListener(myTouchListener);        lv.setOnScrollListener(this);    }    /**     * 隐藏toolbar动画     * @param flag     */    private void toolbarAnimal(int flag) {        if(mAnimator != null && mAnimator.isRunning()){            mAnimator.cancel();        }        if(flag == 0){            mAnimator = ObjectAnimator.ofFloat(toolbar,"translationY",toolbar.getTranslationY(),0);        }else{            mAnimator = ObjectAnimator.ofFloat(toolbar,"translationY",toolbar.getTranslationY(),-toolbar.getHeight());        }        mAnimator.start();    }    /**     * 这里可以无视,是测试滑动状态     * @param view     * @param scrollState     */    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        switch (scrollState){            case NumberPicker.OnScrollListener.SCROLL_STATE_IDLE:                Log.e("SCROLL_STATE_IDLE","停止");                break;            case NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:                Log.e("SCROLL_STATE_TOUCH_SCROLL","滚动");                break;            case NumberPicker.OnScrollListener.SCROLL_STATE_FLING:                Log.e("SCROLL_STATE_FLING","惯性滑动");                break;        }    }    /**     * 这里是判断上滑或者listView滑动的位置     * @param view     * @param firstVisibleItem     * @param visibleItemCount     * @param totalItemCount     */    @Override    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {        if(firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0){            Log.e("滑到底部了", "滑到底部了");        }        if(firstVisibleItem > lastVisibleItem){            Log.e("正在上滑","正在上滑");        }else if(firstVisibleItem<lastVisibleItem){            Log.e("正在下滑","正在下滑");        }        if(firstVisibleItem == 0){            Log.e("滑动到第一项了","滑动到第一项了");        }        lastVisibleItem = firstVisibleItem;    }    class MyAdapter extends BaseAdapter{        @Override        public int getCount() {            return data.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) {            convertView = View.inflate(MainActivity.this,R.layout.activity_item,null);            TextView tv  = (TextView) convertView.findViewById(R.id.tv_content);            String tvData = data.get(position);            tv.setText(tvData);            return convertView;        }    }}

自定义ListView代码,这里主要实现的是弹性效果

public class MyListView extends ListView {    Context mContxt;    int mMaxOverDistance = 30;    public MyListView(Context context) {        this(context, null);    }    public MyListView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mContxt = context;        getmMaxOverDistance();    }    @Override    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxOverDistance, isTouchEvent);    }    //实用屏幕的density来计算具体的值,是为了让不同分辨率的弹性距离一致    public void getmMaxOverDistance(){        DisplayMetrics metrics = mContxt.getResources().getDisplayMetrics();        float density = metrics.density;        mMaxOverDistance = (int)(density*mMaxOverDistance);    }    @Override    public void setOnScrollChangeListener(OnScrollChangeListener l) {        super.setOnScrollChangeListener(l);    }}

项目下载地址https://github.com/GimiZhang/ListViewDemo.git

1 0