カスタムウィジェットのカスタムテーマ

HoloEverywhereの開発中に、 何らかの方法で送られてきた質問のほとんどが、ウィジェットのスタイル設定に関連しているという事実直面しました。

つまり、人々はテーマと属性の仕事の原理そのものを特に理解していない。
このトピックを少し噛んでみましょう。

手始めに:一般的なスタイルとは何ですか? 属性の値のセット。
そして、これらの属性のリストはどこにありますか、それらの値を取得する方法は?
スタイル可能なリソース。

昔ながらの方法でやってみましょう:ビューを作成します:
package habra.tutorial.customwidget; import android.content.Context; import android.util.AttributeSet; import android.view.View; public class HabraWidget extends View { public HabraWidget(Context context) { super(context); } public HabraWidget(Context context, AttributeSet attrs) { super(context, attrs); } public HabraWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } } 


この最後の3番目の引数がコンストラクターにあることを疑問に思ったことはありますか? int defStyle?

考える時間はありますが、とりあえず最初の属性を作成します。その属性の値は、アクティビティまたはアプリケーション全体のトピックに含まれます。
値/ attrs.xmlを作成します(名前は基本的なものではなく、少なくともstrings.xmlでできます)
 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="habraWidgetStyle" format="reference" /> </resources> 

Androidでは、ウィジェットのスタイルの属性の名前は、通常、キャメルケース+接尾辞スタイルのウィジェットの名前によって設定されます。
そして奇妙なことに、フォーマットのセットは値のフォーマットです。 ここに参照を残します、すなわち リソース、この場合はスタイルへのリンク。

次に、ウィジェットのコンストラクターを変更します。 今、彼らは単に親コンストラクタを呼び出します。
そして今、defStyle機能-属性の名前を設定します。デフォルトでは、この属性が参照するスタイルの値が使用されます。
  public HabraWidget(Context context) { this(context, null); } public HabraWidget(Context context, AttributeSet attrs) { this(context, attrs, R.attr.habraWidgetStyle); } 

つまり HabraWidget(Context)コンストラクターは、2番目の引数をnullにしてHabraWidget(Context、AttributeSet)を呼び出します。
そして、彼は属性でHabraWidget(Context、AttributeSet、int)を呼び出します。

次に、決定します。実際、ウィジェットは何をしますか? 彼に彼のコーナーから単純な十字を描かせてください:
  private final Paint paint; public HabraWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); paint = new Paint(); paint.setColor(0xFF00EEFF); paint.setStyle(Style.FILL_AND_STROKE); } @Override protected void onDraw(Canvas canvas) { canvas.drawLine(0, 0, getWidth(), getHeight(), paint); canvas.drawLine(getWidth(), 0, 0, getHeight(), paint); } 

すばらしいですが、線の色はコード(0xFF00EEFF)でハードコーディングされています。同じことを考えています。私は何を話しているのでしょうか? スタイルで取り出してください!
まず、属性でスタイル設定を作成します...まあ、たとえば、lineColor:
attrs.xml
  <declare-styleable name="HabraWidget"> <attr name="lineColor" format="color|reference"/> </declare-styleable> 


そして、デフォルトのスタイルを作成します。
styles.xml
  <style name="HabraWidget"> <item name="lineColor">#f00</item> </style> 


そして今、色を引き出す方法は?
TypedArray:
  public HabraWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HabraWidget, defStyle, R.style.HabraWidget); paint = new Paint(); paint.setColor(a.getColor(R.styleable.HabraWidget_lineColor, 0xFFFF0000)); paint.setStyle(Style.FILL_AND_STROKE); a.recycle(); } 

0xFFFF0000-デフォルトの色。 デフォルトのトピックを示しているため、ゼロを送信することは可能です。
さて、すべてのデータを取り出した後、リサイクルを行うことを忘れないでください。
レイアウトの作成に関するさらなる機能。 すべての属性がandroid:を介して設定されることに慣れています。
しかし、属性はandroidパッケージにないため、名前空間は異なります。
例を挙げます。
 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:habra="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <habra.tutorial.customwidget.HabraWidget android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" habra:lineColor="#00f" /> <habra.tutorial.customwidget.HabraWidget android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" habra:lineColor="#0f0" /> </LinearLayout> 

画像

これで、マークアップから線の色を自由に設定できます。

Source: https://habr.com/ru/post/J157393/


All Articles