يعرف جميع المطورين تقريبًا أن هناك سمات في Android ، لكن استخدامها يقتصر عادةً على نسخ أجزاء من xml من Stack Overflow أو موارد أخرى. توجد معلومات على الإنترنت حول المواضيع ، لكن هذه عادة ما تكون مجرد وصفة لكيفية تحقيق نتيجة معينة. في هذه المقالة ، حاولت إعطاء نظرة عامة تمهيدية لآلية تصميم الأندرويد.
محتوى
مقدمةسمات RectViewنمط ل RectViewالنمط الافتراضيRectView نمط سمة سمةموضوع مستوى النشاطعرض الموضوعكيفية تطبيق قيم السماتموضوعات المواردالنتائجمقدمة
الأنماط والسمات في android هي آليات تسمح لك بفصل تفاصيل التصميم (على سبيل المثال ، اللون ، حجم الخط ، إلخ) عن بنية واجهة المستخدم. لفهم كيفية عمل هذا ، سوف يساعدنا مثال بسيط مع طريقة العرض المخصصة.
سنحتاج إلى طريقة عرض مخصصة بسيطة ترسم مستطيلًا باللون المطلوب داخل حدود العرض.
class RectView @JvmOverloads constructor( context: Context, attrSet: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrSet, defStyleAttr) { private val paint = Paint().apply { color = Color.BLUE } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } }

سمات RectView
الآن أود أن أكون قادرًا على تغيير لون مستطيل التخطيط.
للقيام بذلك ، نحتاج إلى إضافة سمة جديدة ، إضافة attrs.xml إلى الملف
<resources> <attr name="rectColor" format="color"/> </resources>
الآن في الكود يمكننا الوصول إلى معرف هذه السمة من خلال R.attr.rectColor و
في تخطيط الشاشة ، يمكننا استخدام التطبيق: سمة rectColor.
<org.berendeev.themes.RectView android:id="@+id/text2" android:layout_width="100dp" app:rectColor="@color/colorPrimary" android:layout_height="100dp"/>
لكن RectView لا يعرف بعد أن هناك سمة حيث يمكنك أن تأخذ لون المستطيل.
دعنا نعلم RectView لفهم سمة rectColor ، أضف مجموعة من السمات
<resources> <attr name="rectColor" format="color"/> <declare-styleable name="RectView"> <attr name="rectColor"/> </declare-styleable> </resources>
في الفئة R ، تم إنشاء حقلين جديدين:
R.styleable.RectView عبارة عن صفيف من سمات المعرف ، وهو حاليًا صفيف من عنصر واحد R.attr.rectColor
R.styleable.RectView_rectColor هو فهرس المعرف للسمة في صفيف R.styleable.RectView ، أي سمة id يمكننا الحصول عليها وهكذا R.styleable.RectView [R.styleable.RectView_rectColor]
وإضافة دعم لسمة rectColor إلى التعليمات البرمجية.
init { val typedArray = context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, 0 ) try { paint.color = typedArray.getColor( R.styleable.RectView_rectColor, Color.BLUE ) } finally { typedArray.recycle() } }
كود كامل class RectView @JvmOverloads constructor( context: Context, attrSet: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrSet, defStyleAttr) { private val paint = Paint().apply { color = Color.BLUE } init { val typedArray = context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, 0 ) try { paint.color = typedArray.getColor( R.styleable.RectView_rectColor, Color.BLUE ) } finally { typedArray.recycle() } } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } }
الآن يمكننا تغيير لون المستطيل من التخطيط:

نمط ل RectView
الآن لدينا سمة واحدة فقط ، ولكن لنفترض أن هناك عشرة منها - سيكون من غير المريح للغاية بالنسبة لنا تعيين كل هذه السمات في التخطيط لعناصر مماثلة في كل مرة.
قرار لجعل كل شيء في الاسلوب.
<style name="DefaultRectViewStyle"> <item name="rectColor">@color/colorAccent</item> </style>
الآن يمكننا إنشاء أي نوع من العرض بنفس المظهر من خلال تحديد النمط.
<org.berendeev.themes.RectView android:id="@+id/text2" android:layout_width="100dp" style="@style/DefaultRectViewStyle" android:layout_height="100dp"/>
النمط الافتراضي
الآن نريد أن تتمتع جميع المشاهدات بنوع من النمط افتراضيًا. للقيام بذلك ، سوف نحدد النمط الافتراضي لأسلوب getStyledAttributes:
context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, R.style.DefaultRectViewStyle )
هذا يكفي. الآن سيكون لكل RectView الذي نضيفه إلى التصميم النمط الافتراضي DefaultRectViewStyle.
RectView نمط سمة سمة
القيمة الافتراضية جيدة ، لكنني أرغب في التحكم في التصميم بشكل أكثر مرونة. من المريح تعيين نمط عرض معين للتطبيق بأكمله أو لنشاط منفصل.
لهذا نحن بحاجة إلى سمة جديدة. سنضع قيمته في السمة ، وستكون القيمة هي النمط الذي يحدد مظهر RectView.
<attr name="rectViewStyle" format="reference"/>
وعلم rectView لدينا لفهم هذه السمة الموضوع. بتمرير المعلمة الثالثة R.attr.rectViewStyle إلى أسلوب getStyledAttributes.
context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, R.attr.rectViewStyle, R.style.DefaultRectViewStyle )
الآن ، إذا تم تحديد عنصر يحمل الاسم rectViewStyle وقيمة نمط الكتابة في الموضوع ، فسيتم تطبيق هذا النمط على جميع RectView مع هذا المظهر.
موضوع مستوى النشاط
قمنا بتعيين قيمة السمة rectViewStyle في موضوعنا.
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="rectViewStyle">@style/LocalRectViewStyle</item> </style> </resources>
حدد الموضوع في بيان التطبيق.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.berendeev.themes"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
سيتم ضبط كل النشاط على نسق AppTheme الافتراضي. وضعنا تصميم RectView للتطبيق بأكمله.
يمكن أيضًا تعيين الموضوع لنشاط معين في البيان.
<activity android:name=".MainActivity" android:theme="@style/MyTheme">
من المهم هنا أن يتم توارث السمة التي سنقوم بتعيينها على مستوى التطبيق أو النشاط من السمة القياسية. على سبيل المثال ، Theme.AppCompat. خلاف ذلك ، نحصل على تعطل في وقت التشغيل.
java.lang.IllegalStateException: أنت بحاجة إلى استخدام سمة Theme.AppCompat (أو سليل) مع هذا النشاط.
عرض الموضوع
على مستوى العرض ، لا نقوم بإعادة تثبيت السمة ، ولكن نكتب فوق قيم السمة المطلوبة ، لذلك لا نحتاج إلى أن نرث من السمة القياسية. يمكن أن يكون أحد الوالدين فارغًا ، أو على سبيل المثال ، يمكننا أن نرث من أحد تراكبات ThemeOverlay.AppCompat.
نحن هنا نضع سمة MyOverlay لمجموعة LinearLayout وجميع أحفادها في التسلسل الهرمي.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:theme="@style/MyOverlay"> <org.berendeev.themes.RectView android:layout_width="100dp" android:layout_height="100dp"/> </LinearLayout>
في هذا الموضوع ، يمكننا الاستغناء عن أحد الوالدين ، لأن نحن فقط تعديل موضوع النشاط.
<style name="MyOverlay"> <item name="rectViewStyle">@style/LocalRectViewStyle</item> </style>
كيفية تطبيق قيم السمات

إذا نظرنا في طريقة العرض إلى قيم السمة في التصميم وفي النمط وفي السمة ، فسيكون ترتيب اختيار القيمة كما يلي. الأولوية القصوى هي القيمة المحددة في التخطيط ، أي إذا تم تعيين القيمة في التخطيط ، فسيتم تجاهل النمط والسمة ، ثم يستمر النمط ، ثم السمة وفي النمط الأخير النمط الافتراضي.
موضوعات الموارد
يمكن استخدام قيم المواضيع في الموارد. على سبيل المثال ، في الدرج ، يمكننا تعيين لون يعتمد على مجموعة الألوان في السمة.
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="?attr/colorPrimary"/> </shape>
الآن يعتمد لون المستطيل على قيمة السمة colorPrimary في السمة. السمة يمكن أن يكون أي. على سبيل المثال ، يمكننا تعيين سمة لدينا في الموارد وتعيين قيمتها في هذا الموضوع.
يمكن استخدام هذه الخدعة في جميع الموارد ، على سبيل المثال ، في محدد أو في الرسم المتجه. هذا يجعل التصميم أكثر تنظيماً ومرونة. يمكننا تغيير مظهر كل النشاطات بسرعة.
النتائج
- السمة والنمط على مستوى المورد هما نفس الشيء ، لكنهما مختلفان.
- يمكن أن يحتوي السمة على سمات أخرى ، فقط معاني أو أنماط للعرض.
- يشار إلى النمط في التخطيط على مستوى العرض. يقوم LayoutInflater بحساب قيم النمط ويمررها كـ AttributeSet إلى مُنشئ العرض.
- المظاهر هي آلية تسمح لك بتحديد المظهر العالمي للنشاط بأكمله.
- يمكن تغيير قيم الموضوع للعنصر (والأحفاد) في التسلسل الهرمي للعرض.
- يمكن استخدام قيم السمات ليس فقط في طريقة العرض ، ولكن أيضًا في الموارد.
ملاحظة: إذا كانت المقالة مثيرة للاهتمام ، فسوف أكتب مقالة أكثر تقدماً أو مقالة تحتوي على الكثير من الأمثلة الحقيقية.