カスタムview入門
4916 ワード
コントロールをカスタマイズするには、次のステップに分けられます.
1、カスタム属性の宣言と取得
(1)解析に必要なカスタム属性
(2)レスポンス/values/atrs.xmlで声明を定義します.
名前を定義してから3つの属性を定義し、ユーザー定義コントロールの参照に追加します.
(4)viewの構造方法で取得する
カスタムコントロールでTypedArayを利用して設定した属性を取得します.
2、onMewureを測定する(どれぐらいのスペースを占めるか)
通常Viewは画面上に表示されますが、まずmeasreを経由してからlayoutに行きます.onMeassure(int widthSpec,int height Spec)を呼び出すときは、MeasreSpecの使用に関わります.
Meass reSpecは、3つのモードがあります.それぞれ「UNSPECIFIED」、「EXACT LY」、「ATuMOST」です.
私達がwidthまたはheightを設定すると、fill_になります.parentの場合、コンテナがレイアウト時にサブビューのmeasreメソッドを呼び出して入るモードはEXACT LYで、サブビューが残りの容器の空間を占めるため、サイズは決まっています.
設定がwrap_である場合contentの時、容器が入っているのはAT_です.MOSTは、サブビューの大きさが最大でどれぐらいかを表します.このようにviewはこの上限によって自分のサイズを設定します.サブビューのサイズが正確な値に設定されている場合、コンテナがEXACT LYに入りますが、Meass reSpecのUNSPECIFFIEDモードは、通常、スライドコントロールにおけるサブコントロールViewに対するオンメザス方式のデフォルト動作は、モードがUNSPIFIEDの場合、mMinWidth(通常は0)または背景drawableの最小サイズに設定されます.
イメージとしては、オンメスアメソッドは、親要素がコントロールを置くところに呼び出します.親コントロールが呼び出して、サブコントロールに質問します.「どこを使いたいですか?」次に二つのパラメータが入ってきます.widthMeass respecとheightMeass respec.コントロールが得る空間を指定して、そしてこの空間について説明するメタデータを指定します.結果を返すより良い方法は、Viewの高さと幅をsetMeasredDimention方法に伝えることです.
次に経典のViewの中でonMeasreが実現することを見ます.
これは32ビットのint値を表し、高い2桁はspecMode(測定モード)を表し、低い30桁はspecsize(ある測定モードでの規格の大きさ)を表します.
これに関する一般的な3つの関数:
static int getMode(int meass reSpec):提供された測定値(フォーマット)から抽出するモード(上記3つのモードの一つ)
static int getSize(int meass reSpec):提供された測定値に基づいてサイズ値を抽出します.
static int make Meass reSpec(int size,int mode):提供されたサイズ値とパターンに基づいて測定値(フォーマット)を作成します.
3、レイアウトonLayout(どこに置くか)
4、onDrawを描く(何を描くか)
通常はcanvas、PathのAPIを上手に把握する必要があります.属性アニメーションのインタラクションもあるかもしれません.
5、ontouchEvent
ユーザーインタラクティブ、イベントのキャプチャー処理が必要です.
6、onIntercept TouchEvent(view group)
view groupでイベントをブロックするには、イベントの配布メカニズムを把握する必要があります.
入门は主にこのいくつかの内容です.一つ一つのことを深く理解する必要があります.カスタマイズされたviewのソースコードを见るとき、よくこのいくつかのブロックを通して分析します.
1、カスタム属性の宣言と取得
(1)解析に必要なカスタム属性
(2)レスポンス/values/atrs.xmlで声明を定義します.
<resources>
<declare-styleable name="HookView">
<attr name="loadingText" format="string" />
<attr name="completeText" format="string" />
<attr name="textSize" format="dimension" />
</declare-styleable>
</resources>
(3)ラyout xmlファイルで使用する名前を定義してから3つの属性を定義し、ユーザー定義コントロールの参照に追加します.
xmlns:app="http://schemas.android.com/apk/res-auto"
アプリ:loadingText=stringを使って設定する属性(4)viewの構造方法で取得する
カスタムコントロールでTypedArayを利用して設定した属性を取得します.
if (attrs != null) {
//
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HookView);
if (ta.hasValue(R.styleable.HookView_loadingText))
loadingText = ta.getString(R.styleable.HookView_loadingText);
if (ta.hasValue(R.styleable.HookView_completeText))
completeText = ta.getString(R.styleable.HookView_completeText);
textSize = ta.getDimension(R.styleable.HookView_textSize, 20);
ta.recycle();
}
ここで使うとrecycle()を覚えています.これはカスタムViewのためにActivityのCreateごとにCreateが作成されます.そのため、システムが頻繁にarrayを作成する必要があります.メモリと性能に対してはかなりの出費です.プールモードを使わないと、毎回GCに回収され、OutOfMemoryが発生する可能性があります.プログラム起動時には、プールにインスタンスを要求し、使用後にrecycle()方法を呼び出してそのインスタンスを解放し、他のモジュールに多重化してもいいです.recycle()を使用してください.2、onMewureを測定する(どれぐらいのスペースを占めるか)
通常Viewは画面上に表示されますが、まずmeasreを経由してからlayoutに行きます.onMeassure(int widthSpec,int height Spec)を呼び出すときは、MeasreSpecの使用に関わります.
Meass reSpecは、3つのモードがあります.それぞれ「UNSPECIFIED」、「EXACT LY」、「ATuMOST」です.
私達がwidthまたはheightを設定すると、fill_になります.parentの場合、コンテナがレイアウト時にサブビューのmeasreメソッドを呼び出して入るモードはEXACT LYで、サブビューが残りの容器の空間を占めるため、サイズは決まっています.
設定がwrap_である場合contentの時、容器が入っているのはAT_です.MOSTは、サブビューの大きさが最大でどれぐらいかを表します.このようにviewはこの上限によって自分のサイズを設定します.サブビューのサイズが正確な値に設定されている場合、コンテナがEXACT LYに入りますが、Meass reSpecのUNSPECIFFIEDモードは、通常、スライドコントロールにおけるサブコントロールViewに対するオンメザス方式のデフォルト動作は、モードがUNSPIFIEDの場合、mMinWidth(通常は0)または背景drawableの最小サイズに設定されます.
イメージとしては、オンメスアメソッドは、親要素がコントロールを置くところに呼び出します.親コントロールが呼び出して、サブコントロールに質問します.「どこを使いたいですか?」次に二つのパラメータが入ってきます.widthMeass respecとheightMeass respec.コントロールが得る空間を指定して、そしてこの空間について説明するメタデータを指定します.結果を返すより良い方法は、Viewの高さと幅をsetMeasredDimention方法に伝えることです.
次に経典のViewの中でonMeasreが実現することを見ます.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = measureHeight(heightMeasureSpec);
int measuredWidth = measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight, measuredWidth);
}
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST){
// Calculate the ideal size of your
// control within this maximum size.
// If your control fills the available
// space return the outer bound.
result = specSize;
}
else if (specMode == MeasureSpec.EXACTLY){
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
}
private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST){
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
result = specSize;
}
else if (specMode == MeasureSpec.EXACTLY){
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
}
Meassure Spec類についてはここでもっと話してください.これは32ビットのint値を表し、高い2桁はspecMode(測定モード)を表し、低い30桁はspecsize(ある測定モードでの規格の大きさ)を表します.
これに関する一般的な3つの関数:
static int getMode(int meass reSpec):提供された測定値(フォーマット)から抽出するモード(上記3つのモードの一つ)
static int getSize(int meass reSpec):提供された測定値に基づいてサイズ値を抽出します.
static int make Meass reSpec(int size,int mode):提供されたサイズ値とパターンに基づいて測定値(フォーマット)を作成します.
3、レイアウトonLayout(どこに置くか)
4、onDrawを描く(何を描くか)
通常はcanvas、PathのAPIを上手に把握する必要があります.属性アニメーションのインタラクションもあるかもしれません.
5、ontouchEvent
ユーザーインタラクティブ、イベントのキャプチャー処理が必要です.
6、onIntercept TouchEvent(view group)
view groupでイベントをブロックするには、イベントの配布メカニズムを把握する必要があります.
入门は主にこのいくつかの内容です.一つ一つのことを深く理解する必要があります.カスタマイズされたviewのソースコードを见るとき、よくこのいくつかのブロックを通して分析します.