LoginSignup
11
11

More than 5 years have passed since last update.

Drawableのarrayをxmlファイルに定義して、ビューの属性として読み込ませる

Last updated at Posted at 2014-06-21
  • Drawableのarrayをxmlファイルに定義する
  • ビューの属性としてarrayを設定して読み込ませる

の2つの方法はそれぞれググればすぐに見つけられますが、

同時にこれをするのは2時間くらい手こずったのでメモ。

内容

ScrollViewを継承する独自のビューScrollDrawableViewを作成し、
drawablesという名前の独自の属性を与え、
このdrawables属性にDrawableのarrayを設定すると、
自動的にarrayの中身をScrollViewの中に展開して、画面スクロールでDrawableの画像ファイルを見られるようにします。

完成するとこうなります。画面スクロールで画像を見ていけるようになってます。
完成図.png

Drawableのarrayのxmlファイル

res/drawableに、今回表示させるa.pngからu.pngまでを置いてあります。
drawablesという名前のarrayに<item>@drawable/a</item>とアイテムを列挙しているだけですが一応書いておきます。

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <array name="pictures">
        <item>@drawable/a</item>
        <item>@drawable/b</item>
        <item>@drawable/c</item>
        <item>@drawable/d</item>
        <item>@drawable/e</item>
        <item>@drawable/f</item>
        <item>@drawable/g</item>
        <item>@drawable/h</item>
        <item>@drawable/i</item>
        <item>@drawable/j</item>
        <item>@drawable/k</item>
        <item>@drawable/l</item>
        <item>@drawable/m</item>
        <item>@drawable/n</item>
        <item>@drawable/o</item>
        <item>@drawable/p</item>
        <item>@drawable/q</item>
        <item>@drawable/r</item>
        <item>@drawable/s</item>
        <item>@drawable/t</item>
        <item>@drawable/u</item>
    </array>

</resources>

独自の属性を定義するxmlファイル

attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="ScrollDrawableView">
        <attr name="drawables" format="reference" />
    </declare-styleable>

</resources>

declare-styleableのnameは何でもいいのですが、わかりやすいように、自分で独自に作成するビュークラスのクラス名や、用途を書くといいと思います。
attrのformatは文字列ならstring、数値ならinteger、といった具合にそれ専用で用意されている値がいくつかありますが、Drawableにはそれがないので、referenceにします。
これで独自の属性を定義できました。

レイアウトのxmlファイル

アプリのパッケージ名はcom.exampleにしてあります。
MainActivityのレイアウトとして使用するactivity_main.xmlです。
com.example.view.ScrollDrawableViewはScrollViewを継承して自分で作成したビューです。

activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.example"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.example.view.ScrollDrawableView
        android:id="@+id/picker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none"
        custom:drawables="@array/pictures" />

</LinearLayout>

独自の属性を使用するために、xmlns:custom="http://schemas.android.com/apk/res/com.example"で名前空間を設定します。
これで自分で定義した属性をcustomという名前空間で使えるので、custom:drawables="@array/drawables"をビューに設定します。
あとは、ScrollDrawableViewクラスで、drawables属性に指定したarrayのDrawableをImageViewにセットして使用するコードを書くだけです。

独自ビューで独自属性を解釈する

コンストラクタの引数のAttributeSet attrsを使い、設定されている属性のうちから独自に作成した属性を探して、その属性の値として指定されているarrayを取得する流れです。
途中に出てくるR.styleable.ScrollDrawableView_drawablesは、
R.javaの中へと自動的に作成される、
attr.xmlで定義したdeclare-styleableのnameのScrollDrawableViewと、
attrのnameのdrawablesを"_"で連結している名前です。
独自属性を作成したときに勝手に決められるのでちょっとわかりにくいですね。

ScrollDrawableView
package com.example.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import com.example.R;

public class ScrollDrawableView extends ScrollView {
    private final int ELEMENT_WIDTH_HEIGHT = getResources().getDimensionPixelSize(R.dimen.side_length);
    private final LayoutParams ELEMENT_LAYOUT_PARAMS = new LayoutParams(ELEMENT_WIDTH_HEIGHT, ELEMENT_WIDTH_HEIGHT);

    public ScrollDrawableView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // ScrollViewは中に1つしかビューを持てないので、LinearLayoutの中にDrawableのarrayを入れていくことにする
        LinearLayout linearLayout = new LinearLayout(context);
        linearLayout.setOrientation(LinearLayout.VERTICAL);

        // ビューのdrawables属性の値として指定されている、drawableのarrayのリソースIDを取得
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScrollDrawableView);
        int resourceId = typedArray.getResourceId(R.styleable.ScrollDrawableView_drawables, -1);
        typedArray.recycle();

        // arrayの中身のDrawableをImageViewにセットして使用
        TypedArray drawableArray = getResources().obtainTypedArray(resourceId);
        int length = drawableArray.length();
        for (int i = 0; i < length; i++) {
            Drawable drawable = drawableArray.getDrawable(i);
            ImageView imageView = new ImageView(context);
            imageView.setLayoutParams(ELEMENT_LAYOUT_PARAMS);
            imageView.setImageDrawable(drawable);
            linearLayout.addView(imageView);
        }
        drawableArray.recycle();

        addView(linearLayout);
    }
}

アクティビティ

setContentViewでレイアウトのxmlファイルをセットしているだけですが、一応書いておきます。

MainActivity.java
package com.example;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11