آشنایی با متریال دیزاین موشن در اندروید — از صفر تا صد

۴۳ بازدید
آخرین به‌روزرسانی: ۲۸ شهریور ۱۴۰۲
زمان مطالعه: ۵ دقیقه
آشنایی با متریال دیزاین موشن در اندروید — از صفر تا صد

یکی از خصوصیات مهم «متریال دیزاین» (Material Design)، گذار عناصر و کامپوننت‌ها برای بیان رابطه بین آن‌ها و خروجی‌ها و موجود بودن اکشن است. از نسخه 1.2.0-alpha05 به بعد کامپوننت‌های متریال برای کتابخانه اندروید از Transitions و Motion بهره می‌گیرند. این‌ها مجموعه‌ای از کلاس‌ها با استفاده آسان برای پیاده‌سازی نوع متفاوتی از گذار و انیمیشن قابل سفارشی‌سازی هستند. در این مقاله با کاربردهای متریال دیزاین موشن در اندروید آشنا خواهیم شد.

الگوهای متفاوتی وجود دارند که سیستم موشن متریال دیزاین را برای ایجاد گذار بین نماهای تمام صفحه تشکیل می‌دهند. نکته مهم این است که الگوی گذاری با نوع مناسب را برای هر مورد انتخاب کنیم. این الگوهای گذار به شرح زیر هستند:

  • تبدیل کانتینر (Container Transform) – این الگو در گذارهایی استفاده می‌شود که شامل عنصری دائمی از قبیل یک لیست، سطح کارت یا دکمه باشند.
  • محور مشترک (Shared Axis) – این الگو برای گذارهایی بین عناصر UI که روابط فضایی یا ناوبری دارند مورد استفاده قرار می‌گیرد.
  • محو شدن روی هم (Fade Through) – زمانی که یک رابطه بین عناصر مهم نیست یا وجود ندارد مورد استفاده قرار می‌گیرد.
  • محو شدن (Fade) – این الگو در مواردی استفاده می‌شود که عناصر UI باید وارد صفحه و یا از آن خارج شوند.
implementation('com.google.android.material:material:1.2.0-beta01')

در ادامه هر یک از موارد فوق را به تفصیل شرح می‌دهیم.

تبدیل کانتینر

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

از این گذار می‌توان به عنوان یک تبدیل دکمه FAB به منو یا برگه نیز استفاده کرد. از سوی دیگر این گذار را می‌توان بین اکتیویتی‌ها، فرگمان‌ها یا نماها بسته به این که یک نما در یک اکتیویتی یا فرگمان قرار است به نمایی در اکتیویتی یا فرگمان دیگر تبدیل شود یا نه مورد استفاده قرار داد.

این تبدیل با تعیین مقادیر مختلف برای مشخصه‌هایی که روی گذار تأثیر دارند به صورت کامل قابل سفارشی‌سازی است. این مشخصه‌ها به شرح زیر هستند.

مدت (Duration)

این مشخصه مدت این گذار را برحسب میلی‌ثانیه تعیین می‌کند.

Interpolator (درون‌یاب)

نوع درون‌یابی گذار را تعیین می‌کند. ما می‌توانیم برخی انواع درون‌یاب از قبیل FastOutSlowIn را تعیین کنیم و یا درون‌یاب های سفارشی را با استفاده از FastOutSlowIn برای یک منحنی بزیه مکعبی مورد استفاده قرار دهیم.

FadeMode (حالت محو شدن)

این مشخصه نوع محو شدن را که برای تعویض محتوای نمای آغازین یا نمای پایانی استفاده می‌شود، تعیین می‌کند. چهار حالت محو شدن وجود دارند:

  • FADE_MODE_IN – محتوای ورودی را بدون تغییر دادن میزان مات بودن محتوای خروجی محو می‌کند. این حالت پیش‌فرض است.
  • FADE_MODE_OUT – محتوای خروجی را بدون تغییر دادن میزان مات بودن محتوای ورودی محو می‌کند.
  • FADE_MODE_CROSS – محتوای ورودی و خروجی را به صورت متقاطع محو می‌کند.
  • FADE_MODE_THROUGH - به صورت ترتیبی محتوای خروجی را فیدآوت و محتوای ورودی را فیداین می‌کند.

FitMode

این مشخصه سه گزینه دارد.

  • FIT_MODE_HEIGHT - در طی مقیاس انیمیشن، محتوای ورودی را با ارتفاع محتوای خروجی تطبیق می‌دهد.
  • FIT_MODE_WIDTH – در طی مقیاس انیمیشن، محتوای ورودی را با عرض محتوای خروجی تطبیق می‌دهد.
  • FIT_MODE_AUTO – به صورت خودکار از FIT_MODE_HEIGHT یا FIT_MODE_WIDTH استفاده می‌کند.

containerColor

رنگ پس‌زمینه کانتینر مورف‌شونده را تعیین می‌کند. این رنگ زیر نماهای آغازی و پایانی رسم می‌شود. این مشخصه در مواردی که یک یا هر دوی نماها پس‌زمینه تک‌رنگی ندارند، بسیار مفید است. از این مشخصه می‌توان برای تنظیم رنگ گذار و بهبود تبدیل از یک نما به نمای دیگر نیز بهره برد.

scrimColor

این مشخصه رنگی که باید زیر کانتینر مورف‌شونده و درون مرزهای drawingView رسم شود را تعیین می‌کند. این drawingView نمایی است که گذار روی آن همپوشانی خواهد یافت. drawingView را می‌توان با استفاده از تابع ()setDrawingViewId مشخص کرد.

1    private fun buildContainerTransform() =
2        MaterialContainerTransform().apply {
3            addTarget(binding.coordinator)
4            duration = 500
5            fadeMode = MaterialContainerTransform.FADE_MODE_IN
6            interpolator = FastOutSlowInInterpolator()
7        }

FAB to Menu

متریال دیزاین موشن در اندروید

این گذار یک FAB را به Menu تبدیل می‌کند. در این مورد باید نماهای آغازین و پایانی را تعیین کنیم.

1    private fun buildContainerTransformation() =
2        MaterialContainerTransform().apply {
3            scrimColor = Color.TRANSPARENT
4            duration = 300
5            interpolator = FastOutSlowInInterpolator()
6            fadeMode = MaterialContainerTransform.FADE_MODE_IN
7        }           
8
9
10    private fun setClickListeners() {
11        binding.floatingActionButton.setOnClickListener {
12            val transition = buildContainerTransformation()
13
14            transition.startView = binding.floatingActionButton
15            transition.endView = binding.card
16
17            transition.addTarget(binding.card)
18
19            TransitionManager.beginDelayedTransition(findViewById(android.R.id.content), transition)
20            binding.card.visibility = View.VISIBLE
21            binding.fabScrim.visibility = View.VISIBLE
22
23            binding.floatingActionButton.visibility = View.INVISIBLE
24        }
25    }

FAB to Activity

این گذار یک FAB را به یک اکتیویتی تبدیل می‌کند. این گذار از MaterialArcMotion برای جابجایی کانتینر در راستای یک منحنی بهره می‌گیرد.

متریال دیزاین موشن در اندروید
سمت چپ: با استفاده از MaterialArcMotion - سمت راست: بدون استفاده از MaterialArcMotion
1    private fun buildContainerTransform() =
2        MaterialContainerTransform().apply {
3            addTarget(binding.coordinator)
4            setAllContainerColors(MaterialColors.getColor(binding.root, R.attr.colorSurface))
5            pathMotion = MaterialArcMotion()
6            duration = 500
7            interpolator = FastOutSlowInInterpolator()
8            fadeMode = MaterialContainerTransform.FADE_MODE_IN
9        }

متریال دیزاین موشن در اندروید

MaterialCardView to Activity

این گذار یک آیتم لیست را به یک اکتیویتی تبدیل می‌کند. ما می‌توانیم تفاوت بین FADE_MODE_IN و FADE_MODE_OUT را مشاهده کنیم.

متریال دیزاین موشن در اندروید
سمت چپ: FADE_MODE_OUT – سمت راست: FADE_MODE_IN
1    inner class ViewHolder(val binding: ItemNoteBinding) : RecyclerView.ViewHolder(binding.root) {
2        fun bind(note: Note) {
3            binding.note = note
4            binding.noteCard.transitionName = note.id.toString()
5            binding.noteCard.setOnClickListener {
6                noteClickListener.onNoteClick(note.id, binding.noteCard)
7            }
8        }
9    }
1        val adapter = NotesAdapter(notes)
2        adapter.noteClickListener = object : NotesAdapter.NoteClickListener {
3            override fun onNoteClick(id: Int, noteCard: MaterialCardView) {
4                val intent = Intent(this@NotesActivity, NoteDetailActivity::class.java)
5                val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
6                    this@NotesActivity, noteCard, id.toString()
7                )
8                intent.putExtra("noteId", id)
9                startActivity(intent, options.toBundle())
10            }
11        }
1class NoteDetailActivity : AppCompatActivity() {
2    private lateinit var binding: NoteDetailActivityBinding
3
4    override fun onCreate(savedInstanceState: Bundle?) {
5        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
6        binding = NoteDetailActivityBinding.inflate(layoutInflater)
7        val noteId = intent.getIntExtra("noteId", 0)
8        val note = notes.find { it.id == noteId }
9        binding.note = note
10        binding.coordinator.transitionName = noteId.toString()
11        setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
12        window.sharedElementEnterTransition = buildContainerTransform()
13        window.sharedElementReturnTransition = buildContainerTransform()
14        setContentView(binding.root)
15        super.onCreate(savedInstanceState)
16    }
17
18    private fun buildContainerTransform() =
19        MaterialContainerTransform().apply {
20            addTarget(binding.coordinator)
21            duration = 300
22            interpolator = FastOutSlowInInterpolator()
23            fadeMode = MaterialContainerTransform.FADE_MODE_IN
24        }
25}

تبدیل کانتینر در کامپوننت ناوبری اندروید

1        val adapter = AlbumsAdapter(albums, requireContext())
2        adapter.albumClickListener = object : AlbumsAdapter.AlbumClickListener {
3            override fun onAlbumClick(id: Int, cardView: MaterialCardView) {
4                val extras = FragmentNavigatorExtras(
5                    cardView to id.toString()
6                )
7                val action = AlbumsFragmentDirections.navToAlbumFragment(id)
8                findNavController().navigate(action, extras)
9            }
10        }
1    override fun onCreate(savedInstanceState: Bundle?) {
2        super.onCreate(savedInstanceState)
3        sharedElementEnterTransition = buildContainerTransform()
4        sharedElementReturnTransition = buildContainerTransform()
5    }
6
7    private fun buildContainerTransform() =
8        MaterialContainerTransform().apply {
9            drawingViewId = R.id.nav_host_fragment
10            interpolator = FastOutSlowInInterpolator()
11            containerColor = Color.WHITE
12            fadeMode = MaterialContainerTransform.FADE_MODE_OUT
13            duration = 300
14        }

متریال دیزاین موشن در اندروید

محور مشترک (Shared Axis)

این الگو برای گذار بین عناصر UI که روابط فضایی یا ناوبری خاصی دارند مورد استفاده قرار می‌گیرد. این گذار از تبدیل‌های روی محورهای x، y یا z برای تأکید مجدد روی رابطه بین عناصر بهره می‌گیرد. به این ترتیب عناصر با جابجایی در جهت یکسان، با همدیگر مرتبط تصور می‌شوند.

1                val forward = true
2                val fragment = MyFragment.newInstance()
3                // axis: MaterialSharedAxis.X, Y or Z
4                // forward: true if it move in the forward direction or false if it move in the backward direction
5                fragment.enterTransition = MaterialSharedAxis(MaterialSharedAxis.Y, forward)
6                supportFragmentManager
7                    .beginTransaction()
8                    .replace(R.id.fragment_container, fragment)
9                    .commit()

محور X

متریال دیزاین موشن در اندروید

در تصویر فوق مثالی از استفاده از گذار MaterialSharedAxis روی محور X برای یک ناوبری در اپلیکیشن را می‌بینید.

محور Y

متریال دیزاین موشن در اندروید

در تصویر فوق یک stepper عمودی با استفاده از گذار MaterialSharedAxis روی محور Y می‌بینید.

محور Z

گذارهای محور Z شامل جابجایی یک سطح به سمت بالا یا پایین در سلسله مراتب اپلیکیشن است.

متریال دیزاین موشن در اندروید

Fade Through

این الگو برای گذار بین عناصر UI که رابطه‌ای قوی با همدیگر دارند مورد استفاده قرار می‌گیرد. گذار Fade through بهترین گزینه در یک نمای ناوبری تحتانی محسوب می‌شود، زیرا متد‌ها غالب در وظایف عمده‌ای گروه‌بندی شده‌اند که ممکن است با همدیگر مرتبط نباشند.

1class ArtistsFragment : Fragment() {
2
3    override fun onCreate(savedInstanceState: Bundle?) {
4        super.onCreate(savedInstanceState)
5        enterTransition = MaterialFadeThrough()
6    }
7  
8    ...
9}

متریال دیزاین موشن در اندروید

Fade

این الگو برای آن عناصر UI استفاده می‌شود که درون مرزهای صفحه وارد یا از آن خارج می‌شوند. از جمله این موارد شامل یک دیالوگ است که از سمت مرکز در یک نما فیداین یا فیدآوت می‌شود.

1// import androidx.transition.TransitionManager        
2        
3        binding.floatingActionButton.post {
4            val transition = MaterialFade().apply {
5                duration = 1500
6            }
7            TransitionManager.beginDelayedTransition(binding.root, transition)
8            binding.floatingActionButton.visibility = View.VISIBLE
9        }

متریال دیزاین موشن در اندروید

سخن پایانی

به این ترتیب به پایان این مقاله با موضوع معرفی متریال دیزاین موشن برای اندروید می‌رسیم. در این مطلب تلاش کردیم با انواع انیمیشن و گذارهای کامپوننت محبوب متریال دیزاین در اندروید آشنا شویم. امیدواریم این مطلب مورد توجه شما قرار گرفته باشد.

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
proandroiddev
نظر شما چیست؟

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