Android底部操作栏,在使用软键盘时不会隐藏字段

时间:2014-10-20 13:00:41

标签: android android-layout android-actionbar

我正在使用以下方法禁用正常的顶部操作栏:

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">

&安培;我想使用底部操作栏来完成这个日历应用程序的完成/取消操作: enter image description here

但是当我尝试向scrollView中的editTexts写一些内容时,底部操作栏会隐藏字段,&amp;我想让它像下面的日历应用程序一样可见: enter image description here

那么,我怎样才能实现类似的行为?(因此打开软键盘时底部操作栏不会隐藏任何字段),

我正在使用这样的代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="true"
android:orientation="vertical"
android:weightSum="1">

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:fillViewport="false"
    android:id="@+id/formScrollView">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <!-- all form fields goes here -->
    </LinearLayout>

</ScrollView>

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:padding="@dimen/done_button_padding"
    android:id="@+id/happeningDoneLayout">

    <Button
        android:id="@+id/doneButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="@string/done"
        android:layout_alignParentBottom="true"/>
    <Button
        android:id="@+id/cancelButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:text="@string/cancel"
        android:layout_alignParentBottom="true"/>
</FrameLayout>

</RelativeLayout>

3 个答案:

答案 0 :(得分:2)

最简单的方法是在虚拟键盘出现时阻止调整大小:

    <activity
        android:name=".ShareFromDriveActivity_"
        android:hardwareAccelerated="true"
        android:label="@string/titleSharingCalendar"
        android:launchMode="standard"
        android:parentActivityName=".AppWidgetConfigure_"
        android:screenOrientation="sensor"
        android:theme="@style/Theme.Materialamberpurple"
        android:windowSoftInputMode="stateHidden|adjustPan" >
        <intent-filter>
            <action android:name="de.kashban.android.picturecalendar.INTENT_ACTION_SHARE_FROM_DRIVE" />
        </intent-filter>
    </activity>

重要的一行是 android:windowSoftInputMode =“stateHidden | adjustPan”。即使EditText具有焦点, stateHidden 也可确保在启动活动时不打开键盘。

您正在寻找

adjustPan :不再调整布局大小(包括您的下方按钮),但键盘将覆盖布局。仍然可以将它们滚动到可见部分,但是当键盘出现时,它们是不可见的。

来源:Android Guides

也许只有这个设置才能帮助你。

如果这还不够,你需要按钮真的不见了,试试这个:

// Detect soft keyboard visibility changes
final SoftKeyboardStateHelper softKeyboardStateHelper = 
        new SoftKeyboardStateHelper(lyt_share_from_drive_main);
softKeyboardStateHelper.addSoftKeyboardStateListener(this);

SoftKeyboardStateHelper 是Artem Zinnatullin的一个类,用于检测软键盘的状态变化:

/**
 * 
 */
package de.kashban.android.picturecalendar.util.local;

/**
 * @author Artem Zinnatullin
 * http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android/9108219#9108219
 * Usage: final SoftKeyboardStateHelper softKeyboardStateHelper = new SoftKeyboardStateHelper(findViewById(R.id.activity_main_layout);
 *        softKeyboardStateHelper.addSoftKeyboardStateListener(...);
 */
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;

import java.util.LinkedList;
import java.util.List;

public class SoftKeyboardStateHelper implements ViewTreeObserver.OnGlobalLayoutListener {

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);
        void onSoftKeyboardClosed();
    }

    private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
    private final View activityRootView;
    private int        lastSoftKeyboardHeightInPx;
    private boolean    isSoftKeyboardOpened;

    public SoftKeyboardStateHelper(View activityRootView) {
        this(activityRootView, false);
    }

    public SoftKeyboardStateHelper(View activityRootView, boolean isSoftKeyboardOpened) {
        this.activityRootView     = activityRootView;
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        final Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
            isSoftKeyboardOpened = true;
            notifyOnSoftKeyboardOpened(heightDiff);
        } else if (isSoftKeyboardOpened && heightDiff < 100) {
            isSoftKeyboardOpened = false;
            notifyOnSoftKeyboardClosed();
        }
    }

    public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
    }

    public boolean isSoftKeyboardOpened() {
        return isSoftKeyboardOpened;
    }

    /**
     * Default value is zero (0)
     * @return last saved keyboard height in px
     */
    public int getLastSoftKeyboardHeightInPx() {
        return lastSoftKeyboardHeightInPx;
    }

    public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.add(listener);
    }

    public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.remove(listener);
    }

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;

        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardOpened(keyboardHeightInPx);
            }
        }
    }

    private void notifyOnSoftKeyboardClosed() {
        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardClosed();
            }
        }
    }
}

在您的活动中实现Interface SoftKeyboardStateListener 并覆盖这些方法:

@Override
public void onSoftKeyboardOpened(int keyboardHeightInPx) {
    if (D.DEBUG_APP) Log.d(TAG, "onSoftKeyboardOpened() called with keyboard height " + keyboardHeightInPx);
    rdgVisibility.setVisibility(View.GONE);
    if (tvPermissionLabel != null)
        tvPermissionLabel.setVisibility(View.GONE);
    lyt_ShareDriveOkCancel.setVisibility(View.GONE);
    cbShareWithDev.setVisibility(View.GONE);

}

@Override
public void onSoftKeyboardClosed() {
    if (D.DEBUG_APP) Log.d(TAG, "onSoftKeyboardClosed() called.");
    rdgVisibility.setVisibility(View.VISIBLE);
    if (tvPermissionLabel != null)
        tvPermissionLabel.setVisibility(View.VISIBLE);
    lyt_ShareDriveOkCancel.setVisibility(View.VISIBLE);
    cbShareWithDev.setVisibility(View.VISIBLE);
}

在这两种方法中,相应地更改下方按钮的可见性。完成。

以下是我在应用中的显示效果:

Full Dialog Screenshot

键盘已关闭,完整布局可见

Most Controls hidden Screenshot

键盘已打开,但EditText的所有控件都已消失。原因是EditText可以跨越几行,而在小屏幕上,它太杂乱了整个布局。

答案 1 :(得分:1)

Android Keyboard hides EditText

机器人:windowSoftInputMode =&#34; adjustPan | adjustResize&#34;

这应该会给你你想要的效果。把它放在相关活动的清单中。

答案 2 :(得分:1)

要确保底部操作栏不会隐藏任何其他控件,ScrollView和栏可以堆叠成垂直线性布局。这样,当键盘出现/消失时,ScrollView可以缩小/展开聚焦控件,同时保持底部操作栏始终显示在ScrollView下方屏幕的底部。

adjustPan不应与此解决方案一起使用。

权重的分布使得ScrollView是动态改变其高度的部分。

这是代码的最小化样本:

<?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">


        <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/formScrollView"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            ... >

                ...

        </ScrollView>

        <FrameLayout
            android:id="@+id/bottomBar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            ... >

                ...

        </FrameLayout>

    </LinearLayout>