NestedScrollView se da cuenta del efecto de deslizarse hacia arriba para ocultar / mostrar el diseño
Primero en las representaciones:
Para lograr este efecto, debe utilizar NestedScrollView
componentes deslizantes y animación de atributos ViewPropertyAnimator
.
Entonces empecemos:
El primer paso: por supuesto, es escribir el archivo de diseño. Esto es lo que usé para escribir la demostración, solo como referencia:
<?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>
Paso 2: inicializar el NestScrollView
control y configurar el NestedScrollView.OnScrollChangeListener
oyente
Lo Fragment
inicialicé, el siguiente es el código simplificado:
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);
}
}
}
El tercer paso: una forma de lograr tanto la animación hidePlayer()
comoshowPlayer()
/**
* 隐藏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, ¡hazlo! ! !