com.Android.R.attr
のように自分の属性を実装する必要があります。
公式ドキュメントには何も見つからなかったので、これらの属性を定義する方法と私のコードからそれらをどのように使用するかについての情報が必要です。
現在最良のドキュメントがソースです。あなたはそれを見ることができる ここで(attrs.xml) 。
属性は先頭の<resources>
要素内または<declare-styleable>
要素内に定義できます。 attrを複数の場所で使うつもりなら、それをルート要素に入れます。すべての属性は同じグローバル名前空間を共有します。つまり、<declare-styleable>
要素の内側に新しい属性を作成したとしても、その属性をその外側で使用することはできますが、同じ名前で異なるタイプの別の属性を作成することはできません。
<attr>
要素には、2つのxml属性name
とformat
があります。 name
はあなたがそれを何かと呼ぶことを可能にします、そしてこれはあなたがコードでそれを参照することになってしまう方法です、例えばR.attr.my_attribute
。 format
属性は、必要な属性の 'type'に応じて異なる値をとることができます。
|
を使用して、フォーマットを複数のタイプに設定できます(例:format="reference|color"
)。
enum
属性は次のように定義できます。
<attr name="my_enum_attr">
<enum name="value1" value="1" />
<enum name="value2" value="2" />
</attr>
flag
属性は似たようなものですが、値を定義する必要がある点が異なります。
<attr name="my_flag_attr">
<flag name="fuzzy" value="0x01" />
<flag name="cold" value="0x02" />
</attr>
属性に加えて、<declare-styleable>
要素があります。これにより、カスタムビューで使用できる属性を定義できます。 <attr>
要素を指定してこれを行います。以前に定義されている場合はformat
を指定しません。 Android attr、たとえばAndroid:gravityを再利用したい場合は、以下のようにname
でそれを実行できます。
カスタムビュー<declare-styleable>
の例:
<declare-styleable name="MyCustomView">
<attr name="my_custom_attribute" />
<attr name="Android:gravity" />
</declare-styleable>
カスタムビューでカスタム属性をXMLで定義するときには、いくつかの作業が必要です。まずあなたの属性を見つけるために名前空間を宣言しなければなりません。これはルートレイアウト要素で行います。通常はxmlns:Android="http://schemas.Android.com/apk/res/Android"
しかありません。 xmlns:whatever="http://schemas.Android.com/apk/res-auto"
も追加する必要があります。
例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:whatever="http://schemas.Android.com/apk/res-auto"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<org.example.mypackage.MyCustomView
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
whatever:my_custom_attribute="Hello, world!" />
</LinearLayout>
最後に、そのカスタム属性にアクセスするには、通常、カスタムビューのコンストラクタで次のようにしてアクセスします。
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);
String str = a.getString(R.styleable.MyCustomView_my_custom_attribute);
//do something with str
a.recycle();
}
終わり。 :)
Qberticusの答えは良いですが、有用な詳細が1つ欠けています。これらをライブラリに実装している場合は、以下を置き換えます。
xmlns:whatever="http://schemas.Android.com/apk/res/org.example.mypackage"
と:
xmlns:whatever="http://schemas.Android.com/apk/res-auto"
それ以外の場合は、ライブラリを使用するアプリケーションにランタイムエラーが発生します。
上記の答えは、いくつかのことを除いて、すべてを詳細に網羅しています。
まず、スタイルがない場合は、(Context context, AttributeSet attrs)
メソッドシグネチャを使用して設定をインスタンス化します。この場合はcontext.obtainStyledAttributes(attrs, R.styleable.MyCustomView)
を使ってTypedArrayを取得してください。
第二に、それはplauralsリソース(数量文字列)を扱う方法をカバーしていません。これらはTypedArrayを使って処理することはできません。これは私のSeekBarPreferenceからのコードスニペットで、設定の値に従って設定された設定値の概要を設定します。設定のxmlがAndroid:summaryをテキスト文字列または文字列リソースに設定している場合、設定の値は文字列にフォーマットされます(値を取得するには%dが必要です)。 Android:summaryがplauralsリソースに設定されている場合は、それが結果のフォーマットに使用されます。
// Use your own name space if not using an Android resource.
final static private String Android_NS =
"http://schemas.Android.com/apk/res/Android";
private int pluralResource;
private Resources resources;
private String summary;
public SeekBarPreference(Context context, AttributeSet attrs) {
// ...
TypedArray attributes = context.obtainStyledAttributes(
attrs, R.styleable.SeekBarPreference);
pluralResource = attrs.getAttributeResourceValue(Android_NS, "summary", 0);
if (pluralResource != 0) {
if (! resources.getResourceTypeName(pluralResource).equals("plurals")) {
pluralResource = 0;
}
}
if (pluralResource == 0) {
summary = attributes.getString(
R.styleable.SeekBarPreference_Android_summary);
}
attributes.recycle();
}
@Override
public CharSequence getSummary() {
int value = getPersistedInt(defaultValue);
if (pluralResource != 0) {
return resources.getQuantityString(pluralResource, value, value);
}
return (summary == null) ? null : String.format(summary, value);
}
onDialogClosed
メソッドでnotifyChanged()
を呼び出す必要があります。従来のアプローチは、定型コードと不器用なリソース処理でいっぱいです。だから私は Spyglassフレームワーク を作ったのです。これがどのように機能するかを説明するために、Stringのタイトルを表示するカスタムビューを作成する方法を示す例を示します。
手順1:カスタムビュークラスを作成します。
public class CustomView extends FrameLayout {
private TextView titleView;
public CustomView(Context context) {
super(context);
init(null, 0, 0);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr, 0);
}
@RequiresApi(21)
public CustomView(
Context context,
AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs, defStyleAttr, defStyleRes);
}
public void setTitle(String title) {
titleView.setText(title);
}
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflate(getContext(), R.layout.custom_view, this);
titleView = findViewById(R.id.title_view);
}
}
ステップ2:values/attrs.xml
リソースファイルに文字列属性を定義します。
<resources>
<declare-styleable name="CustomView">
<attr name="title" format="string"/>
</declare-styleable>
</resources>
ステップ3:@StringHandler
アノテーションをsetTitle
メソッドに適用して、ビューが膨らんだときに属性値をこのメソッドにルーティングするようにSpyglassフレームワークに指示します。
@HandlesString(attributeId = R.styleable.CustomView_title)
public void setTitle(String title) {
titleView.setText(title);
}
クラスにSpyglassアノテーションが追加されたので、Spyglassフレームワークはコンパイル時にそれを検出し、自動的にCustomView_SpyglassCompanion
クラスを生成します。
手順4:カスタムビューのinit
メソッドで生成されたクラスを使用する
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflate(getContext(), R.layout.custom_view, this);
titleView = findViewById(R.id.title_view);
CustomView_SpyglassCompanion
.builder()
.withTarget(this)
.withContext(getContext())
.withAttributeSet(attrs)
.withDefaultStyleAttribute(defStyleAttr)
.withDefaultStyleResource(defStyleRes)
.build()
.callTargetMethodsNow();
}
それでおしまい。 XMLからクラスをインスタンス化すると、Spyglassコンパニオンは属性を解釈して必要なメソッド呼び出しを行います。たとえば、次のレイアウトを展開すると、引数として"Hello, World!"
を付けてsetTitle
が呼び出されます。
<FrameLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:width="match_parent"
Android:height="match_parent">
<com.example.CustomView
Android:width="match_parent"
Android:height="match_parent"
app:title="Hello, World!"/>
</FrameLayout>
フレームワークは文字列リソースに限定されず、他のリソースタイプを処理するためのさまざまなアノテーションがあります。メソッドに複数のパラメータがある場合は、デフォルト値を定義し、プレースホルダ値を渡すための注釈もあります。
より多くの情報と例についてはGithubレポジトリを見てください。