tejariapp-new-logotejariapp-new-logotejariapp-new-logotejariapp-new-logo
  • صفحه اصلی
  • پروژه ها
    • پروژه طراحی سایت
    • پروژه های اندروید
    • پروژه های تحت ویندوز
    • UI & UX
    • ربات تلگرام
  • سفارش پروژه
    • انجام پروژه اندروید (Android)
    • طراحی و ساخت اپلیکیشن موبایل
    • انجام پروژه طراحی سایت با php
    • انجام پروژه طراحی سایت با Asp.net
    • انجام پروژه سی شارپ
    • فرم سفارش پروژه
  • مدرسه ی تجاری اپ
    • طراحی سایت
    • اندروید
    • سی شارپ
    • آموزش پایگاه داده
    • برنامه های کاربردی
  • لینک های مفید
    • پرداخت آنلاین
    • درباره تجاری اپ
    • تماس با ما
استخدام برنامه نویس متلب
سفارش پروژه
✕
            هیچ نتیجه ای یافت نشدمشاهده همه نتایج

            آموزش آداپتور های بایندینگ (Binding adapters)

            • صفحه نخست
            • مدرسه ی تجاری اپ آموزش اندروید
            • آموزش آداپتور های بایندینگ (Binding adapters)
            کلاس های تولید شده توسط دیتا بایندینگ
            کلاس های تولید شده توسط دیتا بایندینگ
            13 اردیبهشت 1399
            آموزش بایند کردن view های لایه به مولفه های معماری اندروید
            آموزش بایند کردن view های لایه به مولفه های معماری اندروید
            15 اردیبهشت 1399
            منتشر شده توسط مهندس داودی
            آموزش آداپتور های بایندینگ (Binding adapters)

            آموزش آداپتور های بایندینگ (Binding adapters)

            آداپتور های بایندینگ (Binding adapters) ، آداپتور های بایندینگ برای فراخوانی یک سری عملیات مناسب جهت تنظیم کردن مقدار استفاده می شود.برای مثال تنظیم کردن مقدار می توان به فراخوانی متد setText اشاره کرد و یا حتی برای تنظیم کردن یک شنونده رخداد می توان به متد setOnClickListener اشاره کرد.کتابخانه دیتا بایندینگ به شما این امکان را می دهد تا یک متد مشخص با نام دلخواه پیاده کنید و از آن برای تنظیم کردن مقدار (در زمان فراخوانی آن) استفاده کنید. این متد شما که درواقع به عنوان همان آداپتور های بایندینگ یا Binding adapter شناخته می شود می تواند شامل دستورات دلخواه شما و حتی نوع برگشتی دلخواه شما باشد.

            آداپتور های بایندینگ (Binding adapters)

            تنظیم مقادیر ویژگی

            زمانی که یک مقدار تغییر می کند ،کلاس تولید شده توسط کتابخانه دیتا بایندینگ باید متد setter آن مقدار را جهت اعمال مقدار جدید فراخوانی کند.اما شما می توانید به کتابخانه دیتا بایندینگ این اجازه را بدهید که مستقیما به سمت متد دلخواه شما هدایت شود یا حتی براساس یک منطق خاص ،یک متد انتخاب شده و به سمت آن هدایت شود.

            همچنین بخوانید: آموزش کلاس های تولید شده توسط دیتا بایندینگ در اندروید

            انتخاب متد به صورت اتوماتیک

            برای یک attribute با نام example ،کتابخانه دیتا بایندینگ به دنبال متدی مانند setExample(arg) می گردد نوع پارامتر arg آن با نوع مقداری که می خواهد به آن پاس دهد یکی باشد.فضای نام یا namespace آن مهم نیست و فقط نام آن و همچنین type متد مورد بررسی دیتا بایندینگ خواهد بود.

            برای مثال اگر درلایه خود عبارت android:text=”@{user.name}” را داشته باشید کتابخانه دیتا بایندینگ به دنبال متد setText(arg) در پروژه می گردد که نوع پارامتری که دریافت می کند با نوع خروجی متد user.getName() که می خواهد به آن (متد setText ) مقدار پاس دهد برابر و یکی باشد .بدین معنا که اگر نوع خروجی متد user.getName() به صورت String باشد ،پس کتابخانه دیتا بایندینگ هم به دنبال متدی setText() ی می گردد که پارامتر String دریافت کند !این در حالی است که اگر نوع بازگشتی متد user.getName() برابر int بود ،پس کتابخانه دیتا بایندینگ به دنبال متد setText() ی می گشت که نوع پارامتر دریافتی آن برابر با int باشد.

            پس مشخص شد که متد setter هر attribute باید دقیقا مانند نوع خروجی متد getter ی باشد که می خواهد به متد setter مقدار پاس دهد.

            کتابخانه دیتا بایندینگ حتی با attribute هایی که وجود ندارند هم کار می کنند ،این جمله به چه معناست؟

            بدین معناست که شما می توانید با استفاده از دیتا بایندینگ attribute بسازید !و دستورات خود را با استفاده از attribute پیاده و اعمال کنید.برای مثال کلاس DrawerLayout هیچ attribute خاصی ندارد اما setter های فراوانی دارد !مثلا در نمونه زیر ما متد setScrimColor(int) و متد setDrawerListener(DrawerLinster) به عنوان setter صفت های app:scripColor و app:drawerListener استفاده کردیم.

            <android.support.v4.widget.DrawerLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:scrimColor="@{@color/scrim}"
                app:drawerListener="@{fragment.drawerListener}">
            

            نکته :
            همانطور که متوجه شدید ما از دو پیشوند android: و app: برای فراخوانی attribute ها استفاده می کنیم.
            اما تفاوت این دو درچیست؟ android برای صفت ها یا attribute هایی استفاده می شود که مربوط به SDK اندروید هستند ،app برای صفت ها یا attribute هایی استفاده می شود که مربوط به کتابخانه support و یا غیر Android SDK هستند.

            مشخص کردن یک متد با نام سفارشی سازی شده

            برخی attribute ها هستند که متد setter آنها با نام خود attribute همخوانی ندارند.در این مواقع می توان attribute را به متد setter دیگری با استفاده از annotation یا حاشیه نوشت BindingMethods متصل کرد.درواقع annotation یا حاشیه نوشت BindingMethods می تواند شامل چندین حاشیه نوشت BindingMethod باشد که ( هرکدام برای تغییر نام یک متد استفاده شده ) و با یک کلاس استفاده می شود.توجه داشته باشید که annotation یا حاشیه نوشت BindingMethods می تواند در هر کلاسی از پروژه شما پیاده شود.در مثال زیر attribute یا صفت android:tint به متد setter با نام setImageTintList(ColorStateList) متصل شده و نه به متد setTint() !

            همچنین بخوانید: کار با اشیاء داده observable در دیتا بایندینگ Data Binding

            جاوا

            @BindingMethods({
                   @BindingMethod(type = "android.widget.ImageView",
                                  attribute = "android:tint",
                                  method = "setImageTintList"),
            })
            

            کاتلین

            @BindingMethods(value = [
                BindingMethod(
                    type = android.widget.ImageView::class,
                    attribute = "android:tint",
                    method = "setImageTintList")])
            

            اما معمولا نیاز به استفاده از حاشیه نوشت های BindingMethods یا BindingMethod برای تغییر نام متد های setter در فریم ورک اندروید نخواهید داشت.این attribute ها قبلا با استفاده از نام های قراردادی پیاده شدند تا بطور اتوماتیک متدهای مربوط به آنها پیدا و فراخوانی شوند.

            فراهم کردن دستورات سفارشی شده توسط برنامه نویس

            برخی attribute ها به کدنویسی های سفارشی شده جهت بایند شدن نیاز دارند. برای مثال ما setter خاصی برای android:paddingLeft نداریم و به جای آن متدی بصورت setPadding(left, top, right, bottom) داریم که padding های چپ ،بالا ،راست و پایین را برای view مشخص میکند.

            یک متد آداپتور بایندینگ binding adapter به همراه حاشیه نوشت @BindingAdapter این امکان را به ما می دهد که setter را برای هر attribute پیاده کنیم.توجه داشته باشید که attribute های خود کلاس های فریم ورک اندروید annotation های BindingAdapter از پیش ساخته شده دارند.برای مثال نمونه زیر BindingAdapter مربوط به paddingLeft را نمایش می دهد:

            جاوا

            @BindingAdapter("android:paddingLeft")
            public static void setPaddingLeft(View view, int padding) {
              view.setPadding(padding,
                              view.getPaddingTop(),
                              view.getPaddingRight(),
                              view.getPaddingBottom());
            }
            

            کاتلین

            @BindingAdapter("android:paddingLeft")
            fun setPaddingLeft(view: View, padding: Int) {
                view.setPadding(padding,
                            view.getPaddingTop(),
                            view.getPaddingRight(),
                            view.getPaddingBottom())
            }
            

            این دستور مربوط به کلاس های فریم ورک اندروید است و همانطور که گفته شد این دستورات از پیش نوشته و مشخص شده با annotation یا حاشیه نوشت BindingAdapter است.برای اینکه این دستورات را در پروژه خود ببینید کلید میانبر Ctrl + shift + f را بزنید تا پنجره جستجو در کل پروژه نمایش داده شود و سپس عبارت setPaddingLeft را در حالت scope و AllPlace سرچ کنید. خواهید دید در فایل ViewBindingAdapter این متد و متدهای دیگر attribute ها وجود دارد.

            آموزش آداپتور های بایندینگ (Binding adapters)

            نوع پارامتر های متد binding adapter بسیار مهم است

            پارامتر اول همیشه مشخص کننده نوع view است که می خواهیم attribute مربوط به آ نرا مقداردهی کنیم.نوع پارامتر دوم هم درواقع باید نوعی باشد که توسط پراپرتی های attribute قابل پذیرش باشند.برای مثال در نمونه padding بالا که توضیح دادیم پارامتر دوم از نوع int بود چرا که نوع ورودی attribute اصلی ما یعنی setPadding از نوع int است و ما می خواهیم این مقدار را به آن پاس دهیم پس باید نوع ها یکی باشند.همچنین Binding adapter را می توان برای حالت های شخصی سازی دیگر هم به کار برد.برای مثال می توان یک loader یا لود کننده سفارشی شده برای لود کردن عکس پیاده کنیم.به مثال زیر دقت کنید:

            جاوا

            @BindingAdapter({"imageUrl", "error"})
            public static void loadImage(ImageView view, String url, Drawable error) {
              Picasso.get().load(url).error(error).into(view);
            }
            

            کاتلین

            @BindingAdapter("imageUrl", "error")
            fun loadImage(view: ImageView, url: String, error: Drawable) {
                Picasso.get().load(url).error(error).into(view)
            }
            

            شما می توانید از adapter هایی که پیاده کردید در layout به صورت زیر استفاده کنید:

            <ImageView 
            	app:imageUrl="@{venue.imageUrl}" 
            	app:error="@{@drawable/venueError}" />
            

            توجه کنید که @drawable/venueError به یک فایل درون پروژه شما اشاره میکند.همچنین توجه کنید که adapter تعریف شده درصورتی فراخوانی می شود که هردو پارامتر imageUrl و error مقدار دهی شده باشند.اما اگر بخواهید با تنظیم کردن هرکدام از آنها adapter فراخوانی شود میتوانید از دستور requireAll = false استفاده کنید تا با تنظیم کردن مقدار هرکدام از پارامتر ها adapter فراخوانی شود.

            جاوا

            @BindingAdapter(value={"imageUrl", "placeholder"}, requireAll=false)
            public static void setImageUrl(ImageView imageView, String url, Drawable placeHolder) {
              if (url == null) {
                imageView.setImageDrawable(placeholder);
              } else {
                MyImageLoader.loadInto(imageView, url, placeholder);
              }
            }
            

            کاتین

            @BindingAdapter(value = ["imageUrl", "placeholder"], requireAll = false)
            fun setImageUrl(imageView: ImageView, url: String?, placeHolder: Drawable?) {
                if (url == null) {
                    imageView.setImageDrawable(placeholder);
                } else {
                    MyImageLoader.loadInto(imageView, url, placeholder);
                }
            }
            

            زمان هایی که شنونده یا listener شما چندین متد دارد ،متدها باید به چندین شنونده شکسته شوند.برای مثال View.OnAttachStateChangeListener دو متد onViewAttachWindow(View) و onViewDetechedFromWindow(View) دار. کتابخانه دو interface برای تفکیک ویژگی ها و کنترل کننده ها برای آنها فراهم کرده.

            جاوا

            @TargetApi(VERSION_CODES.HONEYCOMB_MR1)
            public interface OnViewDetachedFromWindow {
              void onViewDetachedFromWindow(View v);
            }
            
            @TargetApi(VERSION_CODES.HONEYCOMB_MR1)
            public interface OnViewAttachedToWindow {
              void onViewAttachedToWindow(View v);
            }
            

            کاتلین

            // Translation from provided interfaces in Java:
            @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
            interface OnViewDetachedFromWindow {
                fun onViewDetachedFromWindow(v: View)
            }
            
            @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
            interface OnViewAttachedToWindow {
                fun onViewAttachedToWindow(v: View)
            }
            

            زیرا تغییر وضعیت هر interface می تواند برروی دیگری تاثیر داشته باشد ،بنابراین شما نیاز به دو آداپتور برای هرکدام به صورت جداگانه و یا یک آداپتور که هردو را مدیریت کند ،دارید.شما می توانید از requireAll = false استفاده کنید تا با تنظیم هرکدام binding adapter فراخوانی شود ( الزاما نیاز به تنظیم کردن هردو پارامتر نباشد و تنها ارسال یک پارامتر هم آداپتور را فراخوانی کند ).

            جاوا

            @BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"}, requireAll=false)
            public static void setListener(View view, OnViewDetachedFromWindow detach, OnViewAttachedToWindow attach) {
                if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) {
                    OnAttachStateChangeListener newListener;
                    if (detach == null && attach == null) {
                        newListener = null;
                    } else {
                        newListener = new OnAttachStateChangeListener() {
                            @Override
                            public void onViewAttachedToWindow(View v) {
                                if (attach != null) {
                                    attach.onViewAttachedToWindow(v);
                                }
                            }
                            @Override
                            public void onViewDetachedFromWindow(View v) {
                                if (detach != null) {
                                    detach.onViewDetachedFromWindow(v);
                                }
                            }
                        };
                    }
            
                    OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view, newListener,
                            R.id.onAttachStateChangeListener);
                    if (oldListener != null) {
                        view.removeOnAttachStateChangeListener(oldListener);
                    }
                    if (newListener != null) {
                        view.addOnAttachStateChangeListener(newListener);
                    }
                }
            }
            

            کاتلین

            @BindingAdapter(
                    "android:onViewDetachedFromWindow",
                    "android:onViewAttachedToWindow",
                    requireAll = false
            )
            fun setListener(view: View, detach: OnViewDetachedFromWindow?, attach: OnViewAttachedToWindow?) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
                    val newListener: View.OnAttachStateChangeListener?
                    newListener = if (detach == null && attach == null) {
                        null
                    } else {
                        object : View.OnAttachStateChangeListener {
                            override fun onViewAttachedToWindow(v: View) {
                                attach.onViewAttachedToWindow(v)
                            }
            
                            override fun onViewDetachedFromWindow(v: View) {
                                detach.onViewDetachedFromWindow(v)
                            }
                        }
                    }
            
                    val oldListener: View.OnAttachStateChangeListener? =
                            ListenerUtil.trackListener(view, newListener, R.id.onAttachStateChangeListener)
                    if (oldListener != null) {
                        view.removeOnAttachStateChangeListener(oldListener)
                    }
                    if (newListener != null) {
                        view.addOnAttachStateChangeListener(newListener)
                    }
                }
            }
            

            تبدیل شی

            تبدیل خودکار شی

            زمانی که یک شی از عبارات binding برمی گردد. کتابخانه یک متد را برای دریافت این شی درقالب پارامتر انتخاب می کند و به عبارتی شی به نوع پارامتر متد انتخابی cast یا تبدیل میشود.این عملکرد در برنامه هایی که از ObservableMap استفاده می کنند بسیار مناسب است.

            <TextView
               android:text='@{userMap["lastName"]}'
               android:layout_width="wrap_content"
               android:layout_height="wrap_content" />
            

            نکته:
            ‌شما همچنین می توانید مستقیم به مقدار (value) درون map به صورت object.key هم دسترسی داشته باشید.برای مثال ما در نمونه فوق بدین صورت یک فیلد map را فراخوانی کردیم @{userMap[“lastName”]} درحالی که می توان بدین صورت هم فیلد‌ lastName را فراخوانی کرد @{userMap.lastName}

            همانطور که گفته شد شی userMap مقداری را برمی گرداند که به صورت اتوماتیک به نوع پارامتر متد setText(CharSequence) که وظیفه متصل کردن تکست به ویژگی android:text را دارد ،تبدیل می شود.

            تبدیل سفارشی شده

            در بعضی مواقع یک تبدیل سفارشی به انواع خاص نیازمند است.برای مثال ویژگی android:background توقع پارامتر از نوع Drawable را دارد اما مقدار color از نوع integer است !در مثال زیر می بینید که چگونه attribute توقع مقدار از نوع Drawable را دارد اما مقدار از نوع integer هم مقدار این attribute را فراهم می کند:

            <View
               android:background="@{isError ? @color/red : @color/white}"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"/>
            

            هر زمان که نیاز بود پارامتر از نوع Drawable باشد ولی از نوع integer دریافت کرد ،مقدار int باید تبدیل به ColorDrawable شود.این تبدیل با متد static به همراه annotation یا حاشیه نوشت BindingConversion انجام می شود.

            جاوا

            @BindingConversion
            public static ColorDrawable convertColorToDrawable(int color) {
                return new ColorDrawable(color);
            }
            

            کاتلین

            @BindingConversion
            fun convertColorToDrawable(color: Int) = ColorDrawable(color)
            

            یک نکته مهم را فراموش نکنید که شما نمی توانید از نوع های مختلف پارامتر استفاده کنید مانند مثال زیر:

            <View
               android:background="@{isError ? @drawable/error : @color/white}"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"/>
            

            متدهای binding adapter می توانند مقدار قدیمی راهم به صورت اختیاری دریافت کنند.توجه کنید که متدی که هم مقادیر old و هم مقادیر new (منظور مقادیر قدیم و جدید است) را می خواهد دریافت کند باید تمامی مقادیر قدیمی را جز پارامتر های اول و سپس مقادیر جدید را مشخص کند.

            جاوا

            @BindingAdapter("android:paddingLeft")
            public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
              if (oldPadding != newPadding) {
                  view.setPadding(newPadding,
                                  view.getPaddingTop(),
                                  view.getPaddingRight(),
                                  view.getPaddingBottom());
               }
            }
            

            کاتلین

            @BindingAdapter("android:paddingLeft")
            fun setPaddingLeft(view: View, oldPadding: Int, newPadding: Int) {
                if (oldPadding != newPadding) {
                    view.setPadding(padding,
                                view.getPaddingTop(),
                                view.getPaddingRight(),
                                view.getPaddingBottom())
                }
            }
            

            حتی handler ها می توانند تنها با interface ها یا کلاس های abstract استفاده شوند مانند نمونه زیر:

            جاوا

            @BindingAdapter("android:onLayoutChange")
            public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,
                   View.OnLayoutChangeListener newValue) {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                if (oldValue != null) {
                  view.removeOnLayoutChangeListener(oldValue);
                }
                if (newValue != null) {
                  view.addOnLayoutChangeListener(newValue);
                }
              }
            }
            

            کاتلین

            @BindingAdapter("android:onLayoutChange")
            fun setOnLayoutChangeListener(
                    view: View,
                    oldValue: View.OnLayoutChangeListener?,
                    newValue: View.OnLayoutChangeListener?
            ) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    if (oldValue != null) {
                        view.removeOnLayoutChangeListener(oldValue)
                    }
                    if (newValue != null) {
                        view.addOnLayoutChangeListener(newValue)
                    }
                }
            }
            

            و از این handler می توانید به صورت زیر در layout خود استفاده کنید

            <View android:onLayoutChange="@{() -> handler.layoutChanged()}"/>
            

            همچنین بخوانید: اپراتورها یا عملگرهای RxJava

            امیدوارم این آموزش برای شما مفید بوده باشد…

            اشتراک گذاری

            پست های مرتبط

            دستورات جریان کنترل (Control flow statements) یا دستورات شرطی و حلقه ها در زبان برنامه نویسی دارت Dart

            دستورات جریان کنترل (Control flow statements) یا دستورات شرطی و حلقه ها در زبان برنامه نویسی دارت Dart

            30 بهمن 1400

            دستورات شرطی و حلقه ها در زبان برنامه نویسی دارت (Dart)


            ادامه مطلب
            آموزش عملگرها یا Operator ها در زبان برنامه نویسی دارت یا Dart

            آموزش عملگرها یا Operator ها در زبان برنامه نویسی دارت یا Dart

            30 بهمن 1400

            آموزش عملگرها یا Operator ها در زبان برنامه نویسی دارت (Dart)


            ادامه مطلب
            توابع در زبان برنامه نویسی دارت (Dart)

            توابع در زبان برنامه نویسی دارت (Dart)

            27 بهمن 1400

            توابع در زبان برنامه نویسی دارت (Dart)


            ادامه مطلب

            دیدگاهتان را بنویسید لغو پاسخ

            نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

            ساخت اپلیکیشن های موبایل

            • ساخت اپلیکیشن فروشگاهی
            • ساخت اپلیکشن ابزاری و خدماتی
            • ساخت اپلیکیشن آموزشی
            • و هزاران موضوع دیگر

             
            کلیک کنید

            آخرین دیدگاه ها

            • 9 اسفند 1401

              مهری اصغری نظر در پیاده سازی اولین پروژه با فلاتر Flutter

            • 26 آبان 1401

              سجاد نظر در پروژه مدیریت سیستم مدرسه با سی شارپ و sql server

            • 7 خرداد 1401

              داودی نظر در آموزش استفاده از ckeditor همراه با آپلود عکس در لاراول 6

            تجاری اپ در شبکه های اجتماعی

            لوگوی تایید پرداخت آنلاین

            2015-2022 © تمامي حقوق مادي و معنوي اين وب سايت نزد تجاری اپ محفوظ بوده و هر گونه کپي برداري از مطالب پيگرد قانوني به همراه دارد! | طراح سایت : ProgRun
            سفارش پروژه
                      هیچ نتیجه ای یافت نشدمشاهده همه نتایج