How to use setOutlineProvider instead of setOutline in Lollipop

24,592

Solution 1

Just to complete the @ianhanniballake answer:

Button fab = (Button) findViewById(R.id.fab);
//Outline outline = new Outline();
//outline.setOval(0, 0, size, size);
//fab.setOutline(outline);  
ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {
            // Or read size directly from the view's width/height
            int size = getResources().getDimensionPixelSize(R.dimen.fab_size);
            outline.setOval(0, 0, size, size);
        }
    };
fab.setOutlineProvider(viewOutlineProvider);

Solution 2

Per customizing view shadows and outlines training:

You can create oval and rectangular outlines with rounded corners using the methods in the Outline class. The default outline provider for views obtains the outline from the view's background. To prevent a view from casting a shadow, set its outline provider to null.

So your ViewOutlineProvider just needs to call setOval(0, 0, size, size) on the outline parameter to getOutline():

public void getOutline (View view, Outline outline) {
    // Or read size directly from the view's width/height
    int size = getResources().getDimensionPixelSize(R.dimen.fab_size);
    outline.setOval(0, 0, size, size);
}

Solution 3

Every View has an Outline object and a ViewOutlineProvider(V.O.P) object. As the name suggest viewoutlineprovider provides the outline to the view indirectly.

What the view does is it passes its outline object to the V.O.P and the V.O.P updates it.

so you have the view's Outline object in the getOutline method of the VOP as a parameter,simply update it.

ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
    @Override
    public void getOutline(View view, Outline outline) {
        outline.setOval(0, 0, view.getWidth(), view.getHeight());
    }
};
fab.setOutlineProvider(viewOutlineProvider);
Share:
24,592
Smiler
Author by

Smiler

Updated on July 09, 2022

Comments

  • Smiler
    Smiler almost 2 years

    For the earlier L Preview there were some examples like shown below to add to your code in order to use an FAB (Floating Action Button).

    But unfortunately I can't use that same code to implement an FAB due to the setOutline method not being supported anymore, but it appears to have been replaced by an alternative method 'fab.setOutlineProvider(ViewOutlineProvider);'. could anyone explain how to use this?...

    It is probably something really simple that I am missing, but any help would be much appreciated.

    // Outline
    int size = getResources().getDimensionPixelSize(R.dimen.fab_size);
    Outline outline = new Outline();
    outline.setOval(0, 0, size, size);
    
    Button fab = (Button) findViewById(R.id.fab);
    fab.setOutline(outline);
    fab.setClipToOutline(true);
    
  • russellhoff
    russellhoff over 9 years
    You also should check, beforehand, the current version of the device, as this method is only supported after android L.
  • android developer
    android developer about 8 years
    What does it do exactly? Show the correct shadow of the view?
  • ianhanniballake
    ianhanniballake about 8 years
    @androiddeveloper - that's correct. By default the shadow is cast using the bounds of your view, which works great for opaque rectangular Views that fill their entire bounds, but obviously not so much for (in this case) circular Views.
  • android developer
    android developer about 8 years
    I see. So what should be used if I have a weird shape for a view, or a view that changes its shape ?
  • ianhanniballake
    ianhanniballake about 8 years
    @androiddeveloper - you can set an arbitrary path with setConvexPath(). You can call invalidateOutline at any time if your View changes shape dynamically and you want the outline updated.
  • Jemshit Iskenderov
    Jemshit Iskenderov about 6 years
    what about pre api 21?
  • ianhanniballake
    ianhanniballake about 6 years
    @JemshitIskenderov - there's no such thing as elevation pre-API 21, so no shadows and no need for a specific outline.
  • ianhanniballake
    ianhanniballake about 6 years
    @JemshitIskenderov - you'll need to bake in fake elevation and shadows into your background assets then (this is how CardView works, for instance). There is no API support for pre-21
  • Jemshit Iskenderov
    Jemshit Iskenderov about 6 years
    @ianhanniballake thanks for response. went with Canvas way