学习了Android有一段时间了,学习的东西老是遗忘,于是决定写博客来巩固知识点,激励自己学习。
由于会使用到ObjectAnimator,我们先对ObjectAnimator进行了解:
ObjectAnimator是属性动画,是ValueAnimator的子类,他本身就已经包含时间引擎和值的计算,所以它拥有为对象的某个属性设置动画的功能。
ObjectAnmator中提供ofInt,ofFloat的方法,其参数为:
(操作对象,属性名,动画开始,动画结束)
属性名一般为alpha,translateY,translateX,rotateX,rotateY,scaleX,scaleY
下面举个例子:
ObjectAnimator animator = ObjectAnimator.ofFloat(imageBall,"alpha",0f,1f);//透明度从0-1效果
animator.setDuration(500).start();//持续时间为500ms
接下来我们来实现自动显示、隐藏布局的ListView。
首先我们要在styles.xml中设置NoActionBar:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
为了避免第一个Item被Toolbar遮挡,需要给ListView增加一个HeaderView:
//获取headerView
View header = new View(this);
//宽为match_parent,高为获取系统Actionbar
header.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
(R.dimen.abc_action_bar_default_height_material)));//R.dimen.abc_action_bar_default_height_material获取属性Actionbar的高度
listView.addHeaderView(header);//增加一个HeaderView避免Item被Toolbar被遮挡
我们还需要定义一个mTouchSlop来获取系统认为的最低滑动距离,即超过这个距离就是滑动状态了:
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();//获取滑动的最小距离
接下来为关键代码用来判断滑动事件
private void scorllEvent() {
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN: {
mFirstY = (int) motionEvent.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
mCurrentY = (int) motionEvent.getY();
if (mCurrentY - mFirstY > mTouchSlop) {
//向下滑动
direction = 0;
} else
//向上滑动
{
direction = 1;
}
if (direction == 1) {
if (mShow) {
ToolbarAnim(0);//显示
mShow = false;
}
} else {
if (!mShow) {
ToolbarAnim(1);//隐藏
mShow = true;
}
}
break;
}
}
return false;
}
});
}
最后加上控制动画
private void ToolbarAnim(int i) {
if (animator != null && animator.isRunning())
animator.cancel();
if (i == 0) {//显示
animator = ObjectAnimator.ofFloat(
toolbar,
"translationY",
toolbar.getTranslationY(),
0);
Log.d("tag", "下滑" + toolbar.getTranslationY());
} else {//隐藏
animator = ObjectAnimator.ofFloat(
toolbar,
"translationY",
toolbar.getTranslationY(),
-toolbar.getHeight());
Log.d("tag", "上滑getTranslationY" + toolbar.getTranslationY());
Log.d("tag", "上滑getHeight()" + toolbar.getHeight());
}
animator.start();
}
}
上滑效果图
下滑效果图
如下通过打印查看滑动距离
通过打印内容可以看出上滑距离由0~-56,下滑距离由-56~0
布局文件如下:
<?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">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:background="@android:color/holo_blue_dark"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
完整代码如下:
public class MainActivity extends AppCompatActivity {
private ListView listView;
private List<String> list;
private Toolbar toolbar;
private int mTouchSlop;//系统认为的最小滑动距离
private int mFirstY;//第一次点击的位置
private int mCurrentY;//当前点击的Y轴位置
private boolean mShow = true;//当前是否显示
private int direction;
private ObjectAnimator animator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
listView = (ListView) findViewById(R.id.list_view);
list = new ArrayList<String>();
for (int i = 0; i < 20; i++) {
list.add(i + "");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
listView.setAdapter(adapter);
//获取headerView
View header = new View(this);
//宽为match_parent,高为获取系统Actionbar
header.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
(int) getResources().getDimension(R.dimen.abc_action_bar_default_height_material)));//R.dimen.abc_action_bar_default_height_material获取属性Actionbar的高度
listView.addHeaderView(header);//增加一个HeaderView避免Item被Toolbar被遮挡
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();//获取滑动的最小距离
scorllEvent();
}
private void scorllEvent() {
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN: {
mFirstY = (int) motionEvent.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
mCurrentY = (int) motionEvent.getY();
if (mCurrentY - mFirstY > mTouchSlop) {
//向下滑动
direction = 0;
} else
//向上滑动
{
direction = 1;
}
if (direction == 1) {
if (mShow) {
ToolbarAnim(0);//显示
mShow = false;
}
} else {
if (!mShow) {
ToolbarAnim(1);//隐藏
mShow = true;
}
}
break;
}
}
return false;
}
});
}
private void ToolbarAnim(int i) {
if (animator != null && animator.isRunning())
animator.cancel();
if (i == 0) {//向下滑动显示
animator = ObjectAnimator.ofFloat(
toolbar,
"translationY",
toolbar.getTranslationY(),
0);
} else {
animator = ObjectAnimator.ofFloat(//向上滑动隐藏
toolbar,
"translationY",
toolbar.getTranslationY(),
-toolbar.getHeight());
}
animator.start();
}
}
以上就是ListView自动显示、隐藏布局的方法。