firebase / FirebaseUI-Android

Optimized UI components for Firebase
https://firebaseopensource.com/projects/firebase/firebaseui-android/
Apache License 2.0
4.63k stars 1.83k forks source link

Proposal: Allow fully customized XML layouts for the AuthMethodPickerActivity #1477

Closed samtstern closed 5 years ago

samtstern commented 6 years ago

Proposal

Allow developers to pass their own XML resource for the main login screen:

AuthUI.getInstance().createSignInIntentBuilder()
    // ...
    .setTheme(...)
    .setMainLayout(R.xml.my_custom_layout) // If not provided, default used
    .build()

We would define an implicit public API specifying which resource IDs need to be present in that XML screen in order for us to add controls to it, such as:

Note that this proposal only affects the first screen. The rest would still be governed by the setTheme() attribute. There are too many other screens, and their functionality is too complex, to allow for full user customization of every one.

Rationale

We have gotten many requests to be able to customize the main UI more such as:

1383, #753, #619, #266, #236, #229

When looking at popular Android apps, the sign-in method selection screen is often a showcase for the brand and the UI varies from app to app. There's no way to add more "options" to our system to encompass all use cases.

Here are some examples of screens from other apps that I like and would like to enable. While we can't enable every single feature shown in these screenshots, we can at least allow developers to get most of the way there and create an immersive look and feel without writing anything besides XML.

cc @bojeil-google @morganchen12 @lsirac @SUPERCILEX

SUPERCILEX commented 6 years ago

I think you're right. The main issue I see is that all those screenshots have data which would probably be downloaded dynamically. If we really wanted to support as many use cases as possible, we'd probably have to create a service which gives devs access to the view hierarchy so they can do animations, dynamic stuff, whatever. I'm using a service for the full account linking PR and I've been wanting to do something similar for the email sign-up page to allow custom field add/removal and validation.

In any case, this seems like a step in the right direction to me. 👍

cutiko commented 6 years ago

Greetings

I think this is a great improvement, is what I would expect as customization. I would like to suggest something about this:

which resource IDs need to be present in that XML

That seems prone to human error, a formal structure that represents the layout could be useful:

public class AuthLayout {
       @LayoutRes
        private int layout;
        @IdRes
        private int facebookBtn, googleBtn, emailBtn;
        //Constructors, getters and setters...
}

This way we have to only be careful to have one id for each provider

dimipaun commented 6 years ago

In addition to this, we should export the building blocks of this screen so that users can easily recreate it -- this would solve all these problems and more!

For example, we want to add additional login buttons (e.g. Login with XYZ) which is basically impossible to do right now as the building blocks of this page are not public.

samtstern commented 6 years ago

@cutiko that's a good idea! It would avoid having XML as an implicit API and use something more explicit.

@dimipaun we'd love to do something like that but right now it's really hard because we're managing a whole stack of Activities. Without owning the root activity, there are some things we can't do. It may be possible to define an interface so that anyone could make their own root activity, but that's a non-goal right now.

samtstern commented 6 years ago

@iamyaoxi has started working on this using the suggestions of everyone here.

yos1p commented 6 years ago

Yes! And thanks everyone for those great ideas! And if possible, please review the PR and give your opinion on it.

samtstern commented 6 years ago

Just merged the initial implementation for this by @iamyaoxi, so this should be ready to go for 4.3.0

cutiko commented 6 years ago

Greetings

I have a doubt, what if someone does something like this:

 <FrameLayout>

     <Button
        text="Facebook"/>

    <fragment
      id="coolFragment"
      name="com.package.project.CoolFragment"/>

</FrameLayout>

We can pass a Fragment and then in onActivityCreated access to whatever we want. I can think of plenty cool things I would like to do, but, can this create a conflict in anyhow?

samtstern commented 6 years ago

@cutiko that's actually a pretty interesting idea! There's nothing that will break right away (that I can think of off the top of my head), however we're not going to make any guarantees about the Activity lifecycle or what other Fragments may be present so make sure to do a lot of testing if you go down that road.

cutiko commented 6 years ago

Greetings

I'm working on this basing my self on this.

I'm having some problems as well:

samtstern commented 6 years ago

@cutiko thanks for trying this! Are you using the 4.3.0-SNAPSHOT builds?

If smart lock is not disable .setIsSmartLockEnabled(false) then the Google account chooser dialog is showed before seen the kickoff activity

Are you sure that's the Google account picker and not just the SmartLock hint selector? They look very very similar. Screenshot would help.

if there is only Email sign-in method, then the kickoff activity is skipped, going directly to the specific method activity

This is intended behavior. If you want to always show the sign-in screen, call setAlwaysShowSignInMethodScreen(true) on the builder.

If only Google is available and the smart lock is disabled, then nothing happens

Is there anything in the logs here? This sounds like a bug!

cutiko commented 6 years ago
repositories {
    maven { url "https://oss.jfrog.org/artifactory/oss-snapshot-local" }
}

dependencies {
    ...
    implementation 'com.firebaseui:firebase-ui-auth:4.3.0-SNAPSHOT'
    ...
}

Screenshot as requested SCREENSHOT

Video can be seen here

Ok, that fixes a lot, sorry was not aware of the method.

Couldn't find anything relevant on the logs this is the current repo branch

samtstern commented 6 years ago

@cutiko glad that helped! I will look into the thing about SmartLock exiting, that's a bug.

samtstern commented 6 years ago

@cutiko hmm once I dismiss the SmartLock dialog I get this (the Google sign in dialog):

screen shot 2018-11-20 at 4 31 21 pm

So I am a little stuck on how to reproduce your error. But I will keep trying!

cutiko commented 6 years ago

@samtstern can you take a look at this file found something on the logcat is commented there.

Google is enabled on the console, SHA is set on the project settings...

I think I found something else:

I'm confused, I was able to reproduce the error, then deleting the account and trying to reproducing it again and I can't.

I'm afraid it could be me doing something wrong, but someone else on SO had the same problem

cutiko commented 5 years ago

I think is working, you can see the first version of the demo here

SEE VIDEO

In case anyone wants to take a look more closely, this is the repo

For the moment I want to make a dirty demo just trying to push the layout customization to the max. I'm planning to clean up the code and add some others later, I want to see what happens with a service binding and more than one fragment and using broadcast. All of that should end up being a juicy example of how far this new release can be pushed.

In my regards, I only have kind words to everyone who works on this project, this next release is going to completely blow everyone mind Thanks everybody this is awesome

samtstern commented 5 years ago

@cutiko that's so cool! I am gonna share that with the whole team. And hopefully we can get to the bottom of your SmartLock/Google issues.

samtstern commented 5 years ago

This has been released in version 4.3.0.

sipersso commented 5 years ago

@samtstern Is it possible to have a separate theme for the AuthMethodPickerActivity and the rest of the screens. I am using the customization, which is great, but I don't want the toolbar och the AuthMethodPicker. If I remove it using the them, it will also remove the toolbar from all other activities, like the email sign in flow, where the toolbars are actually useful.

Is there any way to achieve this?

samtstern commented 5 years ago

@sipersso there's no way to do this right now but you may be able to do this in a hacky way.

Use the custom layout to put an invisible <fragment> into the custom UI. Then inside the Fragment do something like getSupportActionBar().hide() and make the toolbar disappear at runtime.

sipersso commented 5 years ago

@samtstern thank you! As you said, very hacky, but I think it might work. I'll give that a try.

sipersso commented 5 years ago

@samtstern works perfectly. Thank you!

nathanvogel commented 5 years ago

Hacky but works :) Here's the full code for the lazy ones like me:

class DisableActionBarFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.empty, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        activity?.actionBar?.hide()
        (activity as? AppCompatActivity)?.supportActionBar?.hide()
    }
}
thestch commented 4 years ago

@samtstern Hi, is it possible to register listeners into the UI elements of the layout used by AuthMethodPickerLayout? The reason is that while I'm using a custom layout, I would also need to register listeners to EditText etc. to get other user details such as their name, instead of launching a new activity to let them enter it.

samtstern commented 4 years ago

Sorry that is not possible. You'll have to fork the library if you want to do something that advanced.

On Tue, Mar 10, 2020, 7:04 AM thestch notifications@github.com wrote:

@samtstern https://github.com/samtstern Hi, is it possible to register listeners into the UI elements of the layout used by AuthMethodPickerLayout? The reason is that while I'm using a custom layout, I would also need to register listeners to EditText etc. to get other user details such as their name, instead of launching a new activity to let them enter it.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/firebase/FirebaseUI-Android/issues/1477?email_source=notifications&email_token=ACATB2WWGHEBH2VQXXHTMMDRGZCHJA5CNFSM4F2PZPDKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOLRHMA#issuecomment-597103536, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACATB2VPXS2QNB2F7S25QRTRGZCHJANCNFSM4F2PZPDA .

cutiko commented 4 years ago

@thestch take a look at this you might find a hack arround https://github.com/cutiko/FirebaseUiAuth Is old but worth the try

mangeshghotage commented 4 years ago

I am trying to create a UI similar to what is shown in the last screenshot (TikTok) by OP. In my case FirebaseUI is not showing transparent background. How to achieve such UI having transparent background? PS: Here is my detailed SO post