くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Androidでカスタムビューコンポーネントを作ってみる

今まではstyleとかで作っていたけど、
UIコンポーネントっぽい感じで作りたいなと思い、
いろいろ調べてみたときの備忘録(*´ω`*)

公式ドキュメントだとこのあたり

クラスを作る

Viewクラスを拡張するっぽい。
もちろん、Buttonなど、すでにあるクラスでもOK。

class PieChart extends View {
  public PieChart(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
}

Android StudioのLayout Editorで操作できるようにするために、
最低でも、ContextAttributeSetのコンストラクタを用意する必要がある。

カスタム属性を定義する

カスタム属性は、<declare-styleable>で定義する形。

<!-- res/values/attrs.xml -->
<resources>
 <declare-styleable name="PieChart">
   <attr name="showText" format="boolean" />
   <attr name="labelPosition" format="enum">
     <enum name="left" value="0"/>
     <enum name="right" value="1"/>
   </attr>
 </declare-styleable>
</resources>

使うときは、
xmlns:custom="http://schemas.android.com/apk/res-auto"を利用し、
custom:をつけて指定する感じ。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:custom="http://schemas.android.com/apk/res-auto">
 <com.example.customviews.charting.PieChart
     custom:showText="true"
     custom:labelPosition="left" />
</LinearLayout>

クラス内でカスタム属性を利用する

指定したカスタム属性の値は、obtainStyledAttributesを使って取得できる。

public PieChart(Context context, AttributeSet attrs) {
  super(context, attrs);
  // カスタム属性全体の取得
  TypedArray a = context.getTheme().obtainStyledAttributes(
      attrs,
      R.styleable.PieChart,
      0, 0);

  try {
     // 個別のカスタム属性を取得
     mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
     textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
  } finally {
     // 共有リソースなので、使い終わったらリサイクルが必要
     a.recycle();
  }
}

クラス内のプロパティを変更する

カスタム属性は初期化時のみのため、
動的に変更したい場合は、getter/setterが必要。

public boolean isShowText() {
 return mShowText;
}

public void setShowText(boolean showText) {
 mShowText = showText;
 // 内部の値が変化したため、反映するために再描画をする
 invalidate();
 requestLayout();
}

その他

親クラスはFrameLayoutが便利かも

Viewを継承する場合だと、onDrawとかも自分でする必要があるので、
UIコンポーネント的に既存のものを組み合わせて使うなら、
FrameLayoutを継承して、addViewするのがいいのかもしれない。

class PieChart extends FrameLayout {
  public PieChart(Context context, AttributeSet attrs) {
    super(context, attrs);
    
    // viewの設定
    View view = inflate(context, R.layout.pie_charr, null);
    
    // FrameLayoutに追加
    addView(view);
  }
}

以上!!これでUIコンポーネントづくりが楽になる。。(´ω`)

参考にしたサイトさま