Skip to content

Commit eb031c7

Browse files
yos1psamtstern
authored andcommitted
Custom Layout for AuthMethodPickerActivity (#1494)
1 parent 0fb425e commit eb031c7

File tree

11 files changed

+488
-124
lines changed

11 files changed

+488
-124
lines changed

app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import android.widget.RadioButton;
3434
import android.widget.TextView;
3535

36+
import com.firebase.ui.auth.AuthMethodPickerLayout;
3637
import com.firebase.ui.auth.AuthUI;
3738
import com.firebase.ui.auth.AuthUI.IdpConfig;
3839
import com.firebase.ui.auth.ErrorCodes;
@@ -48,6 +49,7 @@
4849
import com.google.firebase.auth.FirebaseAuth;
4950

5051
import java.util.ArrayList;
52+
import java.util.Arrays;
5153
import java.util.List;
5254

5355
import butterknife.BindView;
@@ -258,6 +260,32 @@ public Intent buildSignInIntent(@Nullable String link) {
258260
return builder.build();
259261
}
260262

263+
@OnClick(R.id.customised_sign_in)
264+
public void signInCustomLayout() {
265+
AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout
266+
.Builder(R.layout.auth_method_picker_custom_layout)
267+
.setupGoogleButtonId(R.id.custom_google_signin_button)
268+
.setupEmailButtonId(R.id.custom_email_signin_clickable_text)
269+
.build();
270+
271+
//For now we only test Google and Email
272+
List<IdpConfig> availableProviders = Arrays.asList(
273+
new AuthUI.IdpConfig.GoogleBuilder()
274+
.setScopes(getGoogleScopes())
275+
.build(),
276+
new IdpConfig.EmailBuilder()
277+
.setRequireName(mRequireName.isChecked())
278+
.setAllowNewAccounts(mAllowNewEmailAccounts.isChecked())
279+
.build());
280+
281+
startActivityForResult(
282+
AuthUI.getInstance().createSignInIntentBuilder()
283+
.setAvailableProviders(availableProviders)
284+
.setAuthMethodPickerLayout(customLayout)
285+
.build(),
286+
RC_SIGN_IN);
287+
}
288+
261289
@OnClick(R.id.sign_in_silent)
262290
public void silentSignIn() {
263291
AuthUI.getInstance().silentSignIn(this, getSelectedProviders())
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:orientation="vertical"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent" android:gravity="center_horizontal">
6+
7+
<TextView
8+
android:text="@string/launch_title"
9+
android:layout_width="match_parent"
10+
android:layout_height="wrap_content"
11+
android:textSize="25sp"
12+
android:textAlignment="center"
13+
android:layout_margin="24dp"
14+
android:layout_marginBottom="0dp"/>
15+
16+
<TextView android:layout_width="match_parent"
17+
android:layout_height="wrap_content"
18+
android:textAlignment="center"
19+
android:textSize="16sp"
20+
android:layout_margin="16dp"
21+
android:layout_marginBottom="32dp"
22+
android:text="@string/custom_auth_picker_hint"/>
23+
24+
<LinearLayout
25+
android:layout_width="match_parent"
26+
android:layout_height="wrap_content"
27+
android:orientation="horizontal"
28+
android:gravity="center_horizontal">
29+
30+
<Button
31+
android:id="@+id/custom_google_signin_button"
32+
android:layout_width="wrap_content"
33+
android:layout_height="wrap_content"
34+
android:text="@string/providers_google"/>
35+
</LinearLayout>
36+
37+
<LinearLayout
38+
android:layout_width="match_parent"
39+
android:layout_height="wrap_content"
40+
android:gravity="center_horizontal"
41+
android:layout_marginTop="8dp">
42+
43+
<TextView android:layout_width="wrap_content"
44+
android:layout_height="wrap_content"
45+
android:text="@string/custom_auth_use_email"/>
46+
47+
<TextView android:id="@+id/custom_email_signin_clickable_text"
48+
android:layout_width="wrap_content"
49+
android:layout_height="wrap_content"
50+
android:text="@string/providers_email"
51+
android:clickable="true"
52+
android:focusable="true"
53+
android:textStyle="bold"
54+
android:layout_marginLeft="4dp"
55+
android:layout_marginStart="4dp"/>
56+
</LinearLayout>
57+
</LinearLayout>

app/src/main/res/layout/auth_ui_layout.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@
4646
android:layout_marginBottom="16dp"
4747
android:text="@string/sign_in_silent" />
4848

49+
<Button
50+
android:id="@+id/customised_sign_in"
51+
style="@style/Widget.AppCompat.Button.Colored"
52+
android:layout_width="wrap_content"
53+
android:layout_height="wrap_content"
54+
android:layout_marginTop="8dp"
55+
android:layout_gravity="center"
56+
android:layout_marginBottom="16dp"
57+
android:text="@string/custom_auth_picker_start"/>
58+
4959
<TextView
5060
style="@style/Base.TextAppearance.AppCompat.Subhead"
5161
android:layout_width="wrap_content"

app/src/main/res/values/strings.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@
9494
<string name="idp_token">IDP Token</string>
9595
<string name="idp_secret">IDP Secret</string>
9696

97+
<!-- Auth UI - Custom AuthMethodPickerLayout -->
98+
<string name="custom_auth_picker_start">Start with Custom Layout</string>
99+
<string name="custom_auth_picker_hint">You can use customised layout like this to improve your user experience!
100+
</string>
101+
<string name="custom_auth_use_email">Or you can also sign in by using</string>
102+
103+
97104
<!-- Storage -->
98105
<string name="choose_image">Choose Image</string>
99106
<string name="upload">Upload</string>
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package com.firebase.ui.auth;
2+
3+
import android.os.Bundle;
4+
import android.os.Parcel;
5+
import android.os.Parcelable;
6+
import android.support.annotation.IdRes;
7+
import android.support.annotation.LayoutRes;
8+
import android.support.annotation.NonNull;
9+
import com.google.firebase.auth.*;
10+
11+
import java.util.*;
12+
13+
/**
14+
* Layout model to help customizing the AuthPicker
15+
*/
16+
public class AuthMethodPickerLayout implements Parcelable {
17+
18+
@LayoutRes
19+
private int mainLayout;
20+
21+
/**
22+
* PROVIDER_ID -> IdRes of the Button
23+
*/
24+
private Map<String, Integer> providersButton;
25+
26+
private AuthMethodPickerLayout() {
27+
}
28+
29+
private AuthMethodPickerLayout(@NonNull Parcel in) {
30+
this.mainLayout = in.readInt();
31+
Bundle buttonsBundle = in.readBundle(getClass().getClassLoader());
32+
this.providersButton = new HashMap<>();
33+
34+
for (String key : buttonsBundle.keySet()) {
35+
this.providersButton.put(key, buttonsBundle.getInt(key));
36+
}
37+
}
38+
39+
@LayoutRes
40+
public int getMainLayout() {
41+
return mainLayout;
42+
}
43+
44+
public Map<String, Integer> getProvidersButton() {
45+
return providersButton;
46+
}
47+
48+
@Override
49+
public int describeContents() {
50+
return 0;
51+
}
52+
53+
@Override
54+
public void writeToParcel(Parcel parcel, int flags) {
55+
parcel.writeInt(mainLayout);
56+
57+
Bundle bundle = new Bundle();
58+
for (String key : providersButton.keySet()) {
59+
bundle.putInt(key, providersButton.get(key));
60+
}
61+
parcel.writeBundle(bundle);
62+
}
63+
64+
public static final Creator<AuthMethodPickerLayout> CREATOR = new Creator<AuthMethodPickerLayout>() {
65+
66+
@Override
67+
public AuthMethodPickerLayout createFromParcel(Parcel in) {
68+
return new AuthMethodPickerLayout(in);
69+
}
70+
71+
@Override
72+
public AuthMethodPickerLayout[] newArray(int size) {
73+
return new AuthMethodPickerLayout[size];
74+
}
75+
};
76+
77+
/**
78+
* Builder for AuthMethodPickerLayout
79+
*/
80+
public static class Builder {
81+
82+
private Map<String, Integer> providersMapping;
83+
private AuthMethodPickerLayout instance;
84+
85+
public Builder(@LayoutRes int mainLayout) {
86+
instance = new AuthMethodPickerLayout();
87+
instance.mainLayout = mainLayout;
88+
providersMapping = new HashMap<>();
89+
}
90+
91+
public AuthMethodPickerLayout.Builder setupGoogleButtonId(@IdRes int googleBtn) {
92+
providersMapping.put(GoogleAuthProvider.PROVIDER_ID, googleBtn);
93+
return this;
94+
}
95+
96+
public AuthMethodPickerLayout.Builder setupFacebookButtonId(@IdRes int facebookBtn) {
97+
providersMapping.put(FacebookAuthProvider.PROVIDER_ID, facebookBtn);
98+
return this;
99+
}
100+
101+
public AuthMethodPickerLayout.Builder setupTwitterButtonId(@IdRes int twitterBtn) {
102+
providersMapping.put(TwitterAuthProvider.PROVIDER_ID, twitterBtn);
103+
return this;
104+
}
105+
106+
public AuthMethodPickerLayout.Builder setupEmailButtonId(@IdRes int emailButton) {
107+
providersMapping.put(EmailAuthProvider.PROVIDER_ID, emailButton);
108+
return this;
109+
}
110+
111+
public AuthMethodPickerLayout.Builder setupPhoneButtonId(@IdRes int phoneButton) {
112+
providersMapping.put(PhoneAuthProvider.PROVIDER_ID, phoneButton);
113+
return this;
114+
}
115+
116+
public AuthMethodPickerLayout.Builder setupAnonymousButtonId(@IdRes int anonymousButton) {
117+
providersMapping.put(AuthUI.ANONYMOUS_PROVIDER, anonymousButton);
118+
return this;
119+
}
120+
121+
public AuthMethodPickerLayout build() {
122+
//Validating the button set
123+
for (String key : providersMapping.keySet()) {
124+
if (!AuthUI.SUPPORTED_PROVIDERS.contains(key)) {
125+
throw new IllegalArgumentException("Unknown provider: " + key);
126+
}
127+
}
128+
instance.providersButton = providersMapping;
129+
return instance;
130+
}
131+
}
132+
}

auth/src/main/java/com/firebase/ui/auth/AuthUI.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,7 @@ private abstract class AuthIntentBuilder<T extends AuthIntentBuilder> {
11011101
boolean mAlwaysShowProviderChoice = false;
11021102
boolean mEnableCredentials = true;
11031103
boolean mEnableHints = true;
1104+
AuthMethodPickerLayout mAuthMethodPickerLayout = null;
11041105

11051106
/**
11061107
* Specifies the theme to use for the application flow. If no theme is specified, a
@@ -1230,6 +1231,12 @@ public T setIsSmartLockEnabled(boolean enableCredentials, boolean enableHints) {
12301231
return (T) this;
12311232
}
12321233

1234+
@NonNull
1235+
public T setAuthMethodPickerLayout(@NonNull AuthMethodPickerLayout authMethodPickerLayout) {
1236+
mAuthMethodPickerLayout = authMethodPickerLayout;
1237+
return (T) this;
1238+
}
1239+
12331240
/**
12341241
* Forces the sign-in method choice screen to always show, even if there is only
12351242
* a single provider configured.
@@ -1301,7 +1308,8 @@ protected FlowParameters getFlowParams() {
13011308
mEnableHints,
13021309
mEnableAnonymousUpgrade,
13031310
mAlwaysShowProviderChoice,
1304-
mEmailLink);
1311+
mEmailLink,
1312+
mAuthMethodPickerLayout);
13051313
}
13061314
}
13071315
}

auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import android.support.annotation.StyleRes;
2424
import android.text.TextUtils;
2525

26+
import com.firebase.ui.auth.AuthMethodPickerLayout;
2627
import com.firebase.ui.auth.AuthUI.IdpConfig;
2728
import com.firebase.ui.auth.util.ExtraConstants;
2829
import com.firebase.ui.auth.util.Preconditions;
@@ -51,6 +52,7 @@ public FlowParameters createFromParcel(Parcel in) {
5152
boolean enableAnonymousUpgrade = in.readInt() != 0;
5253
boolean alwaysShowProviderChoice = in.readInt() != 0;
5354
String emailLink = in.readString();
55+
AuthMethodPickerLayout customLayout = in.readParcelable(AuthMethodPickerLayout.class.getClassLoader());
5456

5557
return new FlowParameters(
5658
appName,
@@ -63,7 +65,8 @@ public FlowParameters createFromParcel(Parcel in) {
6365
enableHints,
6466
enableAnonymousUpgrade,
6567
alwaysShowProviderChoice,
66-
emailLink);
68+
emailLink,
69+
customLayout);
6770
}
6871

6972
@Override
@@ -98,6 +101,9 @@ public FlowParameters[] newArray(int size) {
98101
public final boolean enableAnonymousUpgrade;
99102
public final boolean alwaysShowProviderChoice;
100103

104+
@Nullable
105+
public final AuthMethodPickerLayout authMethodPickerLayout;
106+
101107
public FlowParameters(
102108
@NonNull String appName,
103109
@NonNull List<IdpConfig> providers,
@@ -109,7 +115,8 @@ public FlowParameters(
109115
boolean enableHints,
110116
boolean enableAnonymousUpgrade,
111117
boolean alwaysShowProviderChoice,
112-
@Nullable String emailLink) {
118+
@Nullable String emailLink,
119+
@Nullable AuthMethodPickerLayout authMethodPickerLayout) {
113120
this.appName = Preconditions.checkNotNull(appName, "appName cannot be null");
114121
this.providers = Collections.unmodifiableList(
115122
Preconditions.checkNotNull(providers, "providers cannot be null"));
@@ -122,6 +129,7 @@ public FlowParameters(
122129
this.enableAnonymousUpgrade = enableAnonymousUpgrade;
123130
this.alwaysShowProviderChoice = alwaysShowProviderChoice;
124131
this.emailLink = emailLink;
132+
this.authMethodPickerLayout = authMethodPickerLayout;
125133
}
126134

127135
/**
@@ -144,6 +152,7 @@ public void writeToParcel(Parcel dest, int flags) {
144152
dest.writeInt(enableAnonymousUpgrade ? 1 : 0);
145153
dest.writeInt(alwaysShowProviderChoice ? 1 : 0);
146154
dest.writeString(emailLink);
155+
dest.writeParcelable(authMethodPickerLayout, flags);
147156
}
148157

149158
@Override

0 commit comments

Comments
 (0)