چکیده کوتاه مطلب
فعال و غیر فعال کردن Viewها توی اندروید یکی از آپشن هایی هستش که توی توسعه اپلیکیشن احتمالا باهاش روبرو بشی.توی این پست میخوام یک روشی رو آموزش بدم که بدون هیچ کتابخونه ای بتونی ویوهای اندروید رو فعال یا غیرفعال کنی.
اینجا آکادمی نوری هستش! سایت جدید. قراره اینجا کلی باهم بترکونیم. سایت nouri.academy جایگرین nouri.in شده.
برای مشاهده لیست علاقه مندی ها وارد شوید!
مشاهده محصولات فروشگاهبعضی مواقع پیش میاد که ما میخوایم بخشی از طراحی خودمون رو غیرفعال کنیم.
فرضا اگه کاربر فلان کار رو انجام نداده باشه، یه بخشی از اپلیکیشن رو نتونه ازش استفاده کنه.
اینجور مواقع اکثرا میان اون بخش هایی که غیرفعال هستن رو خاکستری میکنن که کابر متوجه بشه که این بخش در دسترس نیستش.
برای اینکار برنامه نویس ها میان 2 طرح مجزا رو طراحی میکنن.
یکی برای حالت فعال و یکی هم برای حالت غیرفعال!
خب عملا این روش بدترین روش هستش?
چون اگه بخوای تغییری توی طرح ایجاد بکنی باید برای هر 2 حالت طرحت رو تغییر بدی?
خب راه حل چیه؟ پس باید چیکار کرد؟
راه حل چیزیه که میخوام تویه این پست بگم?
برای اینکه بهتر منظورم رو درک کنی پشنهاد میکنم دمو رو ببینی.
توی این پست میخوام یک Custom View (ویو سفارشی) درست کنم که هر ویوای که داخل اون قرار بدین قابلیت غیرفعال کردن رو میتونه بگیره.
برای ساختن این Custom view از Constraint layout استفاده کردم.
همونطور که میدونی ConstraintLayout یکی از لایه های اندروید هستش که میشه باهاش طراحی رابط کاربری انجام داد.
برای ساختن این ویو سفارشی همونطور که گفتم از Constraint Layout استفاده کردم.
من اسم این ویو رو ConstraintLayoutWithDisableSupport گذاشتم.
یعنی ConstraintLayoutای که حالت غیرفعال رو پشتیبانی میکنه?.
اول از همه از Point استفاده کردم که بتونم به واسطه اون، نقاط رنگی مختلف رو روی ویوهای خودم اعمال کنم.
بعد از اون رنگ خاکستری رو به صورت آرایه درست کردم و در این نقاط اعمال کردم.
کدی که نوشتن به شکل زیر هستش
private val paint = Paint() val cm = ColorMatrix() cm.set( floatArrayOf( 0.33f, 0.33f, 0.33f, 0f, 0f, 0.33f, 0.33f, 0.33f, 0f, 0f, 0.33f, 0.33f, 0.33f, 0f, 0f, 0f, 0f, 0f, 1f, 0f ) ) paint.colorFilter = ColorMatrixColorFilter(cm)
البته این بخشی از کد هستش که در ادامه کدنهایی رو هم قرار میدم.
بر اساس درک من از پردازش تصویر، در حالت ایده آل ما باید بتونیم هر رنگ RGB رو با یک ماتریس ضرب کنیم و در نتیجه رنگی به رنگ خاکستری بدست بیاریم.
سپس سعی کردم API مشابهی رو توی Android و ColorMatrix پیدا کنم که همراه با برخی از سفارشی سازی ها مواردی که مدنظرم بود رو میتونستم پیاده سازی کنم.
من تصمیم گرفتم یک ماتریس سفارشی رو با مقادیر مساوی قرمز، سبز و آبی آزمایش کنم.
از اون موارد واسه فیلترهای رنگی برای CustomView استفاده کردم که اجازه میداد رنگ های ویوها رو به خاکستری تغییر بدم.
نتیجه توضیحات بالا کد زیر شد، چیزی که میتونستم باهاش ویوهام رو تغییر رنگ بدم.
private val paint = Paint() val cm = ColorMatrix() cm.set( floatArrayOf( 0.33f, 0.33f, 0.33f, 0f, 0f, 0.33f, 0.33f, 0.33f, 0f, 0f, 0.33f, 0.33f, 0.33f, 0f, 0f, 0f, 0f, 0f, 1f, 0f ) ) paint.colorFilter = ColorMatrixColorFilter(cm)
از نقاط بالا توی Canvas با استفاده از متدهای dispatchDraw() و draw() میتونیم رنگ خاکستری رو اعمال کنیم.
به این صورت من از کد بالا توی ConstraintLayout استفاده کردم.
import android.content.Context import android.graphics.Canvas import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter import android.graphics.Paint import android.util.AttributeSet import androidx.constraintlayout.widget.ConstraintLayout class ConstraintLayoutWithDisableSupport @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr) { var disabled = false set(value) { field = value requestLayout() } private val paint = Paint() init { val cm = ColorMatrix() cm.set( floatArrayOf( 0.33f, 0.33f, 0.33f, 0f, 0f, 0.33f, 0.33f, 0.33f, 0f, 0f, 0.33f, 0.33f, 0.33f, 0f, 0f, 0f, 0f, 0f, 1f, 0f ) ) paint.colorFilter = ColorMatrixColorFilter(cm) } override fun dispatchDraw(canvas: Canvas?) { if (disabled) { canvas?.saveLayer(null, paint) } super.dispatchDraw(canvas) if (disabled) { canvas?.restore() } } override fun draw(canvas: Canvas?) { if (disabled) { canvas?.saveLayer(null, paint) } super.draw(canvas) if (disabled) { canvas?.restore() } } }
استفاده کردن از این ویو فوقالعاده راحته.
فقط کافیه ویوهایی که میخوای فعال و غیرفعال بشن رو داخل این لایه قرار بدی.
این لایه هم از نظر ساختار درست مثل ConstraintLayout هستش و هیچ فرقی نمیکنه.
تمامی آپشن ها و امکانات اون رو داره.
من میخوام طرحی که توی دمو نشون دادم رو درست کنم.
برای اینکار از 2 تا لایه استفاده کردم.
لایه اصلی که در واقع مربوط به صفحه کلی میشه که Switch مربوط به غیرفعال کردن رو داره.
لایه دوم هم مواردی که میخوام فعال و غیرفعال بشن رو داخل اون قرار دادم.
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".disable_constraintlayout.DisableConstraintPage"> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/disableConstraintPage_switchLay" android:layout_width="0dp" android:layout_height="70dp" android:background="@color/aquaBlue" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"> <TextView android:id="@+id/disableConstraintPage_switchTxt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/iran_sans" android:text="فعال / غیرفعال کردن لایه ها" android:layout_marginRight="20dp" android:textColor="@color/bgLight" android:textSize="12sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.appcompat.widget.SwitchCompat android:id="@+id/disableConstraintPage_switch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:checked="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/disableConstraintPage_switchTxt" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <include android:id="@+id/sample_view" layout="@layout/disable_constraintlayout_items" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/disableConstraintPage_switchLay" /> </androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?> <in.nouri.myinstagramtutorials.disable_constraintlayout.ConstraintLayoutWithDisableSupport xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="20dp"> <ImageView android:id="@+id/iv_image" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/my" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="ContentDescription" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:fontFamily="@font/iran_sans" android:text="محمد نوری" android:textColor="@color/teal_700" android:textSize="26sp" app:layout_constraintEnd_toEndOf="@+id/iv_image" app:layout_constraintStart_toStartOf="@+id/iv_image" app:layout_constraintTop_toBottomOf="@+id/iv_image" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/tv_site" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="www.nouri.academy" android:textColor="@color/pink" android:textSize="16sp" app:layout_constraintEnd_toEndOf="@+id/iv_image" app:layout_constraintStart_toStartOf="@+id/iv_image" app:layout_constraintTop_toBottomOf="@id/tv_title" /> <com.google.android.material.card.MaterialCardView android:id="@+id/item1" android:layout_width="0dp" android:layout_height="60dp" android:layout_marginTop="10dp" app:cardBackgroundColor="@color/itemColor2" app:cardCornerRadius="10dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_site" app:strokeColor="@color/itemColorStroke" app:strokeWidth="1dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:fontFamily="@font/iran_sans" android:text="آیتم اول" android:textColor="@color/bgLight" android:textSize="16sp" /> </com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView android:id="@+id/item2" android:layout_width="0dp" android:layout_height="60dp" android:layout_marginTop="10dp" app:cardBackgroundColor="@color/itemColor2" app:cardCornerRadius="10dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/item1" app:strokeColor="@color/itemColorStroke" app:strokeWidth="1dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:fontFamily="@font/iran_sans" android:text="آیتم دوم" android:textColor="@color/bgLight" android:textSize="16sp" /> </com.google.android.material.card.MaterialCardView> </in.nouri.myinstagramtutorials.disable_constraintlayout.ConstraintLayoutWithDisableSupport>
نتیجه نهایی مثل عکس زیر میشه
من قصد داشتم کل لایه رو غیرفعال کنم، برای همین تمامی ویوها رو داخل ConstraintLayoutWithDisableSupport نوشتم.
حالا شما با توجه به طرح خودت میتونی اون ویوها رو داخل این لایه قرار بدی.
برای اینکه بتونی ویوها رو به صورت داینامیک فعال و غیرفعال باید به صورت کاتلین (یا جاوا) اون رو هندل کنی.
من برای اینکار کد زیر رو نوشتم
class DisableConstraintPage : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_disable_constraint_page) disableConstraintPage_switch.setOnCheckedChangeListener { _, _ -> if (disableConstraintPage_switch.isChecked) { setSampleViewToEnabled() } else { setSampleViewToDisabled() } } } private fun setSampleViewToDisabled() { (sample_view as ConstraintLayoutWithDisableSupport).disabled = true } private fun setSampleViewToEnabled() { (sample_view as ConstraintLayoutWithDisableSupport).disabled = false } }
این کد 2 تا متد داره.
برای فعال یا غیرفعال کردن لایه فقط کافیه که ID لایه رو بنویسی و بعدش از disabled استفاده کنی.
درست مثل کاری که من توی این 2 تا متد انجام دادم.
بعد از اجرا کردن اپلیکیشن و زدن دکمه غیرفعال کردن، ویوهات مثل عکس زیر خاکستری میشن.
امیدوارم که از این آموزش هم لذت ببری و از نهایت استفاده رو بکنی❤
توسط محمد نوری
۶
دیبا عضویت در خبرنامه نوری آکادمی همیشه بروز باشید. مطمئن باشید که ایمیل شما در اختیار دیگران قرار نمیگیرد
دانلود سریع و آسان
بدون هیچ معطلی دوره را بلافاصله پس از پرداخت دانلود و آموزش را شروع کنید!دوره های فشرده و کاربردی
تمامی دوره های ما بصورت پروژه محور و کاملا کاربردی آموزش داده می شوند...همگام با استاندارد های جهانی
خیالت راحت باشه، آموزشهایی که اینجا قرار میدیم دقیقا منطبق با استانداردهای جهانی هستشدوره های کاملا فارسی
با دیدن دورهها به زبان فارسی، بجای حفظ کردن کدها خیلی راحت میتونی اونارو عمیق یاد بگیریتوی نوری آکادمی کمکت میکنم بتونی وارد حوزه برنامه نویسی موبایل بشی. الان دیگه موبایل از اون حالت لوکس بودن خارج شده و جز وسایل ضروری افزاد به حساب میاد. پس چه بهتر که بتونی اپلیکیشن هایی بنویسی که در دسترس عموم مردم قرار بگیره.خوشحال میشم توی این مسیر با من همراه باشی تا بتونم کمکت کنم.
به امید روزهای بهتر
با خبرنامه نوری آکادمی بهتر و راحت تر در دسترسیم...
از مشخصات شما برای مقاصد تبلیغاتی استفاده نخواهیم کرد.تمامی حقوق مطالب ، دوره ها و محصولات برای مدیریت سایت محفوظ است و کپی برداری پیگرد قانونی دارد.