5

ok im already doing (i believe) everything i need to do to make my applications layout scroll/move up when the soft keyboard is shown but it is not working so im guessing there must be something im doing stopping it, i wonder if its the fixed heights im giving my viewpagers or something im unaware of, ive read through posts that describe relative layouts as 'crushing child views' when the keyboard is shown and linear layouts not crushing child views, so with that in mind here are my layouts

MAIN_ACTIVITY

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:id="@+id/viewpagerHolder">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager2"
            android:layout_width="match_parent"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginTop="8dp"
            android:layout_height="@dimen/card_pager_height" />

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/predictsHolder"
            android:layout_below="@id/viewpager2">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager_predicts"
            android:layout_width="wrap_content"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginTop="4dp"
            android:layout_height="@dimen/predicts_pager_height" />

        </RelativeLayout>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/predictsHolder"
            app:tabGravity="fill"
            android:theme="@style/CustomTabLayoutStyle" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/tabs">


        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:background="@color/windowBackground"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
             />

        </LinearLayout>

    </RelativeLayout>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize" />

</android.support.design.widget.AppBarLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="@dimen/card_pager_height">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="12dp"
        android:layout_marginEnd="12dp"
        app:elevation="4dp"
        android:src="@drawable/ic_playlist_play_white_24dp"
        android:layout_gravity="right|top"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>

</RelativeLayout>

</android.support.design.widget.CoordinatorLayout>

There a total of 3 viewpagers each has a different layout the first (top most)

FIRST VIEWPAGER

<RelativeLayout 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:background="@drawable/border"
android:paddingLeft="2dp"
android:paddingRight="2dp"
tools:context=".SpeakGridDB">

<android.support.v7.widget.RecyclerView
    android:id="@+id/card_speak_grid"
    android:layout_width="match_parent"
    android:layout_gravity="center"
    android:layout_height="wrap_content"/>

</RelativeLayout>

SECOND VIEWPAGER

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:background="@drawable/border">

<android.support.v7.widget.RecyclerView
    android:id="@+id/predicts_card_speak_grid"
    android:layout_width="match_parent"
    android:layout_gravity="center"
    android:layout_height="wrap_content"/>

</RelativeLayout>

THIRD VIEWPAGER

i would like this layout to still be present when the keyboard pops up its currently the bottom of the layout ive put it in a linear layout and also tried putting its viewpager in a linear layout

<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="wrap_content"
android:orientation="vertical"
android:background="@color/windowBackground"
tools:context=".OneFragment">

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/activity_main_swipe_refresh_layout"
    android:layout_width="match_parent"
    android:background="@color/windowBackground"
    android:layout_height="wrap_content">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/card_grid"
        android:background="@color/windowBackground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"/>

</android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

I'm also using

        android:windowSoftInputMode="adjustResize"

in my manifest and have also tried

        android:windowSoftInputMode="adjustPan"

but no joy it seems like the tabLayout shifts up slightly when keyboard is shown but generally the top two views stay in place and the bottom one (one i want shown) is hidden by the keyboard any help is appreciated

UPDATE still no further with this i can make a layout witht the fixed heights and have it scroll up perfectly with the softkeyboard shown so there not the problem but i must use layout center vertical on an element and this isnt what i want to do ive also tried wrapping it all in a scroll view and using isScrollContainer true but still no joy anyone got any ideas?

Martin Seal
  • 616
  • 2
  • 14
  • 32

2 Answers2

4

I may mistake, but cause of this problem is probably the known Android bug.

So, firstly, you need to add android:windowSoftInputMode="stateHidden|adjustResize" inside your <activity> tag.

Secondly, you need to add this class to your project:

public class AndroidBug5497Workaround {

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout)  activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }

}

And then simply use it by calling assistActivity() method in your MainActivity that holds ViewPagers:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(...);
    AndroidBug5497Workaround.assistActivity(this);
    ...
}

For more background check this thread.

Community
  • 1
  • 1
romtsn
  • 11,704
  • 2
  • 31
  • 49
  • hi @rom4ek first thank you and what a great name for this class lol ive stuck it in and when the keyboard is shown the layout changes but not as i was looking for, when keyboard is hidden the layout goes back to normal, did you create this? if so what am i going to need to try and adjust to get this perfect im guessing its something on this line frameLayoutParams.height = usableHeightSansKeyboard - heightDifference; right now i just end up with a blank screen – Martin Seal Jan 10 '17 at 22:07
  • So when your keyboard is shown you have a blank screen right? – romtsn Jan 11 '17 at 03:32
  • It's not blank no sorry it's actually my background of the layout holding the viewpagers I changed the line to this frameLayoutParams.height = usableHeightSansKeyboard - heightDifference/2; and I can still see half of the top of my layout (obviously) – Martin Seal Jan 11 '17 at 13:25
  • I still haven't come up with a plausible fix for this but have awarded yours as correct as this may the start of my workaround thanks for your time and effort – Martin Seal Jan 17 '17 at 23:48
  • Thank you. One more approach in addition to my answer - try to use `android.support.design.internal.ScrimInsetsFrameLayout` instead of `RelativeLayout` with scrolling behavior. Don't have enough time to run into your issue deeply, sorry. – romtsn Jan 18 '17 at 04:10
0

You can try adding android:fitsSystemWindows="true" to your coordinator layout

N00b Pr0grammer
  • 4,503
  • 5
  • 32
  • 46
Nainal
  • 1,728
  • 14
  • 27