Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android move layout up when soft keyboard is shown with viewpagers

Tags:

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?

like image 875
Martin Seal Avatar asked Dec 06 '16 00:12

Martin Seal


1 Answers

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.

like image 176
romtsn Avatar answered Sep 25 '22 17:09

romtsn