androidandroid-drawableandroid-shape

Android drawable tooltip arrow box


I tried the below code to create a popup window with a tooltip-like arrow on top. picture attached. But I am getting something different as a result.
popup inflater :

LayoutInflater inflater = (LayoutInflater)
                        getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              View  view = inflater.inflate(R.layout.popup, null);
              mypopupWindow = new PopupWindow(view,500, RelativeLayout.LayoutParams.WRAP_CONTENT, true);            
              mypopupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
              mypopupWindow.showAsDropDown(v,-153,0);

popup layout :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:layout_marginTop="50dp"
        android:background="@drawable/shadow_recta"
        android:orientation="vertical"
        android:gravity="center">
     <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="text long text" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button"/>
</LinearLayout>

drawable file :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:gravity="top|center_horizontal" >
        <rotate android:fromDegrees="0" android:toDegrees="-45"
            android:pivotX="0%" android:pivotY="50%" >
            <shape android:shape="rectangle">
                <size android:width="24dp" android:height="24dp" />
                <stroke android:color="@android:color/holo_blue_bright" android:width="1dp"/>
            </shape>
        </rotate>
    </item>
    <item>
        <shape android:shape="rectangle">
            <size android:width="206dp" android:height="76dp" />
            <solid android:color="@android:color/white" />
            <stroke android:color="@android:color/holo_blue_bright"  android:width="1dp"/>
            <corners android:radius="2dp" />
        </shape>
    </item>

    <item android:gravity="top|center_horizontal">
        <rotate
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fromDegrees="-45"
            android:pivotX="-50%"
            android:pivotY="60%"
            android:toDegrees="35">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/white" />
                <size
                    android:width="24dp"
                    android:height="24dp" />
                <stroke
                    android:width="1dp"
                    android:color="@android:color/holo_blue_bright" />
            </shape>
        </rotate>
    </item>
</layer-list>

Expected image : enter image description here

Output i am getting : enter image description here

Please help me to create a box as in the expected image.


Solution

  • It's not that difficult, key points are three to make this layer-list Drawable:


    1. Create the layer-list Drawable:

    <layer-list
        xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item                      //background part
            android:top="17dp">    //margin top, half of the 【rotated】 rectangle height
    
            <shape
                android:shape="rectangle">
    
                <solid 
                    android:color="@color/purple_200" />
    
                <corners 
                    android:radius="8dp" />
    
                <padding                    //important part
                    android:top="17dp" />   //offset the margin top, shows up the tooltip perfectly
    
            </shape>
    
        </item>
    
        <item                       //tooltip part
            android:width="24dp"    //size must be fixed
            android:height="24dp"
            android:end="32dp"     //margin end (right)
            android:gravity="end"  //place wherever you want 
            android:top="-12dp">   //margin top, negative half of its height, display half of this rotated rectangle
    
            <rotate 
                android:fromDegrees="45">
    
                <shape 
                    android:shape="rectangle">
    
                    <solid 
                        android:color="@color/purple_500" />    //change back to background part color after your experiment and testing
    
                </shape>
    
            </rotate>
    
        </item>
    
    </layer-list>
    

    2. Apply to View:

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hi, I'm Sam"
        android:textColor="@color/black"
        android:textSize="40sp"
        android:background="@drawable/chat_background"    //here
        android:paddingHorizontal="16dp"/>                //apply padding bottom in Drawable, not in here
    
    <TextView                                             //just for comparison
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Hi, I'm Sam"
        android:textColor="@color/black"
        android:textSize="40sp"
        android:background="@color/purple_200"
        android:paddingHorizontal="16dp"/>
    

    Result:

    enter image description here


    Little Math:


    Tips For applying vertical padding: