NestedScrollView realizes the effect of sliding up to hide/showing down the layout
First on the renderings:
To achieve this effect, you need to use NestedScrollView
sliding components and attribute animation ViewPropertyAnimator
.
So let’s get started:
The first step: Of course, it is to write the layout file. This is what I used to write the demo, for reference only:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<androidx.core.widget.NestedScrollView
android:id="@+id/nv_fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="140dp"
android:layout_marginTop="10dp"
app:banner_indicator_selected_color="#ffffff"
app:banner_infinite_loop="true"
app:banner_loop_time="4000"
app:banner_orientation="horizontal"
app:banner_radius="10dp" />
<include
layout="@layout/layout_complex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp" />
<include
layout="@layout/layout_recomment_song_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<include
layout="@layout/layout_recommend_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp" />
<include
layout="@layout/layout_recommend_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
...
</RelativeLayout>
Step 2: Initialize the NestScrollView
control and set up the NestedScrollView.OnScrollChangeListener
listener
I Fragment
initialized it in, the following is the simplified code:
public class MainFragment extends BaseFragment implements NestedScrollView.OnScrollChangeListener{
/**
* 滑动相关
*/
private NestedScrollView mNestScrollView;
private float viewY; // player垂直平移的距离
private boolean isAnimate;
/**
* 底部player布局(从Activity中获取到的)
*/
private RelativeLayout mRlPlayer;
private MainActivity mActivity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, BundlesavedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
init();
return view;
}
public void init(){
mActivity = (MainActivity) getActivity();
mNestScrollView = view.findViewById(R.id.nv_fragment_main);
// 设置滑动监听器
mNestScrollView.setOnScrollChangeListener(this);
mRlPlayer = mActivity.findViewById(R.id.rl_main_player);
}
/**
* 监听NestScrollView的滑动
*
* @param v
* @param scrollX X滑动原点
* @param scrollY Y滑动原点
* @param oldScrollX 上一个X滑动原点
* @param oldScrollY 上一个Y滑动原点
*/
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
// 垂直方向滚动的差值
int dy = scrollY - oldScrollY;
if (dy > 0 && !mActivity.isAnimate()) {
// 大于0表示上滑
// 向下隐藏player
mActivity.hidePlayer(mRlPlayer);
} else if (dy < 0 && !mActivity.isAnimate()) {
// 小于0表示下滑
// 向上显示player
mActivity.showPlayer(mRlPlayer);
}
}
}
The third step: a way to achieve both animation hidePlayer()
andshowPlayer()
/**
* 隐藏player视图
* 动画:向下隐藏player布局
*
* @param view player布局
*/
public void hidePlayer(View view) {
// 创建一个属性动画,做translationY动画
ViewPropertyAnimator animator = view.animate()
// 平移到 y == viewY处
.translationY(mRlPlayer.getHeight() + 100)
// 设置插值器
.setInterpolator(new FastOutSlowInInterpolator())
.setDuration(300);
// 监听动画
animator.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
isAnimate = true;
//Log.d(TAG, "hide onAnimationStart: " + "isAnimate = " + isAnimate);
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimate = false;
//view.setVisibility(View.INVISIBLE);
Log.d(TAG, "hide onAnimationStart: " + "isAnimate = " + isAnimate);
}
@Override
public void onAnimationCancel(Animator animation) {
showPlayer(view);
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
}
/**
* 显示player视图
* 动画:向上显示player
*
* @param view player布局
*/
public void showPlayer(View view) {
ViewPropertyAnimator animator = view.animate()
// 平移到 y == 0处
.translationY(0)
.setInterpolator(new FastOutSlowInInterpolator())
.setDuration(300);
animator.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
isAnimate = true;
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimate = false;
}
@Override
public void onAnimationCancel(Animator animation) {
hidePlayer(view);
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
}
OKK, get it done! ! !