当 BottomSheet 在 BottomNavigationView 后面时,Google 地图应用程序如何让您拖动它?
How does the Google Maps app let you drag the BottomSheet when it's behind the BottomNavigationView?
观看此视频,您就会知道我在说什么。注意 BottomSheet
即使在 BottomNavigationView
后面也可以被拖动:
我想做同样的事情,但使用包含 Button
的 LinearLayout
。我已经尝试了很多东西并且 none 工作。我已经对 LinearLayout
进行了子类化,以便我可以覆盖 onInterceptTouchEvent
,并且我正在使用 GestureListener
来检测卷轴。
我已经在 Github 上发布了一个准系统测试项目:
https://github.com/gavingt/BottomSheetTest
或者您可以查看下面的相关代码:
这是MyLinearLayout
:
public class MyLinearLayout extends LinearLayout {
GestureDetector gestureDetector;
boolean isScrolling = false;
public MyLinearLayout(Context context) {
super(context);
gestureDetector = new GestureDetector(context, new MyGestureListener());
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
gestureDetector = new GestureDetector(context, new MyGestureListener());
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
gestureDetector = new GestureDetector(context, new MyGestureListener());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
gestureDetector.onTouchEvent(ev);
return isScrolling;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
isScrolling = gestureDetector.onTouchEvent(ev);
return isScrolling;
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("TAG", "onScroll: ");
return true;
}
}
}
这里是 activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F00"
android:overScrollMode="never"
app:behavior_hideable="false"
app:behavior_peekHeight="262dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"/>
<com.gavinsappcreations.bottomsheettest.MyLinearLayout
android:layout_gravity="bottom"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/first_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:drawableLeft="@android:drawable/btn_radio"
android:drawablePadding="2dp"
android:maxLines="1"
android:backgroundTint="#00F"
android:paddingLeft="9dp"
android:paddingRight="10dp"
android:text="first button"
android:textAllCaps="false"
android:textSize="17dp"/>
<Button
android:id="@+id/second_button"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginLeft="50dp"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:backgroundTint="#00F"
android:drawablePadding="2dp"
android:drawableRight="@android:drawable/btn_radio"
android:maxLines="1"
android:paddingLeft="8dp"
android:paddingRight="5dp"
android:text="second button"
android:textAllCaps="false"
android:textSize="16dp"/>
</com.gavinsappcreations.bottomsheettest.MyLinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
你能试试这个吗:
- 在
LinearLayout
下方和 google maps fragment
上方设置一个 transparent RelativeLayout
。
- 当这个
transparent RelativeLayout
是 touched
然后将焦点设置到 google maps fragment
- 如果
LinearLayout
被触摸然后将 focus
改回它。
希望这对您有所帮助。
感谢a Reddit user,我已经解决了这个问题。
解决方案是使用他的 DelegatingLayout:
https://gist.github.com/davidliu/c246a717f00494a6ad237a592a3cea4f
查看 Github 项目的完整实现:
观看此视频,您就会知道我在说什么。注意 BottomSheet
即使在 BottomNavigationView
后面也可以被拖动:
我想做同样的事情,但使用包含 Button
的 LinearLayout
。我已经尝试了很多东西并且 none 工作。我已经对 LinearLayout
进行了子类化,以便我可以覆盖 onInterceptTouchEvent
,并且我正在使用 GestureListener
来检测卷轴。
我已经在 Github 上发布了一个准系统测试项目:
https://github.com/gavingt/BottomSheetTest
或者您可以查看下面的相关代码:
这是MyLinearLayout
:
public class MyLinearLayout extends LinearLayout {
GestureDetector gestureDetector;
boolean isScrolling = false;
public MyLinearLayout(Context context) {
super(context);
gestureDetector = new GestureDetector(context, new MyGestureListener());
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
gestureDetector = new GestureDetector(context, new MyGestureListener());
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
gestureDetector = new GestureDetector(context, new MyGestureListener());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
gestureDetector.onTouchEvent(ev);
return isScrolling;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
isScrolling = gestureDetector.onTouchEvent(ev);
return isScrolling;
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("TAG", "onScroll: ");
return true;
}
}
}
这里是 activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F00"
android:overScrollMode="never"
app:behavior_hideable="false"
app:behavior_peekHeight="262dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"/>
<com.gavinsappcreations.bottomsheettest.MyLinearLayout
android:layout_gravity="bottom"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/first_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:drawableLeft="@android:drawable/btn_radio"
android:drawablePadding="2dp"
android:maxLines="1"
android:backgroundTint="#00F"
android:paddingLeft="9dp"
android:paddingRight="10dp"
android:text="first button"
android:textAllCaps="false"
android:textSize="17dp"/>
<Button
android:id="@+id/second_button"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginLeft="50dp"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:backgroundTint="#00F"
android:drawablePadding="2dp"
android:drawableRight="@android:drawable/btn_radio"
android:maxLines="1"
android:paddingLeft="8dp"
android:paddingRight="5dp"
android:text="second button"
android:textAllCaps="false"
android:textSize="16dp"/>
</com.gavinsappcreations.bottomsheettest.MyLinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
你能试试这个吗:
- 在
LinearLayout
下方和google maps fragment
上方设置一个transparent RelativeLayout
。 - 当这个
transparent RelativeLayout
是touched
然后将焦点设置到google maps fragment
- 如果
LinearLayout
被触摸然后将focus
改回它。
希望这对您有所帮助。
感谢a Reddit user,我已经解决了这个问题。
解决方案是使用他的 DelegatingLayout:
https://gist.github.com/davidliu/c246a717f00494a6ad237a592a3cea4f
查看 Github 项目的完整实现: