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

效果图,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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值