次のように独自の属性を実装する必要がありますcom.android.R.attr
公式ドキュメントには何も見つからなかったので、これらの属性を定義する方法とコードからそれらを使用する方法についての情報が必要です。
次のように独自の属性を実装する必要がありますcom.android.R.attr
公式ドキュメントには何も見つからなかったので、これらの属性を定義する方法とコードからそれらを使用する方法についての情報が必要です。
現在、最良のドキュメントはソースです。ここ(attrs.xml)でそれを見ることができます。
<resources>
最上位の要素または要素の内部で属性を定義できます<declare-styleable>
。複数の場所でattrを使用する場合は、ルート要素に配置します。すべての属性が同じグローバル名前空間を共有することに注意してください。つまり、<declare-styleable>
要素の内部で新しい属性を作成した場合でも、その属性は要素の外部で使用でき、同じ名前で異なるタイプの別の属性を作成することはできません。
要素には2つの<attr>
xml属性name
とがありformat
ます。name
あなたはそれを何かと呼ぶことができます、そしてこれはあなたがコードでそれを参照することになる方法です、例えばR.attr.my_attribute
。属性は、必要な属性のformat
「タイプ」に応じて異なる値を持つことができます。
|
たとえば、を使用して、フォーマットを複数のタイプに設定できます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 を取得するために使用します。
次に、複数のリソース (数量文字列) の処理方法については説明していません。これらは 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);
}
notifyChanged()
、設定のonDialogClosed
メソッドを呼び出す必要があります。従来のアプローチは定型コードとぎこちないリソース処理でいっぱいです。それが、 Spyglass フレームワークを作成した理由です。どのように機能するかを示すために、文字列タイトルを表示するカスタム ビューを作成する方法を示す例を次に示します。
ステップ 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);
}
}
values/attrs.xml
ステップ 2:リソース ファイルで文字列属性を定義します。
<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 コンパニオンは属性を解釈し、必要なメソッド呼び出しを行います。たとえば、次のレイアウトをインフレートすると、 が引数としてsetTitle
呼び出され"Hello, World!"
ます。
<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 リポジトリをご覧ください。