2016-07-12 32 views
9

In precedenza vi era alcun problema con modalità di ingresso morbido, ma dopo aver incluso ConstraintLayout, contenuto del frammento non si muove quando viene visualizzata la tastiera.Finestra Soft Input ConstraintLayout

manifesto

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

Frammento

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

layout

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

Ecco il pic per la comprensione:

enter image description here

Come posso capire che cosa sta succedendo? Ho usato ViewTreeObserver prima.

U.P.D.

Il mio obiettivo è

enter image description here

mi aspettavo contenuti per spostarsi in alto quando appare la tastiera, ma la tastiera si sovrappone al posto.

+0

Ci sono certo numero di bug nel ConstrainLayout. Quindi, prova ad aprire il problema qui: https://code.google.com/p/android/issues/list?q=label:Component-Support-Libraries –

+1

Puoi indicare chiaramente qual è il comportamento che ti aspettavi? Ti aspettavi che il contenuto fosse scorrevole? –

+0

@ MarcinKoziński, sì, certo, guarda upd superiore per favore. – Scrobot

risposta

4

Tutto in realtà funziona come previsto con il modo in cui il layout è costruito - i margini sono fissati distanze, quindi l'interfaccia utente è semplicemente troppo alto per lo schermo più piccolo. Dovresti modificare il layout per adattarlo meglio a un piccolo layout, ovvero contrassegnare le viste non necessarie (ad esempio il logo) come svanite (ConstraintLayout considererà le viste "perse" come compresse in un singolo punto, in sostanza, quindi il layout continua funziona) o modificare alcune dimensioni dei margini su un valore inferiore.

Il modo usuale per creare questo è utilizzare bias constraints o guidelines, invece di margini rigidi. L'uso di bias o linee guida (in modalità percentuale) ti consentirebbe di avere un comportamento più "a molla" per reagire meglio alle modifiche alle dimensioni. In genere un layout sarà un mix di margini rigidi e bias/linee guida.

In sintesi, le opzioni sono:

  • cambiamento del layout di utilizzare/linee guida vincoli (per cento) di polarizzazione di avere un layout più reattivo
  • segno alcuni punti di vista, come GONE quando rileva la tastiera
  • modificare alcuni altri valori al volo (dimensione del carattere, valori dei margini ...)
  • o, creare un altro file di layout per la gestione di questo caso
+0

Grazie per questo. Potresti essere un po 'più specifico sull'uso delle linee guida per essere reattivo alla visualizzazione della tastiera virtuale? La tastiera morbida ha sempre un'altezza percentuale dello schermo, quindi è necessario avere una linea guida per questo? –

+0

Fornire un esempio xml sarebbe di grande aiuto –

3

io non sono sicuro che in quanto attività vostro frammento si trova, ma se è in per esempio InitChatActivity, basta aggiungere adjustResize al vostro manifesto, e avvolgere il vostro ConstraintLayout in ScrollView o NestedScrollView:

android:windowSoftInputMode="stateHidden|adjustResize" 
1

ho incontrato lo stesso problema con voi, abbiamo dichiarato android:windowSoftInputMode="stateAlwaysHidden|adjustResize" nel AndroidManifest.xml, ma in realtà l'App ha mostrato i risultati come adjustPan, i contenuti sono andati sulla parte superiore della tastiera virtuale.Così mi sono messo adjustResize programmazione, risolto con successo questo problema:

Basta aggiungere questa linea al vostro onCreate:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);