Facebook SDK v4 LoginButton忽略XML自定义

最近发布的新版Facebook SDK for Android(v4.0)导致了我正在使用的自定义LoginButton的奇怪行为。 以下是如何在不同的SDK版本中呈现相同的XML的比较。

问题似乎是SDK 4.x中的FB图标不能正确拉伸以适应自定义大小的button,并且在4.0.1处, android:layout_height属性将完全忽略

我的问题是如何使SDK 4.x中的button像在SDK 3.x中一样? XML和Java解决scheme都是完全可以接受的。

适用于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 v3.x运行时的XML渲染

用于SDK 4.x的XML(button的包已重命名+我不得不改变宽度和字体以匹配g +button):

 <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(在Genymotion Nexus 5上运行,未修改4.4.4的屏幕截图)的外观如何: 在这里输入图像说明

SDK 4.0.1(Same Genymotion Nexus 5)的外观如何: 在这里输入图像说明

附加信息

  1. 摘自4.0 – > 4.0.1 SDK更改日志 :

loginbutton已更新,以正确测量其大小。

  1. 相关文章:

    • Facebook Android SDK 3.5中的自定义Facebookloginbutton图像
  2. 为了支持不同的屏幕尺寸,在loginbutton的上方,我有一个ViewPagerIndicator和一个ViewPager ,它被configuration为在定位具有定义高度的元素之后占用所有可用的垂直空间。

我设法得到所需的结果,按照以下步骤:

  1. 打开Facebook SDK 3.x LoginButton代码 ,看看button的样式是如何设置的:

     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. 基于这个答案中的解决scheme,我在onPostCreate()期间改变了button参数,如下所示:

     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> 

这导致所需的布局:

所需的布局:D

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属性或为其创build样式:

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

或者如果您使用您的图像作为drawable

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

我相信OnPostCreate方法不是必需的。

因为我想自定义login文本gravity启动,我遇到了setCompoundDrawablePadding方法的问题。 最后,我通过使用自定义布局来解决它。 我认为这是一个更简单的方法来定制Facebook的loginbutton。

最终结果如下:

Facebook登录按钮和Google登录按钮

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

处理自定义Facebookloginbutton的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 } 

人们,你只需要设置paddingTop和paddingBottom的值。

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