显示键盘时向上推除某些视图之外的内容
Push up content except some view when keyboard shown
我的布局在底部包含 5 个 EditText
和一个 Button
以及一个 TextView
。现在,当我按下 EditText
时,键盘将显示并且 all 我的 View
被向上推。
现在我不想把我的 TextView
和 Button
推到键盘上方,只想 全部推上去 EditText
里面 ScrollView
到键盘上方。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
/>
</LinearLayout>
</ScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="I don't want to push this TextView and Button to above keyboard when keyboard is shown. Just obly want to push the ScrollView that contain all EditText"
/>
</LinearLayout>
我有个想法是。当键盘显示和隐藏时我会监听。当键盘显示时,我将设置 ScrollView 的底部边距 = 键盘高度,当键盘隐藏时,我将设置此边距 = 0.
有什么方法更容易处理我的案子吗?任何帮助或建议将不胜感激。
更新
如果我使用 windowSoftInputMode=adjustPan
=> 并非所有 EditText
都被推到键盘上方
如果我使用 windowSoftInputMode=adjustResize
=> Button
、TextView
并且所有 EditText
都被推到键盘上方
不起作用 - 没有可靠的 API 来检测何时显示键盘。您会在此站点上看到 "solutions",但它们有误报和漏报。但似乎对您来说最好的办法是将 softInputMode 设置为 adjustPan。这将使 OS 滚动整个屏幕所需的最小量,使光标在键盘上方可见。 (整个应用程序在键盘上方是由于模式 adjustResize)。
您必须在您的 Manifest
中添加 android:windowSoftInputMode="adjustPan"
,它将像 Pro 一样工作:
<activity android:name=".your_activity_name"
android:windowSoftInputMode="adjustPan">
..............
</activity>
请尝试添加此布局,
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="any text"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
为所有editText、button和textview提供id:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
android:id="@+id/et1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
android:id="@+id/et2"/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
android:id="@+id/et3"/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
android:id="@+id/et4"/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
android:id="@+id/et5"/>
</LinearLayout>
</ScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
android:id="@+id/btn"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="I don't want to push this TextView and Button to above keyboard when keyboard is shown. Just obly want to push the ScrollView that contain all EditText"
android:id="@+id/tv"/>
</LinearLayout>
在您的清单中:-
android:windowSoftInputMode="adjustResize|stateHidden"
在你的Activity中:-
public class Main2Activity extends AppCompatActivity {
EditText e1,e2,e3,e4,e5;
Button button;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
e1=(EditText)findViewById(R.id.et1);
e2=(EditText)findViewById(R.id.et2);
e3=(EditText)findViewById(R.id.et3);
e4=(EditText)findViewById(R.id.et4);
e5=(EditText)findViewById(R.id.et5);
textView=(TextView)findViewById(R.id.tv);
button=(Button)findViewById(R.id.btn);
e1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e2.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e3.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e4.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e5.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
}
private void hideKeyBoard(){
final View activityRootView = findViewById(R.id.activity_main);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > dpToPx(Main2Activity.this, 200)) { // if more than 200 dp, it's probably a keyboard...
// ... do something here
button.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
}
else {
button.setVisibility(View.VISIBLE);
textView.setVisibility(View.VISIBLE);
}
}
});
}
public static float dpToPx(Context context, float valueInDp) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
}
我在这里检查键盘是否可见。如果可见,则隐藏按钮和文本视图。
使用一个 Relavtive Layout
作为父级,将两个线性布局作为子级,并将滚动视图放在第一个线性布局中,而带有文本视图的按钮放在另一个中。
使用此代码。已测试,如您所愿。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="@id/linear">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="I don't want to push this TextView and Button above keyboard"
/>
</LinearLayout>
</RelativeLayout>
首先更改布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 1"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 2" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 3" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 4" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 5"
android:inputType="textNoSuggestions" />
</LinearLayout>
</ScrollView>
<RelativeLayout
android:id="@+id/rlBtm"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btn"
android:text="I don't want to push this TextView and Button to above keyboard when keyboard is shown. Just obly want to push the ScrollView that contain all EditText"
android:textColor="#000" />
</RelativeLayout>
</LinearLayout>
然后添加 class
public class KeyboardUtil {
public static void setKeyboardVisibilityListener(Activity activity, final KeyboardVisibilityListener keyboardVisibilityListener) {
final View contentView = activity.findViewById(android.R.id.content);
contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private int mPreviousHeight;
@Override
public void onGlobalLayout() {
int newHeight = contentView.getHeight();
if (mPreviousHeight != 0) {
if (mPreviousHeight > newHeight) {
// Height decreased: keyboard was shown
keyboardVisibilityListener.onKeyboardVisibilityChanged(true);
} else if (mPreviousHeight < newHeight) {
// Height increased: keyboard was hidden
keyboardVisibilityListener.onKeyboardVisibilityChanged(false);
} else {
// No change
}
}
mPreviousHeight = newHeight;
}
});
}
}
以及来自 onCreate 活动
KeyboardUtil.setKeyboardVisibilityListener(this, new KeyboardVisibilityListener() {
@Override
public void onKeyboardVisibilityChanged(boolean keyboardVisible) {
rlBtm.setVisibility(keyboardVisible ? View.GONE : View.VISIBLE);
}
});
查找 rlBtm 的 ID。
已在所有 Nexus 移动设备和平板设备上进行测试。它工作正常。我正在使用您的布局 xml 代码,并且只向视图添加了 ID。
我在生产应用程序中使用以下库,它非常有前途。为达到同样的效果,请在 app gradle 中添加以下行:
'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.0.1'
Here is the link for the same.
其余代码请参考以下要点:Manifest code, Activity code, Activity layout code。
根据我的经验,上述解决方案可能在 20% 的时间内不起作用。对于一些三星设备,上面的代码没有按预期工作。如果我有时间会尝试使用 Constraintlayout 和 adjustPan 来解决它。
您可以使用下面的代码(但在这种情况下,您的按钮和文本视图位于屏幕的末端。否则您也可以使用线性布局来管理它。如果您想要按钮和文本视图必须显示,请询问。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/sw1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="100dp"
android:background="#ff009988"
android:padding="10dp"
android:textColor="#ffffff" />
<EditText
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginBottom="10dp"
android:background="#ff009988"
android:padding="10dp"
android:textColor="#ffffff" />
<RelativeLayout
android:id="@+id/btmbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button2"
android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, " />
</RelativeLayout>
</LinearLayout>
</ScrollView>
借助 WindowInsetsCompat
的新功能,可以轻松检测键盘可见性(我按照此处的回答 )。
现在我可以通过将 windowSoftInputMode=adjustResize
与 WindowInsetsCompat
结合使用来解决这个问题,而不是像以前那样使用 windowSoftInputMode=adjustPan
来解决不那么复杂的问题
ViewCompat.setOnApplyWindowInsetsListener(root) { v, insets ->
val isKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
if (isKeyboardVisible) {
// Hide some view when keyboard visible
} else {
// Show it again here
}
}
AndroidManifest
<activity android:name=".activity_name"
android:windowSoftInputMode="adjustResize"> // all content will push to above keyboard then we able to scroll to see whole content
</activity>
我的布局在底部包含 5 个 EditText
和一个 Button
以及一个 TextView
。现在,当我按下 EditText
时,键盘将显示并且 all 我的 View
被向上推。
现在我不想把我的 TextView
和 Button
推到键盘上方,只想 全部推上去 EditText
里面 ScrollView
到键盘上方。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
/>
</LinearLayout>
</ScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="I don't want to push this TextView and Button to above keyboard when keyboard is shown. Just obly want to push the ScrollView that contain all EditText"
/>
</LinearLayout>
我有个想法是。当键盘显示和隐藏时我会监听。当键盘显示时,我将设置 ScrollView 的底部边距 = 键盘高度,当键盘隐藏时,我将设置此边距 = 0.
有什么方法更容易处理我的案子吗?任何帮助或建议将不胜感激。
更新
如果我使用 windowSoftInputMode=adjustPan
=> 并非所有 EditText
都被推到键盘上方
如果我使用 windowSoftInputMode=adjustResize
=> Button
、TextView
并且所有 EditText
都被推到键盘上方
不起作用 - 没有可靠的 API 来检测何时显示键盘。您会在此站点上看到 "solutions",但它们有误报和漏报。但似乎对您来说最好的办法是将 softInputMode 设置为 adjustPan。这将使 OS 滚动整个屏幕所需的最小量,使光标在键盘上方可见。 (整个应用程序在键盘上方是由于模式 adjustResize)。
您必须在您的 Manifest
中添加 android:windowSoftInputMode="adjustPan"
,它将像 Pro 一样工作:
<activity android:name=".your_activity_name"
android:windowSoftInputMode="adjustPan">
..............
</activity>
请尝试添加此布局,
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="any text"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
为所有editText、button和textview提供id:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
android:id="@+id/et1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
android:id="@+id/et2"/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
android:id="@+id/et3"/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
android:id="@+id/et4"/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
android:id="@+id/et5"/>
</LinearLayout>
</ScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
android:id="@+id/btn"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="I don't want to push this TextView and Button to above keyboard when keyboard is shown. Just obly want to push the ScrollView that contain all EditText"
android:id="@+id/tv"/>
</LinearLayout>
在您的清单中:-
android:windowSoftInputMode="adjustResize|stateHidden"
在你的Activity中:-
public class Main2Activity extends AppCompatActivity {
EditText e1,e2,e3,e4,e5;
Button button;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
e1=(EditText)findViewById(R.id.et1);
e2=(EditText)findViewById(R.id.et2);
e3=(EditText)findViewById(R.id.et3);
e4=(EditText)findViewById(R.id.et4);
e5=(EditText)findViewById(R.id.et5);
textView=(TextView)findViewById(R.id.tv);
button=(Button)findViewById(R.id.btn);
e1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e2.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e3.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e4.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
e5.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
hideKeyBoard();
}
});
}
private void hideKeyBoard(){
final View activityRootView = findViewById(R.id.activity_main);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > dpToPx(Main2Activity.this, 200)) { // if more than 200 dp, it's probably a keyboard...
// ... do something here
button.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
}
else {
button.setVisibility(View.VISIBLE);
textView.setVisibility(View.VISIBLE);
}
}
});
}
public static float dpToPx(Context context, float valueInDp) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
}
我在这里检查键盘是否可见。如果可见,则隐藏按钮和文本视图。
使用一个 Relavtive Layout
作为父级,将两个线性布局作为子级,并将滚动视图放在第一个线性布局中,而带有文本视图的按钮放在另一个中。
使用此代码。已测试,如您所愿。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 1"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 2"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 3"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 4"
/>
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="EditText 5"
android:inputType="textNoSuggestions"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="@id/linear">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button"
/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="I don't want to push this TextView and Button above keyboard"
/>
</LinearLayout>
</RelativeLayout>
首先更改布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 1"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 2" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 3" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 4" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="EditText 5"
android:inputType="textNoSuggestions" />
</LinearLayout>
</ScrollView>
<RelativeLayout
android:id="@+id/rlBtm"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btn"
android:text="I don't want to push this TextView and Button to above keyboard when keyboard is shown. Just obly want to push the ScrollView that contain all EditText"
android:textColor="#000" />
</RelativeLayout>
</LinearLayout>
然后添加 class
public class KeyboardUtil {
public static void setKeyboardVisibilityListener(Activity activity, final KeyboardVisibilityListener keyboardVisibilityListener) {
final View contentView = activity.findViewById(android.R.id.content);
contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private int mPreviousHeight;
@Override
public void onGlobalLayout() {
int newHeight = contentView.getHeight();
if (mPreviousHeight != 0) {
if (mPreviousHeight > newHeight) {
// Height decreased: keyboard was shown
keyboardVisibilityListener.onKeyboardVisibilityChanged(true);
} else if (mPreviousHeight < newHeight) {
// Height increased: keyboard was hidden
keyboardVisibilityListener.onKeyboardVisibilityChanged(false);
} else {
// No change
}
}
mPreviousHeight = newHeight;
}
});
}
}
以及来自 onCreate 活动
KeyboardUtil.setKeyboardVisibilityListener(this, new KeyboardVisibilityListener() {
@Override
public void onKeyboardVisibilityChanged(boolean keyboardVisible) {
rlBtm.setVisibility(keyboardVisible ? View.GONE : View.VISIBLE);
}
});
查找 rlBtm 的 ID。
已在所有 Nexus 移动设备和平板设备上进行测试。它工作正常。我正在使用您的布局 xml 代码,并且只向视图添加了 ID。
我在生产应用程序中使用以下库,它非常有前途。为达到同样的效果,请在 app gradle 中添加以下行: 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.0.1' Here is the link for the same.
其余代码请参考以下要点:Manifest code, Activity code, Activity layout code。
根据我的经验,上述解决方案可能在 20% 的时间内不起作用。对于一些三星设备,上面的代码没有按预期工作。如果我有时间会尝试使用 Constraintlayout 和 adjustPan 来解决它。
您可以使用下面的代码(但在这种情况下,您的按钮和文本视图位于屏幕的末端。否则您也可以使用线性布局来管理它。如果您想要按钮和文本视图必须显示,请询问。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/sw1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="100dp"
android:background="#ff009988"
android:padding="10dp"
android:textColor="#ffffff" />
<EditText
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginBottom="10dp"
android:background="#ff009988"
android:padding="10dp"
android:textColor="#ffffff" />
<RelativeLayout
android:id="@+id/btmbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button2"
android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, " />
</RelativeLayout>
</LinearLayout>
</ScrollView>
借助 WindowInsetsCompat
的新功能,可以轻松检测键盘可见性(我按照此处的回答 )。
现在我可以通过将 windowSoftInputMode=adjustResize
与 WindowInsetsCompat
windowSoftInputMode=adjustPan
来解决不那么复杂的问题
ViewCompat.setOnApplyWindowInsetsListener(root) { v, insets ->
val isKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
if (isKeyboardVisible) {
// Hide some view when keyboard visible
} else {
// Show it again here
}
}
AndroidManifest
<activity android:name=".activity_name"
android:windowSoftInputMode="adjustResize"> // all content will push to above keyboard then we able to scroll to see whole content
</activity>