以前はソフト入力モードで問題はありませんでしたが、ConstraintLayout
を含めた後、キーボードが表示されてもフラグメントのコンテンツが上に移動しません。
マニフェスト
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="ru.pinspb.pinsupport">
<uses-feature
Android:name="Android.software.leanback"
Android:required="false" />
<uses-permission Android:name="Android.permission.INTERNET" />
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission Android:name="Android.permission.GET_ACCOUNTS" />
<uses-permission Android:name="Android.permission.WAKE_LOCK" />
<uses-permission Android:name="com.google.Android.c2dm.permission.RECEIVE" />
<permission
Android:name="ru.pinspb.pinsupport.permission.C2D_MESSAGE"
Android:protectionLevel="signature" />
<uses-permission Android:name="ru.pinspb.pinsupport.permission.C2D_MESSAGE" />
<uses-permission Android:name="Android.permission.READ_PROFILE" />
<uses-permission Android:name="Android.permission.READ_CONTACTS" />
<application
Android:name=".PinApp"
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:supportsRtl="true"
Android:theme="@style/AppTheme.NoActionBar">
<activity
Android:name=".auth.ui.HomeActivity"
Android:windowSoftInputMode="adjustResize">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
<category Android:name="Android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<activity
Android:name=".front.ui.FrontActivity"
Android:launchMode="singleTop" />
<activity
Android:name=".chats.ui.InitChatActivity"
Android:launchMode="singleTop"
Android:windowSoftInputMode="stateHidden" />
</application>
</manifest>
断片
public class AuthFragment extends Fragment implements ValidationListener {
private static final String TAG = AuthFragment.class.toString();
// UI references.
@NotEmpty @Email @BindView(R.id.email) EditText email;
@NotEmpty @BindView(R.id.password) EditText password;
@BindView(R.id.auth_sign_in) Button signIn;
@BindView(R.id.remember_me) CheckBox remember;
@BindView(R.id.forgot) TextView forgot;
@BindView(R.id.error) TextView errorField;
@Inject @ApplicationContext
Context context;
private Validator validator;
private onAuthenticateEventListener authenticatableEventListener;
private String error = Constants.EMPTY_STRING;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
authenticatableEventListener = (onAuthenticateEventListener) activity;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View render = inflater.inflate(R.layout.fragment_auth, container, false);
ButterKnife.bind(this, render);
final View activityRootView = render.findViewById(R.id.activity_root);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > Helper.dpToPx(container.getContext(), 200)) { // if more than 200 dp, it's probably a keyboard...
Log.d(TAG, "heightDiff: " + heightDiff);
}
});
return render;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
errorField.setText(this.error);
if(this.error.equals(Constants.EMPTY_STRING)) {
errorField.setVisibility(View.GONE);
} else {
errorField.setVisibility(View.VISIBLE);
}
// Set up the login form.
password.setOnEditorActionListener((textView, id, keyEvent) -> {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
});
validator = new Validator(this);
validator.setValidationListener(this);
signIn.setOnClickListener(v -> validator.validate());
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
// Store values at the time of the login attempt.
String email = this.email.getText().toString();
String password = this.password.getText().toString();
Bundle bundle = new Bundle();
bundle.putString("email", email);
bundle.putString("password", password);
authenticatableEventListener.sendAuthRequest(bundle);
}
@Override
public void onValidationSucceeded() {
attemptLogin();
}
@Override
public void onValidationFailed(List<ValidationError> errors) {
for (ValidationError error : errors) {
Log.d(TAG, "onValidationFailed: " + error.getCollatedErrorMessage(context));
View view = error.getView();
String message = error.getCollatedErrorMessage(context);
// Display error messages ;)
if (view instanceof EditText) {
((EditText) view).setError(message);
} else {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
}
public void setErrors(String text) {
this.error = text;
}
public interface onAuthenticateEventListener {
void sendAuthRequest(Bundle params);
void showErrors(String error);
}
}
レイアウト
<Android.support.constraint.ConstraintLayout 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"
Android:gravity="center_horizontal"
Android:orientation="vertical"
Android:background="@color/bg"
Android:id="@+id/activity_root">
<!-- Login progress -->
<ProgressBar
Android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@+id/activity_root"
tools:layout_constraintLeft_creator="1"
app:layout_constraintTop_toTopOf="@+id/activity_root"
tools:layout_constraintTop_creator="1"
app:layout_constraintRight_toLeftOf="@+id/activity_root"
tools:layout_constraintRight_creator="1"
app:layout_constraintBottom_toTopOf="@+id/activity_root"
tools:layout_constraintBottom_creator="1" />
<ImageView
Android:layout_width="120dp"
Android:layout_height="80dp"
Android:id="@+id/logo"
app:srcCompat="@drawable/logo_pin_support"
Android:contentDescription="@string/contentDiscription"
app:layout_constraintLeft_toLeftOf="@+id/activity_root"
tools:layout_constraintLeft_creator="1"
app:layout_constraintTop_toTopOf="@+id/activity_root"
Android:layout_marginTop="56dp"
tools:layout_constraintTop_creator="1"
app:layout_constraintRight_toRightOf="@+id/activity_root"
tools:layout_constraintRight_creator="1" />
<EditText
Android:id="@+id/email"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:hint="@string/auth.email"
Android:inputType="textEmailAddress"
Android:maxLines="1"
Android:drawablePadding="10dp"
Android:paddingTop="20dp"
Android:paddingBottom="20dp"
Android:textSize="@dimen/auth.sizes"
Android:autoLink="none"
Android:focusableInTouchMode="true"
tools:ignore="RtlHardcoded"
app:layout_constraintLeft_toLeftOf="@+id/activity_root"
Android:layout_marginStart="16dp"
app:layout_constraintTop_toBottomOf="@+id/error"
Android:layout_marginTop="8dp"
app:layout_constraintRight_toRightOf="@+id/activity_root"
Android:layout_marginEnd="16dp"
app:layout_constraintHorizontal_bias="0.56" />
<EditText
Android:id="@+id/password"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:hint="@string/auth.password"
Android:imeActionId="@+id/login"
Android:imeOptions="actionUnspecified"
Android:inputType="textPassword"
Android:maxLines="1"
Android:drawablePadding="10dp"
Android:textSize="@dimen/auth.sizes"
Android:paddingTop="20dp"
Android:paddingBottom="20dp"
tools:ignore="MissingConstraints,RtlHardcoded"
app:layout_constraintLeft_toLeftOf="@+id/email"
app:layout_constraintTop_toBottomOf="@+id/email"
app:layout_constraintRight_toRightOf="@+id/email"
app:layout_constraintHorizontal_bias="0.0" />
<TextView
Android:text="@string/auth.title"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:textSize="27sp"
Android:textColor="@color/greyish_brown"
Android:id="@+id/textView"
tools:ignore="MissingConstraints"
app:layout_constraintLeft_toLeftOf="@+id/activity_root"
Android:layout_marginStart="16dp"
app:layout_constraintTop_toBottomOf="@+id/logo"
Android:layout_marginTop="24dp"
app:layout_constraintRight_toRightOf="@+id/activity_root"
Android:layout_marginEnd="16dp" />
<CheckBox
Android:text="@string/auth.remember"
Android:layout_width="0dp"
Android:layout_height="32dp"
Android:id="@+id/remember_me"
style="@Android:style/Widget.Holo.Light.CompoundButton.CheckBox"
Android:checked="true"
Android:textSize="@dimen/auth.sizes"
Android:textColor="@color/warm_grey"
app:layout_constraintLeft_toLeftOf="@+id/activity_root"
Android:layout_marginStart="16dp"
app:layout_constraintTop_toBottomOf="@+id/password"
Android:layout_marginTop="27dp"
app:layout_constraintRight_toRightOf="@+id/activity_root"
Android:layout_marginEnd="16dp"
app:layout_constraintHorizontal_bias="0.0" />
<Button
Android:text="@string/auth.submit"
Android:layout_width="152dp"
Android:layout_height="51dp"
Android:id="@+id/auth_sign_in"
Android:background="@drawable/round_button"
tools:ignore="MissingConstraints"
Android:textColor="@color/white"
Android:textSize="@dimen/auth.sizes"
app:layout_constraintLeft_toLeftOf="@+id/activity_root"
Android:layout_marginStart="16dp"
app:layout_constraintTop_toBottomOf="@+id/remember_me"
Android:layout_marginTop="46dp"
app:layout_constraintRight_toRightOf="@+id/activity_root"
Android:layout_marginEnd="16dp" />
<TextView
Android:text="@string/auth.forgot"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:id="@+id/forgot"
Android:textColor="@color/pinkish_grey"
app:layout_constraintLeft_toLeftOf="@+id/auth_sign_in"
app:layout_constraintTop_toBottomOf="@+id/auth_sign_in"
Android:layout_marginTop="16dp"
app:layout_constraintRight_toRightOf="@+id/auth_sign_in" />
<TextView
Android:text="error"
Android:layout_width="wrap_content"
Android:layout_height="16dp"
Android:id="@+id/error"
Android:textColor="@color/lipstick"
Android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@+id/textView"
app:layout_constraintTop_toBottomOf="@+id/textView"
Android:layout_marginTop="16dp"
app:layout_constraintRight_toRightOf="@+id/textView" />
</Android.support.constraint.ConstraintLayout>
ここに理解のための写真があります:
何が起こっているのか理解するにはどうすればよいですか?以前にViewTreeObserverを使用しました。
U.P.D。
私の目標は
キーボードが表示されたときにコンテンツが上に移動することを期待していましたが、代わりにキーボードが重なっています。
すべては実際にはレイアウトの構築方法で意図したとおりに機能します。マージンは固定距離であるため、UIは小さい画面には高すぎるだけです。レイアウトを変更して、小さなレイアウトにさらに適応させる必要があります-不要なビュー(ロゴなど)を削除済みとしてマークします(ConstraintLayoutは、「削除された」ビューを本質的に単一のポイントに折りたたまれたものと見なします。機能)、または一部のマージン寸法をより小さい値に変更します。
これを構築する通常の方法は、ハードマージンの代わりに バイアス制約 または ガイドライン を使用することです。バイアスまたはガイドライン(パーセントモード)を使用すると、寸法の変化によりよく反応する「スプリング」のような動作をより多く持つことができます。通常、レイアウトはハードマージンとバイアス/ガイドラインを組み合わせたものになります。
要約すると、オプションは次のとおりです。
GONE
としてマークしますフラグメントがどのアクティビティにあるかはわかりませんが、たとえばInitChatActivityにある場合は、マニフェストにadjustResizeを追加して、ConstraintLayoutをScrollViewまたはNestedScrollViewでラップします。
Android:windowSoftInputMode="stateHidden|adjustResize"
私はあなたと同じ問題に遭遇しました、私たちはAndroid:windowSoftInputMode="stateAlwaysHidden|adjustResize"
の中に AndroidManifest.xml
ですが、実際にはアプリはadjustPan
のような結果を表示し、コンテンツはソフトキーボードの上に表示されません。だから私はadjustResize
をプログラムで設定し、この問題をうまく解決しました:
この行をonCreate
に追加するだけです:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);