2013年10月12日土曜日

Viewにborder的な罫線をつける方法

Android の View に枠線をつけるのはそれほど難しいことではありません。

■枠線を付けたい TextView のレイアウト(layout/text_layout.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="12dp"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:text="どうも、適当なTextViewです"
        android:background="@drawable/simple_frame" />

</LinearLayout>

■枠線のレイアウト(drawable/simple_frame.xml)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#FFFFFF"/>
    <stroke android:width="2dp" android:color="#AAAAAA" />
</shape>




が、bottom だけ、とか top 以外、とか特定の方向に限定しようとすると
急激に面倒なことになります。

てか、直接それを実現できる方法は存在しないっぽいです。

html/css なら border 指定で簡単にできるのに…困ったもんです。


んじゃどうすんのよ、というと、

通常の枠線(4方向)もしくは色付き長方形を作成
 →ちょっとずらした長方形(背景色で塗りつぶし)を重ねる

てな指定のしかたで対応方法が一般的みたいです。

参照1)[Android]View に border-bottom をつける
参照2) Is there an easy way to add a border to the top and bottom of an Android View?

やろうとしてる事に対してのまわりくどさがハンパないですな。

■TextView のレイアウト
 →さっきのやつの background を @drawable/underline に変えるだけ

■枠線のレイアウト(drawable/underline.xml)
 <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- 枠線付き長方形 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF"/>
            <stroke android:width="2dp" android:color="#AAAAAA" />
        </shape>
    </item>

    <!-- 2dp分の padding を設定した枠線なし長方形 -->
    <item android:bottom="2dp">
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF"/>
        </shape>
    </item>
</layer-list>




んで、実はここからが本題。

何がしたかったかというと。

ListView 的なモノを作りたい。
→でも項目は固定だし項目数も少ない。
 →わざわざ ListView と Adapter 用意すんの面倒…
  →そのレベルなら TextView 縦に並べるだけで良くね?
   →そのまま並べると各 TextView の間に区切りがない…
    →border 的なの何かないかな?

…ここまでであれば前述の方法で問題ないワケですが、さらに

     →タップしたときに他の Activity に遷移する必要がある
      →タップしたときにアクションがあるなら色とか変えたいよね

こうなるのが人情ってもんです。


で、コレを実現しようとすると、さらに selector を組み合わせることになります。

■TextView のレイアウト
 →さっきのやつの background を @drawable/selectable_underline に変える
 →タップ動作を検出するため android:clickable="true" を追加

■枠線のレイアウト(drawable/selectable_underline.xml)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- タップされたときの設定 -->
    <item android:state_pressed="true">
        <layer-list>
            <!-- 枠線付き長方形 -->
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#FFC0CB"/>
                    <stroke android:width="2dp" android:color="#AAAAAA" />
                </shape>
            </item>

            <!-- 2dp分の padding を設定した枠線なし長方形 -->
            <item android:bottom="2dp">
                <shape android:shape="rectangle">
                    <solid android:color="#FFC0CB"/>
                </shape>
            </item>
        </layer-list>
    </item>

    <!-- 通常時の設定 -->
    <item android:state_pressed="false">
        <layer-list>
            <!-- 枠線付き長方形 -->
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#FFFFFF"/>
                    <stroke android:width="2dp" android:color="#AAAAAA" />
                </shape>
            </item>

            <!-- 2dp分の padding を設定した枠線なし長方形 -->
            <item android:bottom="2dp">
                <shape android:shape="rectangle">
                    <solid android:color="#FFFFFF"/>
                </shape>
            </item>
        </layer-list>
    </item>

</selector>



ようやくそれっぽく動くようになったけど、コレ大人しく Adapter 実装した方が
早かったんじゃ…とか思ったり。

0 件のコメント:

コメントを投稿