2016-07-12 14 views
9

Wcześniej nie było problemu z trybem miękkiego wprowadzania, ale po włączeniu ConstraintLayout zawartość fragmentu nie przesuwa się w górę po wyświetleniu klawiatury.Tryb miękkiego wejścia okna ConstraintLayout

Oczywisty

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

Fragment

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); 
    } 
} 

Układ

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

Oto pic do zrozumienia:

enter image description here

Jak mogę zrozumieć, co się dzieje? Użyłem wcześniej ViewTreeObserver.

U.P.D.

Moim celem jest

enter image description here

Spodziewałem treści, aby poruszać się po wyświetleniu klawiatury, ale klawiatura jest nakładających się go zamiast.

+0

istnieje wiele błędów w ConstrainLayout. Tak więc, spróbuj otworzyć problem: https://code.google.com/p/android/issues/list?q=label:Component-Support-Libraries –

+1

Czy możesz jasno określić, jakie zachowanie się spodziewałeś? Czy spodziewałeś się przewinięcia zawartości? –

+0

@ MarcinKoziński, tak, oczywiście, zobacz górny górny widok proszę. – Scrobot

Odpowiedz

4

Wszystko, co faktycznie działa zgodnie z zamierzeniami, z budową układu - marginesy są ustalonymi odległościami, więc twój interfejs jest po prostu zbyt wysoki dla mniejszego ekranu. Będziesz musiał zmodyfikować swój układ, aby lepiej dostosować go do małego układu - oznaczając niepotrzebne widoki (np. Logo) jako nieobecne (ConstraintLayout uzna, że ​​widoki "minione" zostały zwinięte do jednego punktu, w zasadzie - więc układ nadal działa) lub zmienić niektóre marginesy na mniejszą wartość.

Typowym sposobem na zbudowanie tego jest użycie bias constraints lub guidelines, zamiast sztywnych marginesów. Używanie stronniczości lub wytycznych (w trybie procentowym) pozwoliłoby zachować bardziej "sprężynowe" zachowanie, aby lepiej reagować na zmiany wymiarów. Zazwyczaj układ będzie mieszanką twardych marginesów i stronniczości/wytycznych.

Podsumowując, dostępne opcje to:

  • zmienić układ używać polaryzacji/wytyczne (procentowo) ograniczenia, aby mieć bardziej czuły graficzny wzór
  • znak
  • kilka widoków GONE po wykryciu klawiatury
  • zmienić niektóre inne wartości w locie (rozmiar czcionki, wartości marginesów ...)
  • lub utworzyć kolejny plik układu do obsługi tej sprawy
+0

Dzięki za to. Czy możesz być nieco bardziej konkretny, jeśli chodzi o używanie wskazówek, aby reagować na pokazywanie miękkiej klawiatury? Czy klawiatura miękka jest zawsze procentową wysokością ekranu, więc trzeba mieć wytyczną na tyle? –

+0

Podanie przykładu xml znacznie pomogłoby –

3

Nie jestem pewien, w jaki aktywność Twój fragment jest usytuowany, ale jeśli jest to na przykład w InitChatActivity, wystarczy dodać adjustResize do manifestu i owinąć ConstraintLayout w Scrollview lub NestedScrollView:

android:windowSoftInputMode="stateHidden|adjustResize" 
1

I napotkał ten sam problem z tobą, zadeklarowaliśmy android:windowSoftInputMode="stateAlwaysHidden|adjustResize" w AndroidManifest.xml, ale w rzeczywistości aplikacja pokazała wyniki, takie jak adjustPan, zawartość zniknęła na wierzchu miękkiej klawiatury.Tak ustawić adjustResize programowo, skutecznie rozwiązać ten problem:

Wystarczy dodać tę linię do onCreate:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); 
Powiązane problemy