Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I set the elevation on a view that I add programmatically?

Disclaimer: I am using Xamarin.Android.

I created a view, set its elevation, and then add it to my main layout. The view successfully gets added to the layout when I trigger the event, but there is no elevation shadow whatsoever.

Here is what I am working with:

View that gets added programmatically:

public class TooltipTest : FrameLayout
{
    private Context context;
    private ShapeDrawable box;
    private View carrot;
    private string message;

    public TextView TooltipText
    {
        get;
        private set;
    }

    public TooltipTest(Context context, string message) : base(context)
    {
        this.context = context;
        this.message = message;

        Initialize();
    }

    private void Initialize()
    {
        CreateText();
    }

    private void CreateText()
    {
        int paddingTopBottom = 30;
        int paddingLeftRight = 27;

        TooltipText = new TextView(context);
        TooltipText.Text = message;
        TooltipText.SetTextColor(new Color(ContextCompat.GetColor(context, Resource.Color.tooltipText)));
        TooltipText.SetTextSize(ComplexUnitType.Sp, 14f);
        TooltipText.SetPadding(paddingLeftRight, paddingTopBottom, paddingLeftRight, paddingTopBottom);
        TooltipText.SetBackgroundColor(new Color(ContextCompat.GetColor(context, Resource.Color.tooltipBackground)));

        AddView(TooltipText);
    }

Event to add the view:

        ButtonTest.Click += (sender, e) => {
            var tooltip = new TooltipTest(this, Resources.GetString(Resource.String.test_text));
            var tooltipParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);
            tooltip.Elevation = 20f;
            ParentLayout.AddView(tooltip, tooltipParams);
        };

Any ideas on why the shadow doesn't show? I've tried setting SetClipToPadding(false) and SetClipChildren(false) on the tooltip, but that had no effect.

like image 228
hellaandrew Avatar asked Jun 09 '16 01:06

hellaandrew


2 Answers

Use the AppCompat method ViewCompat.SetElevation(View, int) to set the elevation as desired. But on a pre-Lollipop devices, the method appears to do nothing. The only way I found to render shadows to pre-Lollipop UI elements was using a background instead:

  android:background="@android:drawable/dialog_holo_light_frame"

If you want do dig more on this topic, go to this reddit topic and search for elevation. There are really good updated information there.

like image 136
jzeferino Avatar answered Sep 28 '22 07:09

jzeferino


I have discovered why setting the elevation wasn't working on my custom TooltipTest view. The problem was that that view itself didn't have any background set, and according to Android's documentation, there needs to be some sort of resource in the background property, whether it be a color or some drawable.

As you can see from my original post, within my TooltipTest class, which inherits from a FrameLayout, I create a TextView (TooltipText) and add it to the layout. Then, within my Activity class, I set the elevation on that TooltipTest class. Since I didn't explicitly set a Background resource for the TooltipTest Layout class, Android didn't know what to draw a shadow for.

All I had to do to fix my problem was add Elevation to the TooltipText object, not the TooltipTest object.

private void CreateText()
{
    int paddingTopBottom = 30;
    int paddingLeftRight = 27;

    TooltipText = new TextView(context);
    TooltipText.Text = message;
    TooltipText.SetTextColor(new Color(ContextCompat.GetColor(context, Resource.Color.tooltipText)));
    TooltipText.SetTextSize(ComplexUnitType.Sp, 14f);
    TooltipText.SetPadding(paddingLeftRight, paddingTopBottom, paddingLeftRight, paddingTopBottom);
    TooltipText.SetBackgroundColor(new Color(ContextCompat.GetColor(context, Resource.Color.tooltipBackground)));

    TooltipText.Elevation = 21f; //(or whatever value you want)

    AddView(TooltipText);
}

If you want a shadow on the TooltipTest class, you would need to set the Background property:

private void CreateText()
{
    int paddingTopBottom = 30;
    int paddingLeftRight = 27;

    TooltipText = new TextView(context);
    TooltipText.Text = message;
    TooltipText.SetTextColor(new Color(ContextCompat.GetColor(context, Resource.Color.tooltipText)));
    TooltipText.SetTextSize(ComplexUnitType.Sp, 14f);
    TooltipText.SetPadding(paddingLeftRight, paddingTopBottom, paddingLeftRight, paddingTopBottom);
    TooltipText.SetBackgroundColor(new Color(ContextCompat.GetColor(context, Resource.Color.tooltipBackground)));

    SetBackgroundColor (new Color (ContextCompat.GetColor (context, Resource.Color.white)));

    AddView(TooltipText);
}

Doing it the latter way would give you an ugly white background with a shadow under it. However, you can use any sort of drawable you want for the Background property. Instead of using SetBackgroundColor(Color color), you can do Background = (some drawable);

like image 30
hellaandrew Avatar answered Sep 28 '22 07:09

hellaandrew