নেভিগেশন হল বিষয়বস্তু গন্তব্য অ্যাক্সেস করতে একটি অ্যাপ্লিকেশনের UI এর সাথে ব্যবহারকারীর মিথস্ক্রিয়া। Android এর নেভিগেশন নীতিগুলি নির্দেশিকা প্রদান করে যা আপনাকে সামঞ্জস্যপূর্ণ, স্বজ্ঞাত অ্যাপ নেভিগেশন তৈরি করতে সাহায্য করে।
প্রতিক্রিয়াশীল/অভিযোজিত UIগুলি প্রতিক্রিয়াশীল সামগ্রী গন্তব্যগুলি সরবরাহ করে এবং প্রায়শই প্রদর্শনের আকার পরিবর্তনের প্রতিক্রিয়া হিসাবে বিভিন্ন ধরণের নেভিগেশন উপাদান অন্তর্ভুক্ত করে—উদাহরণস্বরূপ, ছোট ডিসপ্লেতে একটি নীচের নেভিগেশন বার , মাঝারি আকারের ডিসপ্লেতে একটি নেভিগেশন রেল , বা বড়গুলিতে একটি স্থায়ী নেভিগেশন ড্রয়ার ডিসপ্লে-কিন্তু প্রতিক্রিয়াশীল/অভিযোজিত UI গুলি এখনও নেভিগেশনের নীতিগুলি মেনে চলা উচিত।
জেটপ্যাক নেভিগেশন উপাদান নেভিগেশন নীতিগুলি প্রয়োগ করে এবং প্রতিক্রিয়াশীল/অভিযোজিত UI সহ অ্যাপগুলির বিকাশকে সহজ করে।
প্রতিক্রিয়াশীল UI নেভিগেশন
একটি অ্যাপ দ্বারা দখলকৃত ডিসপ্লে উইন্ডোর আকার ergonomics এবং ব্যবহারযোগ্যতা প্রভাবিত করে। উইন্ডো আকারের ক্লাস আপনাকে উপযুক্ত নেভিগেশন উপাদানগুলি (যেমন নেভিগেশন বার, রেল বা ড্রয়ার) নির্ধারণ করতে এবং ব্যবহারকারীর জন্য সবচেয়ে অ্যাক্সেসযোগ্য যেখানে সেগুলি স্থাপন করতে সক্ষম করে। মেটেরিয়াল ডিজাইন লেআউট নির্দেশিকাগুলিতে , নেভিগেশন উপাদানগুলি ডিসপ্লের অগ্রবর্তী প্রান্তে একটি স্থায়ী স্থান দখল করে এবং অ্যাপের প্রস্থ কমপ্যাক্ট হলে নীচের প্রান্তে যেতে পারে৷ আপনার নেভিগেশন উপাদানগুলির পছন্দটি মূলত অ্যাপ উইন্ডোর আকার এবং উপাদানটির থাকা আবশ্যক আইটেমের সংখ্যার উপর নির্ভর করে৷
উইন্ডো সাইজ ক্লাস | কয়েকটি আইটেম | অনেক আইটেম |
---|---|---|
কম্প্যাক্ট প্রস্থ | নীচের নেভিগেশন বার | নেভিগেশন ড্রয়ার (প্রধান প্রান্ত বা নীচে) |
মাঝারি প্রস্থ | নেভিগেশন রেল | নেভিগেশন ড্রয়ার (প্রধান প্রান্ত) |
প্রসারিত প্রস্থ | নেভিগেশন রেল | ক্রমাগত নেভিগেশন ড্রয়ার (প্রধান প্রান্ত) |
লেআউট রিসোর্স ফাইলগুলি বিভিন্ন ডিসপ্লে ডাইমেনশনের জন্য বিভিন্ন নেভিগেশন এলিমেন্ট ব্যবহার করার জন্য উইন্ডো সাইজ ক্লাস ব্রেকপয়েন্ট দ্বারা যোগ্য হতে পারে।
<!-- res/layout/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
... />
<!-- Content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- res/layout-w600dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.navigationrail.NavigationRailView
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
... />
<!-- Content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- res/layout-w1240dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
... />
<!-- Content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>
প্রতিক্রিয়াশীল কন্টেন্ট গন্তব্য
একটি প্রতিক্রিয়াশীল UI-তে, প্রতিটি বিষয়বস্তুর গন্তব্যের বিন্যাস উইন্ডোর আকারের পরিবর্তনের সাথে খাপ খায়। আপনার অ্যাপ লেআউট ব্যবধান সামঞ্জস্য করতে পারে, উপাদানগুলিকে পুনঃস্থাপন করতে পারে, সামগ্রী যোগ করতে বা সরাতে পারে বা নেভিগেশন উপাদান সহ UI উপাদানগুলি পরিবর্তন করতে পারে৷
যখন প্রতিটি পৃথক গন্তব্য রিসাইজ ইভেন্টগুলি পরিচালনা করে, তখন পরিবর্তনগুলি UI-তে বিচ্ছিন্ন হয়৷ নেভিগেশন সহ অ্যাপের বাকি অবস্থা প্রভাবিত হয় না।
উইন্ডোর আকার পরিবর্তনের পার্শ্ব-প্রতিক্রিয়া হিসাবে নেভিগেশন ঘটতে হবে না। শুধুমাত্র বিভিন্ন উইন্ডো আকার মিটমাট করার জন্য সামগ্রী গন্তব্য তৈরি করবেন না। উদাহরণস্বরূপ, একটি ভাঁজযোগ্য ডিভাইসের বিভিন্ন স্ক্রিনের জন্য বিভিন্ন সামগ্রী গন্তব্য তৈরি করবেন না।
উইন্ডোর আকার পরিবর্তনের পার্শ্ব-প্রতিক্রিয়া হিসাবে বিষয়বস্তু গন্তব্যে নেভিগেট করতে নিম্নলিখিত সমস্যা রয়েছে:
- পুরানো গন্তব্য (আগের উইন্ডো আকারের জন্য) নতুন গন্তব্যে নেভিগেট করার আগে মুহূর্তের জন্য দৃশ্যমান হতে পারে
- প্রত্যাবর্তনশীলতা বজায় রাখতে (উদাহরণস্বরূপ, যখন একটি ডিভাইস ভাঁজ করা হয় এবং খোলা হয়), প্রতিটি উইন্ডোর আকারের জন্য নেভিগেশন প্রয়োজন
- গন্তব্যগুলির মধ্যে অ্যাপ্লিকেশনের অবস্থা বজায় রাখা কঠিন হতে পারে, যেহেতু নেভিগেট ব্যাকস্ট্যাক পপ করার সময় রাজ্যকে ধ্বংস করতে পারে
এছাড়াও, উইন্ডোর আকার পরিবর্তনের সময় আপনার অ্যাপটি ফোরগ্রাউন্ডে নাও থাকতে পারে। আপনার অ্যাপের লেআউটের জন্য ফোরগ্রাউন্ড অ্যাপের চেয়ে বেশি জায়গার প্রয়োজন হতে পারে এবং ব্যবহারকারী যখন আপনার অ্যাপে ফিরে আসে, তখন ওরিয়েন্টেশন এবং উইন্ডোর আকার সবই বদলে যেতে পারে।
যদি আপনার অ্যাপের উইন্ডোর আকারের উপর ভিত্তি করে অনন্য সামগ্রী গন্তব্যের প্রয়োজন হয়, তাহলে প্রাসঙ্গিক গন্তব্যগুলিকে একটি একক গন্তব্যে একত্রিত করার কথা বিবেচনা করুন যাতে বিকল্প, অভিযোজিত বিন্যাস অন্তর্ভুক্ত থাকে।
বিকল্প লেআউট সহ বিষয়বস্তুর গন্তব্য
একটি প্রতিক্রিয়াশীল/অভিযোজিত ডিজাইনের অংশ হিসাবে, একটি একক নেভিগেশন গন্তব্যে অ্যাপ উইন্ডোর আকারের উপর নির্ভর করে বিকল্প লেআউট থাকতে পারে। প্রতিটি লেআউট পুরো উইন্ডোটি নেয়, কিন্তু বিভিন্ন লেআউট বিভিন্ন উইন্ডো আকারের (অভিযোজিত নকশা) জন্য উপস্থাপন করা হয়।
একটি আদর্শ উদাহরণ হল তালিকা-বিশদ দৃশ্য । কমপ্যাক্ট উইন্ডোর আকারের জন্য, আপনার অ্যাপ তালিকার জন্য একটি বিষয়বস্তুর লেআউট এবং বিস্তারিত বিবরণের জন্য একটি প্রদর্শন করে। তালিকা-বিশদ দৃশ্যের গন্তব্যে নেভিগেট করা প্রাথমিকভাবে শুধুমাত্র তালিকা বিন্যাস প্রদর্শন করে। যখন একটি তালিকা আইটেম নির্বাচন করা হয়, আপনার অ্যাপ্লিকেশন বিস্তারিত বিন্যাস প্রদর্শন করে, তালিকা প্রতিস্থাপন. যখন ব্যাক কন্ট্রোল নির্বাচন করা হয়, তখন বিস্তারিত প্রতিস্থাপন করে তালিকা লেআউটটি প্রদর্শিত হয়। যাইহোক, প্রসারিত উইন্ডো আকারের জন্য, তালিকা এবং বিস্তারিত লেআউট পাশাপাশি প্রদর্শিত হয়।
SlidingPaneLayout
আপনাকে একটি একক নেভিগেশন গন্তব্য তৈরি করতে সক্ষম করে যা বড় স্ক্রিনে পাশাপাশি দুটি বিষয়বস্তু প্যান প্রদর্শন করে, কিন্তু প্রচলিত ফোনের মতো ছোট স্ক্রীনে একবারে একটি প্যান দেখায়।
<!-- Single destination for list and detail. -->
<navigation ...>
<!-- Fragment that implements SlidingPaneLayout. -->
<fragment
android:id="@+id/article_two_pane"
android:name="com.example.app.ListDetailTwoPaneFragment" />
<!-- Other destinations... -->
</navigation>
SlidingPaneLayout
ব্যবহার করে একটি তালিকা-বিশদ বিন্যাস বাস্তবায়নের বিশদ বিবরণের জন্য একটি দুটি ফলক বিন্যাস তৈরি করুন দেখুন।
একটি নেভিগেশন গ্রাফ
যেকোনো ডিভাইস বা উইন্ডো আকারে একটি সামঞ্জস্যপূর্ণ ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে, একটি একক নেভিগেশন গ্রাফ ব্যবহার করুন যেখানে প্রতিটি বিষয়বস্তুর গন্তব্যের লেআউট প্রতিক্রিয়াশীল।
আপনি যদি প্রতিটি উইন্ডো সাইজ ক্লাসের জন্য একটি ভিন্ন নেভিগেশন গ্রাফ ব্যবহার করেন, যখনই অ্যাপটি একটি সাইজ ক্লাস থেকে অন্য সাইজের ক্লাসে রূপান্তরিত হয়, তখন আপনাকে অন্যান্য গ্রাফগুলিতে ব্যবহারকারীর বর্তমান গন্তব্য নির্ধারণ করতে হবে, একটি ব্যাক স্ট্যাক তৈরি করতে হবে এবং রাজ্যের তথ্যের মধ্যে পার্থক্য করতে হবে। গ্রাফ
নেস্টেড নেভিগেশন হোস্ট
আপনার অ্যাপ এমন একটি বিষয়বস্তু গন্তব্য অন্তর্ভুক্ত করতে পারে যার নিজস্ব বিষয়বস্তুর গন্তব্য রয়েছে। উদাহরণস্বরূপ, একটি তালিকা-বিশদ বিন্যাসে, আইটেম বিশদ প্যানে UI উপাদানগুলি অন্তর্ভুক্ত থাকতে পারে যা সামগ্রীতে নেভিগেট করে যা আইটেমের বিবরণকে প্রতিস্থাপন করে।
এই ধরনের সাবনেভিগেশন বাস্তবায়নের জন্য, বিশদ ফলকটিকে তার নিজস্ব নেভিগেশন গ্রাফ সহ একটি নেস্টেড নেভিগেশন হোস্ট করুন যা বিশদ ফলক থেকে অ্যাক্সেস করা গন্তব্যগুলি নির্দিষ্ট করে:
<!-- layout/two_pane_fragment.xml -->
<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_pane"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
<!-- Detail pane is a nested navigation host. Its graph is not connected
to the main graph that contains the two_pane_fragment destination. -->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/detail_pane"
android:layout_width="300dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/detail_pane_nav_graph" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
এটি নেস্টেড নেভিগেশন গ্রাফ থেকে আলাদা কারণ নেস্টেড NavHost
এর নেভিগেশন গ্রাফ প্রধান নেভিগেশন গ্রাফের সাথে সংযুক্ত নয়; অর্থাৎ, আপনি একটি গ্রাফের গন্তব্য থেকে অন্য গ্রাফের গন্তব্যে সরাসরি নেভিগেট করতে পারবেন না।
আরও তথ্যের জন্য, নেস্টেড নেভিগেশন গ্রাফ দেখুন।
সংরক্ষিত রাষ্ট্র
প্রতিক্রিয়াশীল বিষয়বস্তু গন্তব্য প্রদান করতে, ডিভাইসটি ঘোরানো বা ভাঁজ করা বা অ্যাপ উইন্ডোর আকার পরিবর্তন করা হলে আপনার অ্যাপটিকে অবশ্যই তার অবস্থা সংরক্ষণ করতে হবে। ডিফল্টরূপে, কনফিগারেশনের পরিবর্তনগুলি যেমন এগুলি অ্যাপের কার্যকলাপ, খণ্ডগুলি এবং শ্রেণিবিন্যাসকে পুনরায় তৈরি করে৷ UI অবস্থা সংরক্ষণ করার প্রস্তাবিত উপায় হল একটি ViewModel
এর সাথে, যা কনফিগারেশন পরিবর্তন জুড়ে টিকে থাকে। ( ইউআই স্টেট সংরক্ষণ করুন দেখুন।)
আকার পরিবর্তনগুলি বিপরীত হওয়া উচিত—উদাহরণস্বরূপ, যখন ব্যবহারকারী ডিভাইসটিকে ঘোরান এবং তারপরে এটিকে ঘোরান৷
প্রতিক্রিয়াশীল/অভিযোজিত বিন্যাস বিভিন্ন উইন্ডো আকারে বিভিন্ন সামগ্রী প্রদর্শন করতে পারে; এবং তাই, প্রতিক্রিয়াশীল লেআউটগুলিকে প্রায়ই বিষয়বস্তুর সাথে সম্পর্কিত অতিরিক্ত স্থিতি সংরক্ষণ করতে হয়, এমনকি বর্তমান উইন্ডো আকারের জন্য রাজ্যটি প্রযোজ্য না হলেও। উদাহরণস্বরূপ, একটি লেআউটে শুধুমাত্র বড় উইন্ডো প্রস্থে একটি অতিরিক্ত স্ক্রোলিং উইজেট দেখানোর জন্য স্থান থাকতে পারে। যদি একটি রিসাইজ ইভেন্টের কারণে উইন্ডোর প্রস্থ খুব ছোট হয়ে যায়, উইজেটটি লুকানো থাকে। যখন অ্যাপটি তার পূর্ববর্তী মাত্রার আকার পরিবর্তন করে, তখন স্ক্রলিং উইজেটটি আবার দৃশ্যমান হয় এবং মূল স্ক্রোল অবস্থানটি পুনরুদ্ধার করা উচিত।
মডেল স্কোপ দেখুন
ন্যাভিগেশন কম্পোনেন্ট ডেভেলপারের গাইডে মাইগ্রেট করুন একটি একক-অ্যাক্টিভিটি আর্কিটেকচার যেখানে গন্তব্যগুলিকে খণ্ড হিসাবে প্রয়োগ করা হয় এবং তাদের ডেটা মডেলগুলি ViewModel
ব্যবহার করে প্রয়োগ করা হয়।
একটি ViewModel
সর্বদা একটি লাইফসাইকেলের জন্য স্কোপ করা হয় এবং যখন সেই লাইফসাইকেলটি স্থায়ীভাবে শেষ হয়, তখন ViewModel
সাফ করা হয় এবং বাতিল করা যেতে পারে। যে জীবনচক্রে ViewModel
স্কোপ করা হয়েছে—এবং সেইজন্য ViewModel
কতটা বিস্তৃতভাবে শেয়ার করা যেতে পারে— ViewModel
পাওয়ার জন্য ব্যবহৃত সম্পত্তি প্রতিনিধির উপর নির্ভর করে।
সবচেয়ে সহজ ক্ষেত্রে, প্রতিটি নেভিগেশন গন্তব্য একটি সম্পূর্ণ বিচ্ছিন্ন UI অবস্থা সহ একটি একক অংশ; এবং তাই, প্রতিটি খণ্ডটি সেই খণ্ডের স্কোপযুক্ত একটি ViewModel
পেতে viewModels()
সম্পত্তি প্রতিনিধি ব্যবহার করতে পারে।
টুকরোগুলির মধ্যে UI স্থিতি ভাগ করতে, অংশগুলির মধ্যে activityViewModels()
কল করে ক্রিয়াকলাপের জন্য ViewModel
স্কোপ করুন ( Activity
সমতুল্য হল viewModels()
)। এটি ViewModel
দৃষ্টান্ত ভাগ করার জন্য কার্যকলাপ এবং এটির সাথে সংযুক্ত যেকোনো অংশকে অনুমতি দেয়। যাইহোক, একটি একক-অ্যাক্টিভিটি আর্কিটেকচারে, এই ViewModel
স্কোপটি কার্যকরীভাবে যতদিন অ্যাপটি থাকে ততক্ষণ পর্যন্ত, তাই ViewModel
মেমরিতে থাকে এমনকি কোনো টুকরা ব্যবহার না করলেও।
ধরুন আপনার নেভিগেশন গ্রাফে একটি চেকআউট প্রবাহের প্রতিনিধিত্বকারী খণ্ড গন্তব্যগুলির একটি ক্রম রয়েছে এবং পুরো চেকআউট অভিজ্ঞতার জন্য বর্তমান অবস্থাটি একটি ViewModel
রয়েছে যা টুকরোগুলির মধ্যে ভাগ করা হয়েছে৷ ক্রিয়াকলাপের জন্য ViewModel
স্কোপ করা কেবলমাত্র খুব বিস্তৃত নয়, তবে প্রকৃতপক্ষে আরেকটি সমস্যা প্রকাশ করে: ব্যবহারকারী যদি একটি অর্ডারের জন্য চেকআউট প্রবাহের মধ্য দিয়ে যায়, এবং তারপরে দ্বিতীয় অর্ডারের জন্য এটির মধ্য দিয়ে যায়, উভয় অর্ডারই চেকআউটের একই উদাহরণ ব্যবহার করে ViewModel
। দ্বিতীয় অর্ডার চেকআউট করার আগে, আপনাকে প্রথম অর্ডার থেকে ম্যানুয়ালি ডেটা সাফ করতে হবে। কোনো ভুল ব্যবহারকারীর জন্য ব্যয়বহুল হতে পারে.
পরিবর্তে, বর্তমান NavController
এ একটি নেভিগেশন গ্রাফে ViewModel
স্কোপ করুন। চেকআউট প্রবাহের অংশ গন্তব্যগুলিকে এনক্যাপসুলেট করতে একটি নেস্টেড নেভিগেশন গ্রাফ তৈরি করুন৷ তারপর সেই প্রতিটি খণ্ড গন্তব্যে, navGraphViewModels()
প্রপার্টি প্রতিনিধি ব্যবহার করুন এবং ভাগ করা ViewModel
পেতে নেভিগেশন গ্রাফের আইডি পাস করুন। এটি নিশ্চিত করে যে একবার ব্যবহারকারী চেকআউট প্রবাহ থেকে প্রস্থান করে এবং নেস্টেড নেভিগেশন গ্রাফ সুযোগের বাইরে চলে গেলে, ViewModel
এর সংশ্লিষ্ট উদাহরণ বাতিল করা হয় এবং পরবর্তী চেকআউটের জন্য ব্যবহার করা হবে না।
ব্যাপ্তি | সম্পত্তি প্রতিনিধি | সাথে ViewModel শেয়ার করতে পারেন |
---|---|---|
খণ্ড | Fragment.viewModels() | শুধুমাত্র টুকরা |
কার্যকলাপ | Activity.viewModels() বা Fragment.activityViewModels() | কার্যকলাপ এবং এটি সংযুক্ত সমস্ত টুকরা |
নেভিগেশন গ্রাফ | Fragment.navGraphViewModels() | একই নেভিগেশন গ্রাফে সমস্ত খণ্ড |
মনে রাখবেন যে আপনি যদি একটি নেস্টেড নেভিগেশন হোস্ট ব্যবহার করেন ( নেস্টেড নেভিগেশন হোস্ট বিভাগটি দেখুন), সেই হোস্টের গন্তব্যগুলি navGraphViewModels()
ব্যবহার করার সময় হোস্টের বাইরের গন্তব্যগুলির সাথে ViewModel
দৃষ্টান্তগুলি ভাগ করতে পারে না কারণ গ্রাফগুলি সংযুক্ত নয়৷ এই ক্ষেত্রে, আপনি পরিবর্তে কার্যকলাপ সুযোগ ব্যবহার করতে পারেন.