android user-interface facebook-sdk-4.0

android - Facebook SDK v4 LoginButton ignora las personalizaciones XML



user-interface facebook-sdk-4.0 (5)

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

El problema parece ser que el ícono FB en SDK 4.x no se estira correctamente para ajustarse a un botón de tamaño personalizado, y en 4.0.1 la propiedad android:layout_height se ignora por completo.

Mi pregunta es ¿cómo hago que el botón aparezca en SDK 4.x como lo hizo en SDK 3.x? Ambas soluciones XML y Java 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 SDK 3.x (captura de pantalla tomada en OnePlus One, ejecutando CM11S):

XML para SDK 4.x (el paquete del botón se renombró + Tuve que cambiar el ancho y la fuente un poco para que coincida con el botón g +):

<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 SDK 4.0 (Captura de pantalla tomada en un Genymotion Nexus 5, ejecutando 4.4.4 sin modificar):

Cómo se ve en SDK 4.0.1 (Same Genymotion Nexus 5):

Información Adicional

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

El botón de inicio de sesión se actualiza para medir correctamente su tamaño.

  1. Artículos Relacionados:

  2. Para admitir diferentes tamaños de pantalla, 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 colocar los elementos con una altura definida.


Como quería personalizar el inicio de gravity texto de inicio de sesión, encontré un problema con el método setCompoundDrawablePadding . Finalmente lo resolví usando un diseño personalizado. Creo que es una forma mucho más fácil de personalizar el botón de inicio de sesión de Facebook.

Aquí está el resultado final:

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>

El código de Java que maneja el botón de inicio de sesión personalizado de Facebook hace clic:

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


Enfrenté el mismo problema y lo resolví configurando el relleno y los dibujables en código java 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 usas tu imagen como dibujable

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

Creo que el método OnPostCreate no es obligatorio.


Gente, solo necesitas establecer los valores de paddingTop y paddingBottom.

android:paddingTop="15dp" android:paddingBottom="15dp"


La altura de LoginButton está relacionada con sus paddings y tamaño de 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()); //... }

Por lo tanto, si desea cambiar su altura mediante un archivo xml, use las propiedades android:padding* y android:textSize o cree un estilo para él:

<style name="FacebookLoginButtonStyle"> <item name="android:textSize">16sp</item> <item name="android:paddingTop">10sp</item> <item name="android:paddingBottom">10sp</item> </style>


Logré obtener el resultado deseado siguiendo los siguientes pasos:

  1. Abrió el código LoginButton de Facebook SDK 3.x y vio cómo se diseñó el botón allí:

    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. En función de la solución presentada en esta respuesta , onPostCreate() parámetros del botón durante onPostCreate() 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 mis dimensiones personalizadas son las siguientes:

    <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 da como resultado el diseño deseado: