Das neue Facebook-SDK für Android (v4.0) , das kürzlich veröffentlicht wurde, verursachte seltsames Verhalten für einen angepassten LoginButton , den ich verwende. Unten ist ein Vergleich, wie dasselbe XML in verschiedenen SDK-Versionen dargestellt wird.
Das Problem scheint zu sein, dass das FB-Symbol in SDK 4.x nicht richtig gedehnt wird, um auf eine Schaltfläche in der benutzerdefinierten Größe zu passen. In 4.0.1 lautet die Android:layout_height
-Eigenschaft ignored ganz.
Meine Frage ist Wie kann ich die Schaltfläche in SDK 4.x wie in SDK 3.x erscheinen lassen? Sowohl XML- als auch Java-Lösungen sind absolut akzeptabel.
XML für 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"
/>
Wie es auf SDK 3.x aussieht (Screenshot auf einem OnePlus One, auf dem CM11S ausgeführt wird):
XML für SDK 4.x (das Paket der Schaltfläche wurde umbenannt + Ich musste die Breite und die Schriftart etwas ändern, um mit der Taste g + übereinzustimmen):
<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"
/>
Wie es auf SDK 4.0 aussieht (Screenshot auf einem Genymotion Nexus 5, das unverändert 4.4.4 ausgeführt wird):
So sieht es in SDK 4.0.1 (Same Genymotion Nexus 5) aus:
Die Login-Schaltfläche wird aktualisiert, um die Größe korrekt zu messen.
Zusammenhängende Posts:
Um verschiedene Bildschirmgrößen zu unterstützen, habe ich über den Login-Schaltflächen einen ViewPagerIndicator und einen ViewPager , der so konfiguriert ist, dass er den gesamten verfügbaren vertikalen Platz beansprucht, der nach dem Positionieren von Elementen mit definierter Höhe übrig bleibt.
Es gelang mir, das gewünschte Ergebnis zu erzielen, indem Sie die folgenden Schritte ausführen:
Öffnet den Facebook SDK 3.x LoginButton-Code und sah, wie der Button dort gestaltet wurde:
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));
Basierend auf der in dieser Antwort präsentierten Lösung habe ich die Tastenparameter während der onPostCreate()
wie folgt geändert:
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));
Wo meine benutzerdefinierten Abmessungen sind wie folgt:
<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>
Daraus ergibt sich das gewünschte Layout:
Die Höhe von LoginButton
hängt von seinen Füllungen und der Textgröße ab:
//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());
//...
}
Wenn Sie die Höhe über die XML-Datei ändern möchten, verwenden Sie die Eigenschaften Android:padding*
und Android:textSize
, oder erstellen Sie einen Stil dafür:
<style name="FacebookLoginButtonStyle">
<item name="Android:textSize">16sp</item>
<item name="Android:paddingTop">10sp</item>
<item name="Android:paddingBottom">10sp</item>
</style>
ich hatte das gleiche Problem und löste es, indem ich die Auffüllung und die Drawables in Java-Code wie folgt setzte:
authButton.setPadding(0, myTopDp, 0, myBottomDp);
authButton.setCompoundDrawablePadding(hostActivity.getResources().getDimensionPixelSize(R.dimen.fb_margin_override_textpadding));
authButton.setCompoundDrawablesWithIntrinsicBounds(myFbResource, 0, 0, 0);
oder wenn Sie Ihr Bild als gezeichnet verwenden
authButton.setCompoundDrawablesWithIntrinsicBounds(myFbDrawable, null, null, null);
Ich glaube, dass die OnPostCreate-Methode nicht erforderlich ist.
Da ich den Login-Text gravity
start anpassen wollte, ist ein Problem mit der setCompoundDrawablePadding
-Methode aufgetreten. Schließlich löste ich es mit einem benutzerdefinierten Layout. Ich denke, es ist eine viel einfachere Möglichkeit, die Facebook-Login-Schaltfläche anzupassen.
Hier ist das Endergebnis:
Das Layout 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>
Java-Code, der die benutzerdefinierten Facebook-Anmeldungsschaltflächenklicks verarbeitet:
@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
}
Setzen Sie den Button einfach in ein RelativeLayout. Meine Höhe beträgt 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>