6
votes

I have an activity which has a layout content as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="?attr/colorPrimary"
     android:minHeight="?attr/actionBarSize"
     style="@style/ToolBarStyle.Event" />

    <com.mypackage.corecode.ui.view.SlidingTabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary_color" />

    <android.support.v4.view.ViewPager
        android:id="@+id/vendor_main_tabview_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

And inside viewpager, I have a fragment which has the following layout:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:weightSum="3"
                        android:orientation="horizontal">

                        <EditText
                            android:theme="@style/ScrollableContentThemeNoActionBar"
                            android:id="@+id/edit_text_vendor_sms_phone_number"
                            android:layout_width="0dp"
                            android:layout_weight="2"
                            android:layout_height="wrap_content"
                            android:inputType="number" />

                        <Button
                            android:id="@+id/button_send_sms"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:layout_height="wrap_content"
                            />
                    </LinearLayout>
         </LinearLayout>
 </ScrollView>

When the content inside the fragment doesn't fit the screen, the scrollview allows the user to see the content which is below the screen. (Works as expected)

The problem is when the edittext gets focus, the keyboard overlaps the edittext area, rather than the scrollview causing the content to scroll.

I expect the fragment to handle keyboard shown and scrollview to fit the keyboard on the screen.

Or am I wrong and is activity responsible for the keyboard? Since the root view in activity layout is linearlayout, is it restricting the expansion?

I tried wrapping the whole content of the activity layout with a scrollview, but this time viewpager doesnt appear on the screen if I don't give it a fixed size. Even when I do, I end up having a scrollview inside the fragment which is under the scrollview of the main layout and still keyboard is hovering over the edittext.

I'm a bit lost here, my objective is to be able to scroll the fragment content when the edittext gets focused, but rather the keyboard overlaps the edittext currently.

4
have you tried android:windowSoftInputMode="adjustResize|adjustPan"?muratgu
Yes i have tried adding these in the manifest for the activity, if thats what you mean, but no luckMehmet Katircioglu
can you provide the code of your activities to test your issue?tsiro
Remove adjustResize from adjustResize | adjustPan. And then try. Use only adjustPan.Anish Mittal

4 Answers

7
votes

I may mistake, but it's probably because of known Android bug, all you need is to add next 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 Activity that holds ViewPager and SlidingTabLayout:

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

For more background check this thread.

1
votes

I had similar problem with a ListView inside a ScrollView. You need to add a similar OnTouchListener with your ScrollView inside OnCrateView.

myList.setOnTouchListener(new ListView.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            // Disallow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(true);
            break;

            case MotionEvent.ACTION_UP:
            // Allow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }

        // Handle ListView touch events.
        v.onTouchEvent(event);
        return true;
    }
});

Here's another SO Answer which might help you.

0
votes

I think you need to use adjustPan or adjustResize for automatic adjustment of space when a keyboard is shown. According to the doc :

"adjustResize" The activity's main window is always resized to make room for the soft keyboard on screen.

"adjustPan" The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window.

You can declare one of these in your manifest under activity tag like this : android:windowSoftInputMode="stateUnchanged|adjustResize

I hope this will cover your requirement.

0
votes

You have to create sub class of ViewPager then override the onTouchEvent as shown in this