页面截图:
java代码:
MainActivity:
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity implements MyScrollView.ScrollChangedListener {
MyScrollView myScrollview;
LinearLayout lineAddNavigationSuspension;
LinearLayout lineAddNavigationFixation;
View titleView;
View navigation;
int statusBarHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myScrollview = findViewById(R.id.myScrollview);
myScrollview.setListener(this::onScrollChanged);
titleView = findViewById(R.id.titleView);
navigation = findViewById(R.id.navigation);
lineAddNavigationSuspension = findViewById(R.id.lineAddNavigationSuspension);
lineAddNavigationFixation = findViewById(R.id.lineAddNavigationFixation);
}
@Override
public void onScrollChanged(int scrollX, int scrollY, int oldl, int oldt) {
int[] location = new int[2];
lineAddNavigationFixation.getLocationOnScreen(location);
//lineAddNavigationFixation是包裹导航栏的LinearLayout
int y = location[1];//导航栏距屏幕顶部的距离,会随着scrollview的滑动而改变
if (y <= titleView.getHeight() + getStatusHeight()) {//导航栏距屏幕顶部的距离小于等于标题栏的高度时 悬浮,即上滑到紧贴标题栏时 悬浮
addNavigationSuspension();
} else {//反之下滑到距离大于标题栏的高度时放回原来的位置
addNavigationFixation();
}
}
private void addNavigationSuspension() {
if (lineAddNavigationSuspension.getChildCount() == 0) {
if (navigation.getParent() != null)
((ViewGroup) navigation.getParent()).removeView(navigation);
lineAddNavigationSuspension.addView(navigation);
}
}
private void addNavigationFixation() {
if (lineAddNavigationFixation.getChildCount() == 0) {
if (navigation.getParent() != null)
((ViewGroup) navigation.getParent()).removeView(navigation);
lineAddNavigationFixation.addView(navigation);
}
}
/**
* 状态栏高度
* @return
*/
private int getStatusHeight() {
if (statusBarHeight == 0) {
Rect rect = new Rect();
this.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
return statusBarHeight = rect.top; //状态栏高度
} else return statusBarHeight;
}
}
MyScrollView:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
/**
* author:xxf
*/
public class MyScrollView extends ScrollView {
public ScrollChangedListener listener;
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (listener != null)
listener.onScrollChanged(l, t, oldl, oldt);
}
public void setListener(ScrollChangedListener listener) {
this.listener = listener;
}
public static interface ScrollChangedListener {
void onScrollChanged(int l, int t, int oldl, int oldt);
}
}
activity_main.xm l代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--标题栏-->
<TextView
android:id="@+id/titleView"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="标题栏"
android:background="#aaa"
android:gravity="center"/>
<!--内容布局最外层使用FrameLayout-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--下面是自定义scrollview-->
<com.xxfen.ceilinglayoutdemo.MyScrollView
android:id="@+id/myScrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:focusable="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:background="#bcc" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="头部内容"
android:background="#bac"
android:gravity="center"/>
</LinearLayout>
<!--下面LinearLayout用于包裹导航栏控件-->
<LinearLayout
android:id="@+id/lineAddNavigationFixation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
<TextView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="导航栏"
android:background="#bee"
android:gravity="center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:text="内容块"
android:gravity="center"
android:background="#bbe" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:text="内容块"
android:gravity="center"
android:background="#bbe" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:text="内容块"
android:gravity="center"
android:background="#bbe" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:text="内容块"
android:gravity="center"
android:background="#bbe" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:text="内容块"
android:gravity="center"
android:background="#bbe" />
</LinearLayout>
</LinearLayout>
</com.xxfen.ceilinglayoutdemo.MyScrollView>
<!--下面LinearLayout用于占位-->
<LinearLayout
android:id="@+id/lineAddNavigationSuspension"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
</LinearLayout>
|