在编辑文本获得焦点后出现软键盘时,我尝试调整布局。现在,如果我有很多编辑文本并且键盘出现,则隐藏最后一个编辑文本,我无法向上滚动。
这就是我的布局构建方式:
模板:
<LinearLayout>
<LinearLayout>
// header 1
</LinearLayout>
<LinearLayout>
// header 1
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:orientation="vertical">
// where I inflate view_1
</LinearLayout>
<LinearLayout>
// footer
</LinearLayout>
</LinearLayout>
查看(view_1):
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true">
<LinearLayout>
// ...
</LinearLayout>
<LinearLayout>
// ...
</LinearLayout>
<LinearLayout>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
</LinearLayout>
</LinearLayout>
</ScrollView>
我已经尝试了android:windowSoftInputMode
的各种组合(在manifest.xml上并以编程方式)。我试图在滚动视图上设置android:isScrollContainer="false"
,但没有。
我也试过这个answer,在我的滚动视图中放置了一个GlobalLayoutListener,但是当键盘出现时没有调用onGlobalLayout。而isKeyboardShown
总是错误的。
答案 0 :(得分:4)
我找到的最佳解决方案是在活动&lt;&gt;中添加adjustpan
属性标记在 manifest.xml 文件中。
<activity
android:name="MyActivity"
android:windowSoftInputMode="adjustPan"/>
答案 1 :(得分:3)
这是一个迟到的答案,但对于仍在寻找替代解决方案的任何人来说,它可能会有所帮助。我创建了一个可能适合您的用例的自定义ViewTreeObserver.OnGlobalLayoutListener
,如果您正在寻找一种方法来控制您希望确保在显示软键盘时可见的View
的位置。 Here is a gist该解决方案。
OnGlobalLayoutListener
动画通过在显示键盘时平滑移动软键盘边界上方的视图并在键盘解除时返回到视图的起始位置来更改视图的translationY
属性。如果您对使用有任何疑问,请与我们联系。
答案 2 :(得分:1)
我最终以我的方式做到了。
我创建了一个实现OnFocusChangeListener的类来处理我的所有EditText:
public class EditTextFocusChangeListener implements OnFocusChangeListener {
private ScrollView scrollView;
public EditTextFocusChangeListener(ScrollView scrollView) {
this.scrollView = scrollView;
}
@Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus) {
int left = view.getLeft();
int top = view.getTop();
int bottom = view.getBottom();
int keyboardHeight = scrollView.getHeight() / 3;
// if the bottom of edit text is greater than scroll view height divide by 3,
// it means that the keyboard is visible
if (bottom > keyboardHeight) {
// increase scroll view with padding
scrollView.setPadding(0, 0, 0, keyboardHeight);
// scroll to the edit text position
scrollView.scrollTo(left, top);
}
}
}
}
然后在活动中,我为每个编辑文本设置了监听器:
EditTextFocusChangeListener listener = new EditTextFocusChangeListener(mainScrollView);
editText1 = (EditText) findViewById(R.id.editText1);
editText1.setOnFocusChangeListener(listener);
editText2 = (EditText) findViewById(R.id.editText2);
editText2.setOnFocusChangeListener(listener);
...
editTextN = (EditText) findViewById(R.id.editTextN);
editTextN.setOnFocusChangeListener(listener);
对于最后一个编辑文本,我设置了一个EditorAction listerner来处理&#39;完成&#39;软键盘上的按钮 - 隐藏键盘并将滚动视图放回原位:
editTextN.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int result = actionId & EditorInfo.IME_MASK_ACTION;
switch(result) {
// user taped on keyboard DONE button
case EditorInfo.IME_ACTION_DONE:
// put the scroll view back to its original position
mainScrollView.setPadding(0, 0, 0, 0);
// hide keyboard
((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
// remove focus from any edit text
LinearLayout scrollViewLL = (LinearLayout) mainScrollView.getChildAt(0);
scrollViewLL.requestFocus();
break;
}
return false;
}
});
最后,一种方法可以处理用户何时触摸编辑文本以隐藏键盘并将滚动视图恢复到原始位置(在Web上找到并稍微更改以符合我的需要):
public void setupUI(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// put the scroll view back to its original position
if (v instanceof ScrollView) {
v.setPadding(0, 0, 0, 0);
LinearLayout scrollViewLL = (LinearLayout) ((ScrollView) v).getChildAt(0);
scrollViewLL.requestFocus();
}
hideKeyboard();
return false;
}
});
}
// If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
答案 3 :(得分:0)
将所有热门代码放入ScrollView
,而不仅仅是view_1
。这允许您在任何子EditText
点击时移动所有父布局。
编辑: view_1
在这种情况下不得包含ScrollView
!
答案 4 :(得分:0)
android:weightSum="1"
添加此
答案 5 :(得分:0)
如果您使用Android Studio Basic Activity
向导(包含CoordinatorLayout
和theme="@style/AppTheme.NoActionBar"
)创建活动,则默认行为为adjustPan,其中活动的顶部是推离屏幕,EditText显示在键盘上方。您还可以将其更改为adjustResize
,其中维护活动的顶部。
修改AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<application ...>
<activity
android:name=".TestInputActivity"
android:label="@string/title_activity_test_input"
android:windowSoftInputMode="adjustResize"
android:theme="@style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
请注意,如果您使用Scrolling Activity
,效果和行为可能略有不同,例如NestedScrollView
。
https://code.luasoftware.com/tutorials/android/move-layout-when-keyboard-shown/
答案 6 :(得分:-1)
以下代码对我有用。试试这个例子:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/RelativeAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.scrollview.MainActivity">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<EditText
android:id="@+id/editTextUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:ems="10"
android:inputType="textPersonName"
android:hint="Name" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/editTextUserName"
android:layout_alignLeft="@+id/editTextUserName"
android:layout_alignRight="@+id/editTextUserName"
android:layout_alignStart="@+id/editTextUserName"
android:layout_below="@+id/editTextUserName"
android:layout_marginTop="20dp"
android:ems="10"
android:inputType="textPersonName"
android:hint="Address" />
<Button
android:id="@+id/buttonLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/address"
android:layout_centerHorizontal="true"
android:layout_marginTop="47dp"
android:text="Button" />
</RelativeLayout>
</ScrollView>
</RelativeLayout>
在manifest.xml中添加以下行:
android:theme="@style/AppTheme"
android:windowSoftInputMode="stateHidden|adjustPan"
根据您的主题要求在style.xml中声明AppTheme。然后,如果您在页面加载时不需要键盘,则可以在活动中添加以下行:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
快乐编码: - )