web-dev-qa-db-ja.com

Android描画可能な吹き出し

私は何日も探しましたが、バブルを描画する方法、または9パッチの描画イメージを背景として使用する場所について、良いリードを見つけることができません。私はひどいアーティストです-誰か助けてもらえますか?

私が見つけた最高のサンプルはここstackoverflowにありますが、それはObjective Cで書かれています

iPhoneで「吹き出し」を描画する方法

ありがとうございました

36
user1024776

チャット画面を作成している場合は、着信吹き出しと発信吹き出しを実装することになるでしょう。ここに私がそれをした方法があります:

shape_bg_incoming_bubble.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item>
        <rotate
            Android:fromDegrees="-45"
            Android:pivotX="0%"
            Android:pivotY="0%"
            Android:toDegrees="0" >
            <shape Android:shape="rectangle" >
                <solid Android:color="@color/primary" />
            </shape>
        </rotate>
    </item>
    <item Android:left="16dp">
        <shape Android:shape="rectangle" >
            <solid Android:color="@color/primary" />
            <corners Android:radius="4dp" />
        </shape>
    </item>
</layer-list>

shape_bg_outgoing_bubble.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item>
        <rotate
            Android:fromDegrees="45"
            Android:pivotX="100%"
            Android:pivotY="0%"
            Android:toDegrees="0" >
            <shape Android:shape="rectangle" >
                <solid Android:color="@color/grey_500" />
            </shape>
        </rotate>
    </item>
    <item Android:right="16dp">
        <shape Android:shape="rectangle" >
            <solid Android:color="@color/grey_500" />
            <corners Android:radius="4dp" />
        </shape>
    </item>
</layer-list>
76
toobsco42

これが私が作った簡単な吹き出しのドローアブルです。うまくいけば、それは誰かにとって正しい方向から始まります。このドローアブルが使用されているというビューでは、適切に表示するために、少なくとも70〜80 dpの高さと同様の最小幅が必要です。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >

    <item Android:top="30dp">
        <rotate
            Android:fromDegrees="-45"
            Android:pivotX="0%"
            Android:pivotY="0%"
            Android:toDegrees="0" >
            <shape Android:shape="rectangle" >
                <solid Android:color="#CCC" />
            </shape>
        </rotate>
    </item>
    <item Android:left="20dp">
        <shape Android:shape="rectangle" >
            <solid Android:color="#CCC" />

            <corners Android:radius="5dp" />
        </shape>
    </item>

</layer-list>

Androidドローアブルは、少しでも複雑なものを描画するのにどれほど使いやすいかという点で、多くのことが望まれています。

このバージョンは次のようになります。

Old speech bubble version

[〜#〜] update [〜#〜]私は再びXMLの吹き出しに取り組んでおり、2014のソリューションには少し不満がありました。 2018年には、上記よりも優れたソリューションを可能にするベクター型ドローアブルがあります。ここにいくつかのより現代的な選択肢があります。小さなメッセージや透明性などを許可します。

speech_bubble_simple_user.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" >

    <item
        Android:bottom="@dimen/speech_bubble_tail"
        tools:width="100dp"
        tools:height="50dp">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_user"/>
            <corners
                Android:topLeftRadius="@dimen/speech_bubble_corners"
                Android:topRightRadius="@dimen/speech_bubble_corners"
                Android:bottomRightRadius="0dp"
                Android:bottomLeftRadius="@dimen/speech_bubble_corners"/>
        </shape>
    </item>

    <item
        Android:width="@dimen/speech_bubble_tail"
        Android:height="@dimen/speech_bubble_tail"
        Android:gravity="bottom|right">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_tail"
            Android:height="@dimen/speech_bubble_tail"
            Android:viewportWidth="25.0"
            Android:viewportHeight="25.0">
            <path
                Android:pathData="M25,25 25,0 0,0z"
                Android:fillColor="@color/speech_bubble_user"/>
        </vector>
    </item>

</layer-list>

speech_bubble_simple_agent.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" >

    <item
        Android:bottom="@dimen/speech_bubble_tail"
        tools:width="100dp"
        tools:height="50dp">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_agent"/>
            <corners
                Android:topLeftRadius="@dimen/speech_bubble_corners"
                Android:topRightRadius="@dimen/speech_bubble_corners"
                Android:bottomLeftRadius="0dp"
                Android:bottomRightRadius="@dimen/speech_bubble_corners"/>
        </shape>
    </item>

    <item
        Android:width="@dimen/speech_bubble_tail"
        Android:height="@dimen/speech_bubble_tail"
        Android:gravity="bottom|left">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_tail"
            Android:height="@dimen/speech_bubble_tail"
            Android:viewportWidth="25.0"
            Android:viewportHeight="25.0">
            <path
                Android:pathData="M0,25 25,0 0,0z"
                Android:fillColor="@color/speech_bubble_agent"/>
        </vector>
    </item>

</layer-list>

上記の2つは次のようになります(これらのバージョンは透明度では十分に機能せず、以下のバージョンが正常に機能しているように見える理由がわかりません)。

Two simple speech bubbles

speech_bubble_nine_patch_user.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" >

    <item
        Android:left="@dimen/speech_bubble_corners"
        Android:right="@dimen/speech_bubble_corners_plus_tail"
        Android:bottom="@dimen/speech_bubble_spacing"
        tools:width="50dp"
        tools:height="50dp">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_user"/>
        </shape>
    </item>

    <item
        Android:top="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_corners_plus_tail"
        Android:gravity="left"
        Android:width="@dimen/speech_bubble_corners">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_user"/>
        </shape>
    </item>

    <item
        Android:top="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_corners_plus_tail"
        Android:right="@dimen/speech_bubble_spacing"
        Android:gravity="right"
        Android:width="@dimen/speech_bubble_corners">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_user"/>
        </shape>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners"
        Android:height="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_spacing"
        Android:gravity="bottom|left">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners"
            Android:height="@dimen/speech_bubble_corners"
            Android:viewportWidth="10.0"
            Android:viewportHeight="10.0">
            <path
                Android:pathData="M0,0 A10,10 0 0,0 10,10 L10,0 Z"
                Android:fillColor="@color/speech_bubble_user"/>
        </vector>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners"
        Android:height="@dimen/speech_bubble_corners"
        Android:right="@dimen/speech_bubble_spacing"
        Android:gravity="top|right">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners"
            Android:height="@dimen/speech_bubble_corners"
            Android:viewportWidth="10.0"
            Android:viewportHeight="10.0">
            <path
                Android:pathData="M10,10 A10,10 0 0,0 0,0 L0,10 Z"
                Android:fillColor="@color/speech_bubble_user"/>
        </vector>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners"
        Android:height="@dimen/speech_bubble_corners"
        Android:gravity="top|left">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners"
            Android:height="@dimen/speech_bubble_corners"
            Android:viewportWidth="10.0"
            Android:viewportHeight="10.0">
            <path
                Android:pathData="M10,0 A10,10 0 0,0 0,10 L10,10 Z"
                Android:fillColor="@color/speech_bubble_user"/>
        </vector>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners_plus_tail"
        Android:height="@dimen/speech_bubble_corners_plus_tail"
        Android:gravity="bottom|right">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners_plus_tail"
            Android:height="@dimen/speech_bubble_corners_plus_tail"
            Android:viewportWidth="150.0"
            Android:viewportHeight="150.0">
            <path
                Android:pathData="M0,100 C7.67309143,100 14.1935201,100.346373 20.500756,99.0996492 C43.6628959,129.872031 94.1698247,146.306561 150.320843,150.792562 C113.168693,130.799632 87.2808993,98.5054948 81.0808824,68.6524321 C94.1277117,51.7595331 100,23.9957121 100,0 L0,0 L0,100 Z"
                Android:fillColor="@color/speech_bubble_user"/>
        </vector>
    </item>

</layer-list>

speech_bubble_nine_patch_agent.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" >

    <item
        Android:left="@dimen/speech_bubble_corners_plus_tail"
        Android:right="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_spacing"
        tools:width="50dp"
        tools:height="50dp">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_agent"/>
        </shape>
    </item>

    <item
        Android:top="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_corners_plus_tail"
        Android:left="@dimen/speech_bubble_spacing"
        Android:gravity="left"
        Android:width="@dimen/speech_bubble_corners">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_agent"/>
        </shape>
    </item>

    <item
        Android:top="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_corners_plus_tail"
        Android:gravity="right"
        Android:width="@dimen/speech_bubble_corners">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/speech_bubble_agent"/>
        </shape>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners"
        Android:height="@dimen/speech_bubble_corners"
        Android:bottom="@dimen/speech_bubble_spacing"
        Android:gravity="bottom|right">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners"
            Android:height="@dimen/speech_bubble_corners"
            Android:viewportWidth="10.0"
            Android:viewportHeight="10.0">
            <path
                Android:pathData="M0,10 A10,10 0 0,0 10,0 L0,0 Z"
                Android:fillColor="@color/speech_bubble_agent"/>
        </vector>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners"
        Android:height="@dimen/speech_bubble_corners"
        Android:gravity="top|right">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners"
            Android:height="@dimen/speech_bubble_corners"
            Android:viewportWidth="10.0"
            Android:viewportHeight="10.0">
            <path
                Android:pathData="M10,10 A10,10 0 0,0 0,0 L0,10 Z"
                Android:fillColor="@color/speech_bubble_agent"/>
        </vector>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners"
        Android:height="@dimen/speech_bubble_corners"
        Android:left="@dimen/speech_bubble_spacing"
        Android:gravity="top|left">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners"
            Android:height="@dimen/speech_bubble_corners"
            Android:viewportWidth="10.0"
            Android:viewportHeight="10.0">
            <path
                Android:pathData="M10,0 A10,10 0 0,0 0,10 L10,10 Z"
                Android:fillColor="@color/speech_bubble_agent"/>
        </vector>
    </item>

    <item
        Android:width="@dimen/speech_bubble_corners_plus_tail"
        Android:height="@dimen/speech_bubble_corners_plus_tail"
        Android:gravity="bottom|left">
        <vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:width="@dimen/speech_bubble_corners_plus_tail"
            Android:height="@dimen/speech_bubble_corners_plus_tail"
            Android:viewportWidth="150.0"
            Android:viewportHeight="150.0">
            <path
                Android:pathData="M150,100 L150,0 L50,0 C50,11.9054549 52.5180742,22.2130322 55.2200144,32.2289993 C59.25,47.1679688 65.7054859,60.8615415 68.15625,65.5820312 C55.2200144,107.207031 41.7460938,127.800781 0,151 C61.5311854,147.539062 101.691406,129.675781 124.615295,97.6602593 C132.823321,99.8389881 141.106342,100 150,100 Z"
                Android:fillColor="@color/speech_bubble_agent"/>
        </vector>
    </item>

</layer-list>

上記の2つは次のようになります。

Speech bubbles with curly tails

dimens.xml(両方)

<dimen name="speech_bubble_corners">10dp</dimen>
<dimen name="speech_bubble_corners_plus_tail">15dp</dimen>
<dimen name="speech_bubble_spacing">5dp</dimen>
<dimen name="speech_bubble_tail">25dp</dimen>
40
TTransmit

私はこれが遅すぎることを知っています。 9パッチ画像を使用したくないが、吹き出しから影を落としたい人​​のために。これは、WhatsAppの吹き出しに到達できる最も近い場所です。上記の答えをありがとう@ toobsco42。

どうぞ..

着信吹き出し:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

<!--Shadow Layers-->

<item>
    <rotate
        Android:fromDegrees="-35"
        Android:pivotX="0%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp"/>
            <padding
                Android:bottom="1px"
                Android:left="1px"
                Android:right="1px"/>
            <solid Android:color="#01000000" />
        </shape>
    </rotate>
</item>
<item Android:left="8dp">
    <shape Android:shape="rectangle">
        <padding
            Android:bottom="1px"
            Android:left="1px"
            Android:right="1px"/>
        <solid Android:color="#01000000" />
        <corners Android:radius="8dp" />
    </shape>
</item>

<!--===============-->
<item>
    <rotate
        Android:fromDegrees="-35"
        Android:pivotX="0%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp"/>
            <padding
                Android:bottom="1px" />
            <solid Android:color="#09000000" />
        </shape>
    </rotate>
</item>
<item Android:left="8dp">
    <shape Android:shape="rectangle">
        <padding
            Android:bottom="1px" />
        <solid Android:color="#09000000" />
        <corners Android:radius="8dp" />
    </shape>
</item>

<!--===============-->

<item>
    <rotate
        Android:fromDegrees="-35"
        Android:pivotX="0%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp"/>
            <padding
                Android:bottom="1px"
                Android:left="1px"
                Android:right="1px"/>
            <solid Android:color="#10000000" />
        </shape>
    </rotate>
</item>
<item Android:left="8dp">
    <shape Android:shape="rectangle">
        <padding
            Android:bottom="1px"
            Android:left="1px"
            Android:right="1px"/>
        <solid Android:color="#10000000" />
        <corners Android:radius="8dp" />
    </shape>
</item>

<!--ForeGround-->

<item>
    <rotate
        Android:fromDegrees="-35"
        Android:pivotX="0%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp"/>
            <solid Android:color="@color/colorWhite" />
        </shape>
    </rotate>
</item>
<item Android:left="8dp">
    <shape Android:shape="rectangle">
        <solid Android:color="@color/colorWhite" />
        <corners Android:radius="8dp" />
    </shape>
</item>

</layer-list>

発信の吹き出し:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

<!--Shadow Layer-->

<item>
    <rotate
        Android:fromDegrees="40"
        Android:pivotX="100%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp" />
            <padding
                Android:bottom="1px"
                Android:left="1px"
                Android:right="1px" />
            <solid Android:color="#01000000" />
        </shape>
    </rotate>
</item>
<item Android:right="10dp">
    <shape Android:shape="rectangle">
        <corners Android:radius="4dp" />
        <padding
            Android:bottom="1px"
            Android:left="1px"
            Android:right="1px" />
        <solid Android:color="#01000000" />
    </shape>
</item>

<!--===============-->

<item>
    <rotate
        Android:fromDegrees="40"
        Android:pivotX="100%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp" />
            <padding Android:bottom="1px" />
            <solid Android:color="#09000000" />
        </shape>
    </rotate>
</item>
<item Android:right="10dp">
    <shape Android:shape="rectangle">
        <corners Android:radius="4dp" />
        <padding Android:bottom="1px" />
        <solid Android:color="#09000000" />
    </shape>
</item>

<!--===============-->

<item>
    <rotate
        Android:fromDegrees="40"
        Android:pivotX="100%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <corners Android:radius="4dp" />
            <padding
                Android:bottom="1px"
                Android:left="1px"
                Android:right="1px" />
            <solid Android:color="#10000000" />
        </shape>
    </rotate>
</item>
<item Android:right="10dp">
    <shape Android:shape="rectangle">
        <corners Android:radius="4dp" />
        <padding
            Android:bottom="1px"
            Android:left="1px"
            Android:right="1px" />
        <solid Android:color="#10000000" />
    </shape>
</item>

<!--===============-->


<!--ForeGround-->

<item>
    <rotate
        Android:fromDegrees="40"
        Android:pivotX="100%"
        Android:pivotY="0%"
        Android:toDegrees="0">
        <shape Android:shape="rectangle">
            <solid Android:color="#CBEBFC" />
        </shape>
    </rotate>
</item>
<item Android:right="10dp">
    <shape Android:shape="rectangle">
        <solid Android:color="#CBEBFC" />
        <corners Android:radius="4dp" />
    </shape>
</item>

</layer-list>

レイアウトでパディングを適切に使用します。私はこれらの値を使用しました:

<TextView
    Android:id="@+id/text_message_incoming"
    Android:layout_width="0dp"
    Android:layout_height="wrap_content"
    Android:background="@drawable/bg_speech_bubble_incoming"
    Android:lineSpacingExtra="2dp"
    Android:paddingLeft="20dp"
    Android:paddingTop="4dp"
    Android:paddingRight="10dp"
    Android:paddingBottom="10dp"
    Android:text="Hi, How are you?"
    Android:textColor="@color/colorBlack"
    Android:textSize="13.5dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintWidth_max="wrap"
    app:layout_constraintWidth_percent="0.8" />

私の出力は次のようになりました:

enter image description here

36
VipiN Negi

なんらかの画像エディタで画像を作成し、それから9パッチを作成する必要があります。コンテンツに9パッチ方式を使用する領域を設定できます。その後、背景を9パッチに設定したTextViewを作成できます。市場に出ているBnterというアプリを見てください。吹き出しを使用して、探しているものと同様の会話を表示します。

4
Bobbake4