引言
在App日益追求体验的时代,优秀的用户体验往往会使产品脱颖而出。今天我们就来介绍一种简单的滑动ListView来显示或者隐藏ToolBar的功能。
布局文件
下面我们来看一下这个主界面的布局文件。在这个布局文件中,主要是一个ListView控件和一个ToolBar控件。布局如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <ListView 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 android:background="#f2f2f2" 11 android:divider="#abcdee" 12 android:dividerHeight="1px" 13 android:id="@+id/listView"> 14 15 </ListView> 16 17 <!--ToolBar--> 18 <android.support.v7.widget.Toolbar 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:background="#4097e6" 22 android:id="@+id/toolBar"> 23 24 </android.support.v7.widget.Toolbar> 25 26 </RelativeLayout>
主界面代码
实现思路:
让一个布局显示或者隐藏并且带有动画效果,我们可以通过属性动画来实现。实现这个效果的关键就是监听ListView的各种滑动事件,我们肯定需要借助View的OnTouchListener接口来监听各种状态。注意点:
由于增加了一个ToolBar,我们需要为ListView添加一个HeadView,防止ToolBar挡住ListView的第一个Item。
下面看代码实现:
1 package com.research.gong.android_view_research; 2 3 import android.animation.ObjectAnimator; 4 import android.app.Activity; 5 import android.os.Bundle; 6 import android.support.v7.widget.Toolbar; 7 import android.view.MotionEvent; 8 import android.view.View; 9 import android.view.ViewConfiguration; 10 import android.widget.AbsListView; 11 import android.widget.ArrayAdapter; 12 import android.widget.ListView; 13 14 public class MainActivity extends Activity { 15 16 private ListView listView; 17 String[] datas = {"A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", 18 "A11", "A12", "A13", "A14", "A15", "A16", "A17", "A18", "A19", "A20"}; 19 private float scaledTouchSlop; 20 private float firstY = 0; 21 private Toolbar toolbar; 22 private ObjectAnimator animtor; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 toolbar = (Toolbar) findViewById(R.id.toolBar); 29 listView = (ListView) findViewById(R.id.listView); 30 /** 31 * 添加一个HeadView避免第一个Item被ToolBar遮挡 32 * 必须在setAdapter之前进行设置 33 */ 34 initHeadView(); 35 listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, datas)); 36 //判断认为是滑动的最小距离(乘以系数调整滑动灵敏度) 37 scaledTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop()*3.0f; 38 /** 39 * 设置触摸事件 40 */ 41 listView.setOnTouchListener(new View.OnTouchListener() { 42 private float currentY; 43 private int direction=-1; 44 private boolean mShow = true; 45 46 @Override 47 public boolean onTouch(View v, MotionEvent event) { 48 switch (event.getAction()) { 49 case MotionEvent.ACTION_DOWN: 50 firstY = event.getY(); 51 break; 52 case MotionEvent.ACTION_MOVE: 53 currentY = event.getY(); 54 //向下滑动 55 if (currentY - firstY > scaledTouchSlop) { 56 direction = 0; 57 } 58 //向上滑动 59 else if (firstY - currentY > scaledTouchSlop) { 60 direction = 1; 61 } 62 //如果是向上滑动,并且ToolBar是显示的,就隐藏ToolBar 63 if (direction == 1) { 64 if (mShow) { 65 toobarAnim(1); 66 mShow = !mShow; 67 } 68 } else if (direction == 0) { 69 if (!mShow) { 70 toobarAnim(0); 71 mShow = !mShow; 72 } 73 } 74 break; 75 case MotionEvent.ACTION_UP: 76 break; 77 } 78 return false;//注意此处不能返回true,因为如果返回true,onTouchEvent就无法执行,导致的后果是ListView无法滑动 79 } 80 }); 81 } 82 83 84 /** 85 * 设置头布局,注意:这个头布局的高度要和ToolBar的高度一致 86 */ 87 public void initHeadView() { 88 View view = new View(this); 89 //abc_action_bar_default_height_material获取系统ActionBar的高度 90 AbsListView.LayoutParams params = new AbsListView.LayoutParams 91 (AbsListView.LayoutParams.MATCH_PARENT, 92 (int) getResources().getDimension(R.dimen.abc_action_bar_default_height_material)); 93 view.setLayoutParams(params); 94 listView.addHeaderView(view); 95 } 96 97 /** 98 * ToolBar显示隐藏动画 99 * @param direction 100 */ 101 public void toobarAnim(int direction) { 102 //开始新的动画之前要先取消以前的动画 103 if (animtor != null && animtor.isRunning()) { 104 animtor.cancel(); 105 } 106 //toolbar.getTranslationY()获取的是Toolbar距离自己顶部的距离 107 float translationY=toolbar.getTranslationY(); 108 if (direction == 0) { 109 animtor = ObjectAnimator.ofFloat(toolbar, "translationY", translationY, 0); 110 } else if (direction == 1) { 111 animtor = ObjectAnimator.ofFloat(toolbar, "translationY", translationY, -toolbar.getHeight()); 112 } 113 animtor.start(); 114 } 115 }
相信代码中注释已经解释的很详细了。唯一需要注意的是:scaledTouchSlop值默认获取的是Android系统能识别的最小滑动距离。我们通过乘以相关系数,可以适当的调整滑动的灵敏度。
时间: 2024-10-10 16:06:16