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

效果图,gif图片看起来略卡顿,实际很流畅
【实现ListView的弹性效果,下拉隐藏ToolBar(ActionBar),上拉显示ToolBar】实现ListView的弹性效果,下拉隐藏ToolBar(ActionBar),上拉显示ToolBar
文章图片

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、布局文件

Item布局文件

主界面的代码实现
public class MainActivity extends ActionBarActivity implements AbsListView.OnScrollListener {public ArrayList data= https://www.it610.com/article/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

自定义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

    推荐阅读