最近リリースされた新しい Facebook SDK for Android(v4.0) は、カスタマイズした LoginButton を使用しているため、奇妙な動作を引き起こしました。以下は、異なるバージョンのSDKで同じXMLがどのようにレンダリングされるかの比較です。
問題は、SDK 4.xのFBアイコンがカスタムサイズのボタンに合わせて適切に伸縮しないことと、4.0.1ではAndroid:layout_height
プロパティはignoredである。
私の質問はSDK 3.xのようにSDK 4.xにボタンを表示するにはどうすればよいですか?XMLとJavaソリューションは完全に受け入れられます。
SDK 3.xのXML:
<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"
/>
SDK 3.xでの表示(CM11Sを実行しているOnePlus Oneでのスクリーンショット):
SDK 4.xのXML(ボタンのパッケージの名前が変更され、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"
/>
SDK 4.0の外観(変更されていない4.4.4を実行しているGenymotion Nexus 5でのスクリーンショット):
SDK 4.0.1(同じGenymotion Nexus 5)での表示:
ログインボタンが更新され、サイズが適切に測定されます。
関連記事:
さまざまな画面サイズをサポートするために、ログインボタンの上に ViewPagerIndicator と ViewPager があり、定義された高さの要素を配置した後に残るすべての利用可能な垂直スペースを占有するように構成されています。
次の手順を実行して、目的の結果を得ることができました。
Facebook SDK 3.x LoginButton code を開き、そこでボタンがどのようにスタイルされているかを確認しました。
_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));
_
この回答 で提示されたソリューションに基づいて、onPostCreate()
の間にボタンパラメーターを次のように変更しました。
_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));
_
カスタムディメンションは次のとおりです。
_<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>
_
これにより、目的のレイアウトが得られます。
LoginButton
の高さは、パディングとテキストサイズに関連しています。
//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());
//...
}
したがって、xmlファイルを使用して高さを変更する場合は、Android:padding*
およびAndroid:textSize
プロパティまたはスタイルを作成します。
<style name="FacebookLoginButtonStyle">
<item name="Android:textSize">16sp</item>
<item name="Android:paddingTop">10sp</item>
<item name="Android:paddingBottom">10sp</item>
</style>
私は同じ問題に直面し、Javaこのようなコードでパディングとドロウアブルを設定することで解決しました:
authButton.setPadding(0, myTopDp, 0, myBottomDp);
authButton.setCompoundDrawablePadding(hostActivity.getResources().getDimensionPixelSize(R.dimen.fb_margin_override_textpadding));
authButton.setCompoundDrawablesWithIntrinsicBounds(myFbResource, 0, 0, 0);
または画像を描画可能として使用する場合
authButton.setCompoundDrawablesWithIntrinsicBounds(myFbDrawable, null, null, null);
OnPostCreateメソッドは必要ないと思います。
ログインテキストgravity
startをカスタマイズしたかったため、setCompoundDrawablePadding
メソッドで問題が発生しました。最後に、カスタムレイアウトを使用して解決しました。 Facebookのログインボタンをカスタマイズする方がはるかに簡単な方法だと思います。
最終結果は次のとおりです。
レイアウト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>
Facebookのカスタムログインボタンのクリックを処理するJavaコード:
@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
}
ボタンをRelativeLayoutに配置するだけです。私の身長は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>