La nueva Facebook SDK para Android (v4.0) que fue lanzado recientemente causó un comportamiento extraño para un personalizados LoginButton estoy usando. A continuación se muestra una comparación de cómo el mismo XML se representa en diferentes versiones de SDK.

El problema parece ser que el FB icono en el SDK 4.x no estirar correctamente para que se ajuste a un tamaño personalizado botón, y en la 4.0.1 el android:layout_height propiedad es ignorado por completo.

Mi pregunta es ¿cómo puedo hacer que el botón aparezca en el SDK 4.x como se hizo en el SDK 3.x? Tanto en Java y XML soluciones son perfectamente aceptables.

XML para SDK 3.x:

<com.facebook.widget.LoginButton
        android:background="@color/com_facebook_blue"
        android:id="@+id/login_btn_facebook"
        android:layout_width="225dp"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:layout_gravity="center"
        android:onClick="onFacebookLoginClick"
            />

Cómo se ve en el SDK 3.x (captura de pantalla tomada en un OnePlus One, la ejecución de CM11S):
Facebook SDK v4 LoginButton ignora XML personalizaciones

XML para SDK 4.x (el botón del paquete fue rebautizado con el nombre + tuve que cambiar el ancho & font un poco para que coincida con el g+ botón):

<com.facebook.login.widget.LoginButton
        android:background="@color/com_facebook_blue"
        android:id="@+id/login_btn_facebook"
        android:layout_width="221dp"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:layout_gravity="center"
        android:textSize="7pt"
        android:onClick="onFacebookLoginClick"
            />

Cómo se ve en el SDK 4.0 (Captura de pantalla tomada en un Genymotion Nexus 5, la ejecución sin modificar 4.4.4):
Facebook SDK v4 LoginButton ignora XML personalizaciones

Cómo se ve en el SDK de la 4.0.1 (Mismo Genymotion Nexus 5):
Facebook SDK v4 LoginButton ignora XML personalizaciones

Información adicional

  1. Extracto de la 4.0 -> 4.0.1 SDK de registro de cambios:

Botón de inicio de sesión se actualiza correctamente, medir su tamaño.

  1. Puestos relacionados con:

  2. Apoyo para los diferentes tamaños de pantalla, por encima de los botones de inicio de sesión tengo un ViewPagerIndicator y un ViewPager que está configurado para ocupar todo el espacio vertical disponible que queda después de la colocación de los elementos definidos altura.

InformationsquelleAutor Dev-iL | 2015-04-04

6 Comentarios

  1. 60

    Me las arreglé para conseguir el resultado deseado siguiendo los siguientes pasos:

    1. Abre la Facebook SDK 3.x LoginButton código y vio cómo el botón de estilo no:

      this.setBackgroundResource(R.drawable.com_facebook_button_blue);
      this.setCompoundDrawablesWithIntrinsicBounds(
                   R.drawable.com_facebook_inverse_icon, 0, 0, 0);
      this.setCompoundDrawablePadding(getResources().getDimensionPixelSize(
                   R.dimen.com_facebook_loginview_compound_drawable_padding));
      this.setPadding(getResources().getDimensionPixelSize(
                      R.dimen.com_facebook_loginview_padding_left),
                  getResources().getDimensionPixelSize(
                      R.dimen.com_facebook_loginview_padding_top),
                  getResources().getDimensionPixelSize(
                      R.dimen.com_facebook_loginview_padding_right),
                  getResources().getDimensionPixelSize(
                      R.dimen.com_facebook_loginview_padding_bottom));
    2. Basado en la solución presentada en esta respuesta, he cambiado el botón de parámetros durante la onPostCreate() de la siguiente manera:

      float fbIconScale = 1.45F;
      Drawable drawable = hostActivity.getResources().getDrawable(
                                     com.facebook.R.drawable.com_facebook_button_icon);
      drawable.setBounds(0, 0, (int)(drawable.getIntrinsicWidth()*fbIconScale),
                               (int)(drawable.getIntrinsicHeight()*fbIconScale));
      authButton.setCompoundDrawables(drawable, null, null, null); 
      authButton.setCompoundDrawablePadding(hostActivity.getResources().
                        getDimensionPixelSize(R.dimen.fb_margin_override_textpadding));
      authButton.setPadding(
              hostActivity.getResources().getDimensionPixelSize(
                                                        R.dimen.fb_margin_override_lr),
              hostActivity.getResources().getDimensionPixelSize(
                                                       R.dimen.fb_margin_override_top),
              hostActivity.getResources().getDimensionPixelSize(
                                                        R.dimen.fb_margin_override_lr),
              hostActivity.getResources().getDimensionPixelSize(
                                                   R.dimen.fb_margin_override_bottom));

      Donde mi costumbre dimensiones son como sigue:

      <dimen name="fb_margin_override_top">13dp</dimen>
      <dimen name="fb_margin_override_bottom">13dp</dimen>
      <!--The next value changes the margin between the FB icon and the left border:-->
      <dimen name="fb_margin_override_lr">10dp</dimen>
      <!--The next value changes the margin between the FB icon and the login text:-->
      <dimen name="fb_margin_override_textpadding">17dp</dimen>

    Esto se traduce en el diseño deseado:

    Facebook SDK v4 LoginButton ignora XML personalizaciones

  2. 12

    Altura de LoginButton está relacionado con sus rellenos y el tamaño del texto:

    //LoginButton.java
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = (getCompoundPaddingTop() +
                (int)Math.ceil(Math.abs(fontMetrics.top) + Math.abs(fontMetrics.bottom)) +
                getCompoundPaddingBottom());
        //...
    }

    Así que si usted quiere cambiar su altura a través del archivo xml de uso android:padding* y android:textSize propiedades o crear un estilo para ti:

    <style name="FacebookLoginButtonStyle">
        <item name="android:textSize">16sp</item>
        <item name="android:paddingTop">10sp</item>
        <item name="android:paddingBottom">10sp</item>
    </style>
    • Cambiar el relleno en XML es sin duda un buen consejo, sin embargo, esta respuesta es incompleta – no aborda el FB icono de la escala (que sigue siendo pequeño), ni facilitar el desplazamiento del texto en el botón (a ser capaz de alinear con el g+ texto a continuación).
    • sí, una mala respuesta
  3. 4

    yo enfrentan el mismo problema y lo he resuelto estableciendo el relleno y la dibujables en java de código como este:

    authButton.setPadding(0, myTopDp, 0, myBottomDp);
        authButton.setCompoundDrawablePadding(hostActivity.getResources().getDimensionPixelSize(R.dimen.fb_margin_override_textpadding));
        authButton.setCompoundDrawablesWithIntrinsicBounds(myFbResource, 0, 0, 0);

    o si se usa la imagen como imagen

    authButton.setCompoundDrawablesWithIntrinsicBounds(myFbDrawable, null, null, null);

    Creo que la OnPostCreate método no es necesario.

    • Hola, y gracias por la respuesta. Acabo de probar este código y la imagen no parece escala + también está pegado al borde izquierdo del botón. Ah, y mi IDE parece como authButton.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null); mejor (0 en lugar de null genera un paño que no deje de error; probado en API 22).
    • Hola, el método setCompoundDrawablesWithIntrinsicbounds acepta los identificadores de recursos o dibujables, en mi ejemplo, me estaba refiriendo a los identificadores de recursos (tal vez tengo que actualizar mi respuesta). A escala de la imagen que usted tiene que establecer el relleno como en su respuesta. voy a actualizar mi respuesta
  4. 2

    Porque quería personalizar el texto de inicio de sesión gravity inicio, me encontré con un problema con el setCompoundDrawablePadding método. Finalmente lo resuelto por el uso de un diseño personalizado. Creo que es una manera mucho más fácil personalizar el Facebook botón de inicio de sesión.

    Aquí está el resultado final:

    Facebook SDK v4 LoginButton ignora XML personalizaciones

    El diseño xml:

    <LinearLayout
            android:id="@+id/fb_login_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:background="@drawable/com_facebook_button_background"
            android:orientation="horizontal">
    
            <ImageView
                android:layout_width="38dp"
                android:layout_height="38dp"
                android:layout_gravity="center_vertical"
                android:layout_marginBottom="1dp"
                android:layout_marginLeft="1dp"
                android:layout_marginStart="1dp"
                android:layout_marginTop="1dp"
                android:padding="8dp"
                android:src="@drawable/com_facebook_button_icon" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:padding="8dp"
                android:text="Log in with Facebook"
                android:textColor="@color/white"
                android:textSize="14sp"
                android:textStyle="bold" />
        </LinearLayout>

    Código Java que se encarga de la costumbre Facebook de inicio de sesión de clics del botón:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    findViewById(R.id.fb_login_btn).setOnClickListener(this);
    boolean login = AccessToken.getCurrentAccessToken() != null;
    updateFacebookLogInButton(login);
    new AccessTokenTracker() {
    @Override
    protected void onCurrentAccessTokenChanged(
    AccessToken oldAccessToken,
    AccessToken currentAccessToken) {
    if (currentAccessToken == null) {
    updateFacebookLogInButton(false);
    }
    }
    };
    FacebookCallback<LoginResult> facebookCallback = new FacebookCallback<LoginResult>() {
    @Override
    public void onSuccess(LoginResult loginResult) {
    updateFacebookLogInButton(true);
    handleLoginResult(loginResult.getAccessToken());
    }
    @Override
    public void onCancel() {
    }
    @Override
    public void onError(FacebookException error) {
    error.printStackTrace();
    }
    };
    callbackManager = CallbackManager.Factory.create();
    loginManager = LoginManager.getInstance();
    loginManager.registerCallback(callbackManager, facebookCallback);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.fb_login_btn:
    if (AccessToken.getCurrentAccessToken() == null) {
    loginManager.logInWithReadPermissions(this, Arrays.asList("public_profile", "email"));
    } else {
    String logout = getResources().getString(
    com.facebook.R.string.com_facebook_loginview_log_out_action);
    String cancel = getResources().getString(
    com.facebook.R.string.com_facebook_loginview_cancel_action);
    String message;
    Profile profile = Profile.getCurrentProfile();
    if (profile != null && profile.getName() != null) {
    message = String.format(
    getResources().getString(
    com.facebook.R.string.com_facebook_loginview_logged_in_as),
    profile.getName());
    } else {
    message = getResources().getString(
    com.facebook.R.string.com_facebook_loginview_logged_in_using_facebook);
    }
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(message)
    .setCancelable(true)
    .setPositiveButton(logout, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
    loginManager.logOut();
    }
    })
    .setNegativeButton(cancel, null);
    builder.create().show();
    }
    break;
    default:
    break;
    }
    }
    private Bundle getRequestParameters() {
    Bundle parameters = new Bundle();
    parameters.putString("fields", "id,name,email,gender");
    return parameters;
    }
    private void updateFacebookLogInButton(boolean login) {
    TextView loginTextView = (TextView) findViewById(R.id.fb_login_tv);
    if (login) {
    loginTextView.setText("Log out");
    } else {
    loginTextView.setText("Log in with Facebook");
    }
    }
    private void handleRequestResult(JSONObject object) {
    //handle GraphRequest here
    }
    • Esta respuesta es actualmente incompleto debido a que la resultante de diseño personalizado no tiene la misma funcionalidad que el original FB botón de inicio de sesión (por ejemplo: la onClick comportamiento que interfiere con el SDK y le da de inicio de sesión y cierre de sesión de capacidades; y cambios automáticos de el botón de texto basado en el estado de inicio de sesión). Si usted desea mejorar la respuesta, le sugiero que también proporcionan el código de Java para «volver» a la pérdida de funcionalidad.
    • Gracias @Dev-iL. He mejorado la respuesta.
    • Gracias. Personalizar Facebook por el diseño personalizado + roles loginmanager , creo que es la mejor solución.
  5. 0

    Acabo de poner el botón en un RelativeLayout. Mi Altura es de 60dp

     <RelativeLayout
    android:id="@+id/rlGoogle"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_marginTop="30dp"
    app:layout_constraintTop_toBottomOf="@+id/btnSingInWithFace">
    <com.google.android.gms.common.SignInButton
    android:id="@+id/btnSingInWithGoogle"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </RelativeLayout>
    • Este es un buen consejo, pero que hace este trabajo para el Facebook de inicio de sesión en el botón? Después de todo, esta fue una pregunta acerca de fb…
    • para el facebook Botón de Tu esto: android:paddingTop=»20dp» android:paddingStart=»20dp»
  6. -3

    Personas, u sólo tendrá que establecer paddingTop y paddingBottom valores.

                android:paddingTop="15dp"
    android:paddingBottom="15dp"
    • Este ya ha sido sugerido
    • Nosotros, «la gente» que sabe leer y no sugieren cosas que ya se han sugerido.
    • Era lo suficientemente bueno para mi problema: «relleno» no trabajo pero «paddingTop» trabajado

Dejar respuesta

Please enter your comment!
Please enter your name here