web-dev-qa-db-fra.com

Facebook SDK v4 LoginButton ignore les personnalisations XML

Le nouveau Facebook SDK pour Android (v4.0) ​​_ qui a été publié récemment a provoqué un comportement étrange pour un LoginButton personnalisé que j'utilise. Vous trouverez ci-dessous une comparaison de la manière dont le même XML est rendu dans différentes versions du SDK. 

Le problème semble être que l’icône du FB dans SDK 4.x ne s’étire pas correctement pour tenir sur un bouton de taille personnalisée et que, à 4.0.1, la propriété Android:layout_height est ignorée.

Ma question est comment puis-je faire en sorte que le bouton apparaisse dans SDK 4.x comme dans SDK 3.x? Les solutions XML et Java sont parfaitement acceptables.

XML pour 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"
            />

A quoi ça ressemble sur le SDK 3.x (capture d’écran prise sur un OnePlus One, exécutant CM11S): XML rendering when running with SDK v3.x

XML for SDK 4.x (le paquet du bouton a été renommé + je devais changer un peu la largeur et la police pour correspondre au bouton 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"
            />

A quoi cela ressemble-t-il sur le SDK 4.0 (capture d’écran prise sur un Genymotion Nexus 5 fonctionnant sans modification en 4.4.4): enter image description here

A quoi ça ressemble sur SDK 4.0.1 (Same Genymotion Nexus 5): enter image description here

Information additionnelle

  1. Extrait du journal des modifications du SDK (4.0 -> 4.0.1) :

Le bouton de connexion est mis à jour pour mesurer correctement sa taille.

  1. Articles Similaires:

  2. Pour prendre en charge différentes tailles d'écran, au-dessus des boutons de connexion, j'ai un ViewPagerIndicator et un ViewPager configuré pour occuper tout l'espace vertical restant après le positionnement des éléments à une hauteur définie.

37
Dev-iL

J'ai réussi à obtenir le résultat souhaité en suivant les étapes suivantes:

  1. Ouvert le Facebook SDK 3.x LoginButton code et a vu comment le bouton a été stylé ici:

    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. Sur la base de la solution présentée dans cette réponse , j’ai modifié les paramètres du bouton pendant onPostCreate() comme suit:

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

    Où mes dimensions personnalisées sont les suivantes:

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

Cela se traduit par la mise en page souhaitée:

The desired layout :D

60
Dev-iL

La hauteur de LoginButton est liée à ses rembourrages et à la taille du texte:

//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());
    //...
}

Donc, si vous voulez changer sa hauteur via un fichier xml, utilisez les propriétés Android:padding* et Android:textSize ou créez un style pour cela:

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

j'ai fait face au même problème et je l'ai résolu en définissant le remplissage et les éléments dessinables en code Java comme suit:

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

ou si vous utilisez votre image comme dessinable

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

Je crois que la méthode OnPostCreate n'est pas requise.

4
Bronx

Parce que je voulais personnaliser le texte de connexion gravity start, j'ai rencontré un problème avec la méthode setCompoundDrawablePadding. Enfin, je l'ai résolu en utilisant une mise en page personnalisée. Je pense que c'est un moyen beaucoup plus facile de personnaliser le bouton de connexion Facebook.

Voici le résultat final:

 Facebook login button and Google sign in button

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

Le code Java qui gère les clics du bouton de connexion Facebook personnalisé:

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

Il suffit de mettre le bouton dans un RelativeLayout. Ma taille est 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>
0
Miguel Vieira