MapFragment
内に視差効果を持つAppBarLayout
があります:
地図上のタッチイベントは常にスクロールイベントとして処理されるため、AppBarLayout
でのスクロールを無効にします。画面の下部にあるAppBarLayout
のみをスクロールして、RecyclerView
の折りたたみを処理したいと思います。
これは私のxmlです:
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:fitsSystemWindows="true"
app:contentScrim="@color/white"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:titleEnabled="false">
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_collapseMode="parallax"
Android:fitsSystemWindows="true">
<fragment
Android:id="@+id/map"
Android:name="com.androidmapsextensions.SupportMapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</FrameLayout>
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="73dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<include
Android:id="@+id/search_bar"
layout="@layout/layout_searchbar" />
</Android.support.v7.widget.Toolbar>
<View
Android:id="@+id/toolbar_shadow"
Android:layout_width="match_parent"
Android:layout_height="3dp"
Android:layout_below="@id/search_bar"
Android:layout_gravity="bottom"
Android:background="@drawable/toolbar_dropshadow"
Android:visibility="gone" />
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<RecyclerView
Android:id="@+id/farm_list"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@Android:color/transparent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
回答ありがとうございます。
入手したかどうかはわかりませんが、DragCallback
を探していると思います。
DragCallback
インターフェイスを使用すると、AppBarLayout
へのスクロールによって兄弟スクロールビューを制御するかどうかを選択できます。
以下を呼び出すことで定義できます:
_CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false;
}
});
_
常にfalse
を返すことにより、スクロールビューはABLによって制御されなくなります。
注:これを呼び出す前に、ViewCompat.isLaidOut(appBarLayout)
を確認する必要があります。そうでない場合、params.getBehavior()
はnullを返します。
問題
ソリューション
AppBarLayoutの「ドラッグ」動作を無効にします。
// Disable "Drag" for AppBarLayout (i.e. User can't scroll appBarLayout by directly touching appBarLayout - User can only scroll appBarLayout by only using scrollContent)
if (appBarLayout.getLayoutParams() != null) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior appBarLayoutBehaviour = new AppBarLayout.Behavior();
appBarLayoutBehaviour.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false;
}
});
layoutParams.setBehavior(appBarLayoutBehaviour);
}
参照
これは、上記の「natario」の受け入れられた答えの単なる拡張です。
これを実現するには、xmlでカスタムapp:layout_behavior
を定義します。このアプローチを使用すると、LayoutParams
への参照を取得したり、nullチェックを実行したりする必要がなくなります。
<Android.support.design.widget.AppBarLayout
Android:id="@+id/app_bar_layout"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="com.yourcompany.FixedAppBarLayoutBehavior"
>
次に、AppBarLayout.Behavior
から拡張するカスタムクラスを作成します。
public class FixedAppBarLayoutBehavior extends AppBarLayout.Behavior {
public FixedAppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
setDragCallback(new DragCallback() {
@Override public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false;
}
});
}
}
Kotlinバージョンで更新:
class FixedAppBarLayoutBehavior(context: Context, attrs: AttributeSet) : AppBarLayout.Behavior(context, attrs) {
init {
setDragCallback(object : DragCallback() {
override fun canDrag(appBarLayout: AppBarLayout): Boolean = false
})
}
}
だから、2時間試した後、私は解決策を見つけました。これは非常に簡単です。クラスが次のようになるように、CoordinatorLayout
を拡張し、OnInterceptTouchEvent
メソッドをオーバーライドする必要がありました。
public class NonTouchableCoordinatorLayout extends CoordinatorLayout {
public NonTouchableCoordinatorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
NestedScrollView.setNestedScrollingEnabled(false)
を使用して、AppBarLayoutのnext Scrollイベントを無効にできます。