Reputation: 623
I'm using a NestedScrollView in a layout, and am attempting to use the new CoordinatorLayout from the design support library for CollapsingToolbarLayout.
My layout file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="200dp"
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="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!-- app:expandedTitleMarginEnd="64dp"-->
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@drawable/image_load_default_big" />
<android.support.v7.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/nestedScrollVw"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|enterAlways"
android:fitsSystemWindows="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:fitsSystemWindows="true">
<LinearLayout
android:id="@+id/changePasswordButtonContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/changePasswordExpand"
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="@drawable/back_img"
android:text="Change Your Password"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/changePasswordContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/changePasswordButtonContainer"
android:layout_centerInParent="true"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Edit Your Password"
android:textColor="@color/orange" />
<EditText
android:id="@+id/etUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/edittext_default_bg"
android:drawableLeft="@drawable/password_icon"
android:drawableRight="@drawable/tick"
android:hint=" Old Password"
android:padding="12dp"
android:password="true"
android:textColorHint="#b5b5b5" />
<EditText
android:id="@+id/etPass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/edittext_default_bg"
android:drawableLeft="@drawable/password_icon"
android:drawableRight="@drawable/cross"
android:hint=" New Password"
android:padding="12dp"
android:password="true"
android:textColorHint="#b5b5b5" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingTop="20dp"
android:text="show password" />
<Button
android:id="@+id/btnSingIn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="@drawable/login_button_background"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:text="Done"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/dealerToDealerContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/changePasswordContainer"
android:orientation="vertical">
<Button
android:id="@+id/dealerToDealerExpand"
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="@drawable/back_img"
android:text="Dealer To Dealer Platform No"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/dealerToDealerContainer"
android:layout_centerInParent="true"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Edit Number"
android:textColor="@color/orange" />
<EditText
android:id="@+id/dealerToDealerNo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/edittext_default_bg"
android:drawableLeft="@drawable/password_icon"
android:drawableRight="@drawable/tick"
android:hint=" 56546789"
android:padding="12dp"
android:password="true"
android:textColorHint="#b5b5b5" />
<Button
android:id="@+id/dealerToDealerNoDone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="@drawable/login_button_background"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:text="Done"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
When i try to scroll, sometimes it doesn't work. reason for this is, other elements of layout with click events are consuming the touch event. Basically EditText, RadioButton, Button are consuming touch events. Any Suggestions to solve this problem ?
Upvotes: 33
Views: 13128
Reputation: 610
The solution here (a workaround for this google issue by overriding the nestedScrollview) https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2 worked like a charm!
Define FixAppBarLayoutBehavior.java
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package your.package;
import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
/**
* Workaround AppBarLayout.Behavior for https://issuetracker.google.com/66996774
*
* See https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2 for
* example usage.
*
* Change the package name as you wish.
*/
public class FixAppBarLayoutBehavior extends AppBarLayout.Behavior {
public FixAppBarLayoutBehavior() {
super();
}
public FixAppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target,
int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, type);
stopNestedScrollIfNeeded(dyUnconsumed, child, target, type);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
View target, int dx, int dy, int[] consumed, int type) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
stopNestedScrollIfNeeded(dy, child, target, type);
}
private void stopNestedScrollIfNeeded(int dy, AppBarLayout child, View target, int type) {
if (type == ViewCompat.TYPE_NON_TOUCH) {
final int currOffset = getTopAndBottomOffset();
if ((dy < 0 && currOffset == 0)
|| (dy > 0 && currOffset == -child.getTotalScrollRange())) {
ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH);
}
}
}
}
Usage in java:
AppBarLayout abl = findViewById(R.id.app_bar);
((CoordinatorLayout.LayoutParams) abl.getLayoutParams()).setBehavior(new FixAppBarLayoutBehavior());
Usage in xml:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_height="..."
android:layout_width="..."
app:layout_behavior="your.package.FixAppBarLayoutBehavior">
</android.support.design.widget.AppBarLayout>
<!-- Content -->
</android.support.design.widget.CoordinatorLayout>
This is provided in the post Click not working on RecyclerView in CoordinatorLayout when scrolling.
Upvotes: 1
Reputation: 377
In your AndroidManifest.xml, make sure you have 'windowSoftInputMode' attribute set to 'adjustResize'.
<activity android:name=".activities.YourActivity" android:windowSoftInputMode="adjustResize">
Upvotes: 2
Reputation: 2282
I had the same problem. It happens only when NestedScrollView content height is less than height of device screen. So the workaround is to use setMinimumHeight(..)
method for the view inside your NestedScrollView
to make it resize to screen height:
DisplayMetrics displaymetrics = new DisplayMetrics();
getBaseActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenHeight = displaymetrics.heightPixels;
int actionBarHeight = 0;
TypedValue tv = new TypedValue();
if (getBaseActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
view.setMinimumHeight(screenHeight - actionBarHeight);
where view
is your RelativeLayout
It works fine fore me. Hope it helps you
Upvotes: 22
Reputation: 18276
One of your ScrollViews will send all events to the first View that answer true on dispatchMotionEvent.
You may avoid using such scenario in your app OR override all dispatchMotionEvent methods (from scrolls and Views) to not consume the ACTION_DOWN.
Upvotes: 2