নেভিগেশন কম্পোনেন্টে মাইগ্রেট করুন

নেভিগেশন কম্পোনেন্ট হল একটি লাইব্রেরি যা জটিল নেভিগেশন, ট্রানজিশন অ্যানিমেশন, ডিপ লিঙ্কিং এবং কম্পাইল-টাইম চেক করা আর্গুমেন্ট আপনার অ্যাপের স্ক্রীনের মধ্যে পাসিং পরিচালনা করতে পারে।

এই নথিটি ন্যাভিগেশন উপাদান ব্যবহার করার জন্য একটি বিদ্যমান অ্যাপ স্থানান্তর করার জন্য একটি সাধারণ-উদ্দেশ্য নির্দেশিকা হিসাবে কাজ করে।

উচ্চ স্তরে, মাইগ্রেশন এই পদক্ষেপগুলিকে অন্তর্ভুক্ত করে:

  1. স্ক্রীন-নির্দিষ্ট UI লজিককে কার্যকলাপের বাইরে সরান - প্রতিটি স্ক্রীনের বাস্তবায়নকে একটি খণ্ড বা কাস্টম-এ অর্পণ করার সময় প্রতিটি কার্যকলাপ গ্লোবাল নেভিগেশন UI উপাদানগুলির লজিকের মালিক, যেমন একটি Toolbar , নিশ্চিত করে আপনার অ্যাপের UI যুক্তিকে ক্রিয়াকলাপ থেকে সরিয়ে দিন গন্তব্য।

  2. নেভিগেশন উপাদান একত্রিত করুন - প্রতিটি কার্যকলাপের জন্য, একটি নেভিগেশন গ্রাফ তৈরি করুন যাতে সেই কার্যকলাপ দ্বারা পরিচালিত এক বা একাধিক খণ্ড রয়েছে। ন্যাভিগেশন কম্পোনেন্ট অপারেশনের সাথে টুকরো লেনদেন প্রতিস্থাপন করুন।

  3. কার্যকলাপের গন্তব্য যোগ করুন - কার্যকলাপের গন্তব্য ব্যবহার করে কর্মের সাথে startActivity() কল প্রতিস্থাপন করুন।

  4. ক্রিয়াকলাপগুলি একত্রিত করুন - যেখানে একাধিক ক্রিয়াকলাপ একটি সাধারণ বিন্যাস ভাগ করে সেই ক্ষেত্রে নেভিগেশন গ্রাফগুলিকে একত্রিত করুন৷

পূর্বশর্ত

এই গাইডটি অনুমান করে যে আপনি ইতিমধ্যেই AndroidX লাইব্রেরি ব্যবহার করার জন্য আপনার অ্যাপ স্থানান্তর করেছেন৷ আপনি যদি তা না করে থাকেন, তাহলে চালিয়ে যাওয়ার আগে AndroidX ব্যবহার করার জন্য আপনার প্রকল্পটি স্থানান্তর করুন

স্ক্রীন-নির্দিষ্ট UI লজিককে কার্যকলাপের বাইরে সরান

ক্রিয়াকলাপগুলি হল সিস্টেম-স্তরের উপাদান যা আপনার অ্যাপ এবং অ্যান্ড্রয়েডের মধ্যে একটি গ্রাফিকাল মিথস্ক্রিয়াকে সহজতর করে। ক্রিয়াকলাপগুলি আপনার অ্যাপের ম্যানিফেস্টে নিবন্ধিত হয় যাতে Android জানে যে কোন ক্রিয়াকলাপগুলি চালু করার জন্য উপলব্ধ৷ অ্যাক্টিভিটি ক্লাস আপনার অ্যাপ্লিকেশানটিকে অ্যান্ড্রয়েড পরিবর্তনগুলিতে প্রতিক্রিয়া জানাতে সক্ষম করে, যেমন আপনার অ্যাপের UI যখন অগ্রভাগে প্রবেশ করে বা ছেড়ে যায়, ঘূর্ণায়মান ইত্যাদি। অ্যাক্টিভিটিটি স্ক্রিনের মধ্যে স্টেট শেয়ার করার জায়গা হিসেবেও কাজ করতে পারে।

আপনার অ্যাপের প্রেক্ষাপটে, ক্রিয়াকলাপগুলি নেভিগেশনের জন্য একটি হোস্ট হিসাবে কাজ করা উচিত এবং স্ক্রিন, ডেটা পাস ইত্যাদির মধ্যে কীভাবে স্থানান্তর করা যায় তার যুক্তি এবং জ্ঞান রাখা উচিত। যাইহোক, আপনার UI এর বিবরণ পরিচালনা করা আপনার UI এর একটি ছোট, পুনঃব্যবহারযোগ্য অংশে ছেড়ে দেওয়া ভাল। এই প্যাটার্নের জন্য প্রস্তাবিত বাস্তবায়ন হল টুকরাএকক ক্রিয়াকলাপ দেখুন: কেন, কখন, এবং কীভাবে টুকরো ব্যবহার করার সুবিধাগুলি সম্পর্কে আরও শিখবেন। নেভিগেশন ন্যাভিগেশন-টুকরো নির্ভরতার মাধ্যমে টুকরা সমর্থন করে। নেভিগেশন কাস্টম গন্তব্য প্রকার সমর্থন করে।

যদি আপনার অ্যাপটি টুকরো ব্যবহার না করে, তাহলে প্রথমে আপনাকে যা করতে হবে তা হল একটি টুকরো ব্যবহার করার জন্য আপনার অ্যাপের প্রতিটি স্ক্রীন স্থানান্তর করা। আপনি এই মুহুর্তে কার্যকলাপ মুছে ফেলছেন না. বরং, আপনি পর্দার প্রতিনিধিত্ব করার জন্য একটি খণ্ড তৈরি করছেন এবং দায়িত্ব দ্বারা আপনার UI যুক্তিকে ভেঙে ফেলছেন।

টুকরা প্রবর্তন

টুকরো প্রবর্তনের প্রক্রিয়াটি ব্যাখ্যা করার জন্য, আসুন দুটি স্ক্রীন নিয়ে গঠিত একটি অ্যাপ্লিকেশনের উদাহরণ দিয়ে শুরু করা যাক: একটি পণ্য তালিকা স্ক্রীন এবং একটি পণ্যের বিবরণ স্ক্রীন। তালিকার স্ক্রিনে একটি পণ্যে ক্লিক করা ব্যবহারকারীকে পণ্য সম্পর্কে আরও জানতে একটি বিশদ স্ক্রিনে নিয়ে যায়।

এই উদাহরণে, তালিকা এবং বিশদ স্ক্রীনগুলি বর্তমানে পৃথক কার্যকলাপ।

UI হোস্ট করার জন্য একটি নতুন লেআউট তৈরি করুন

একটি খণ্ড প্রবর্তন করতে, খণ্ডটি হোস্ট করার জন্য কার্যকলাপের জন্য একটি নতুন লেআউট ফাইল তৈরি করে শুরু করুন। এটি কার্যকলাপের বর্তমান কন্টেন্ট ভিউ লেআউটকে প্রতিস্থাপন করে।

একটি সাধারণ দৃশ্যের জন্য, আপনি একটি FrameLayout ব্যবহার করতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে product_list_host :

<FrameLayout
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/main_content"
   android:layout_height="match_parent"
   android:layout_width="match_parent" />

id অ্যাট্রিবিউট কন্টেন্ট সেকশনকে বোঝায় যেখানে আমরা পরে ফ্র্যাগমেন্ট যোগ করি।

এর পরে, আপনার কার্যকলাপের onCreate() ফাংশনে, এই নতুন লেআউট ফাইলটিকে নির্দেশ করতে আপনার কার্যকলাপের onCreate ফাংশনে লেআউট ফাইলের রেফারেন্স পরিবর্তন করুন:

কোটলিন

class ProductListActivity : AppCompatActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        // Replace setContentView(R.layout.product_list) with the line below
        setContentView(R.layout.product_list_host)
        ...
    }
}

জাভা

public class ProductListActivity extends AppCompatActivity {
    ...
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        ...
        // Replace setContentView(R.layout.product_list); with the line below
        setContentView(R.layout.product_list_host);
        ...
    }
}

বিদ্যমান লেআউট ( product_list , এই উদাহরণে) আপনি যে খণ্ডটি তৈরি করতে চলেছেন তার রুট ভিউ হিসাবে ব্যবহার করা হয়।

একটি খণ্ড তৈরি করুন

আপনার স্ক্রিনের জন্য UI পরিচালনা করতে একটি নতুন খণ্ড তৈরি করুন৷ আপনার অ্যাক্টিভিটি হোস্ট নামের সাথে সামঞ্জস্যপূর্ণ হওয়া একটি ভালো অভ্যাস। নীচের স্নিপেটটি ProductListFragment ব্যবহার করে, উদাহরণস্বরূপ:

কোটলিন

class ProductListFragment : Fragment() {
    // Leave empty for now.
}

জাভা

public class ProductListFragment extends Fragment {
    // Leave empty for now.
}

একটি খণ্ডে কার্যকলাপ যুক্তি সরান

ফ্র্যাগমেন্টের সংজ্ঞা ঠিক রেখে, পরবর্তী ধাপ হল এই স্ক্রিনের জন্য UI লজিককে কার্যকলাপ থেকে এই নতুন খণ্ডে নিয়ে যাওয়া। আপনি যদি একটি কার্যকলাপ-ভিত্তিক আর্কিটেকচার থেকে আসছেন, তাহলে সম্ভবত আপনার কার্যকলাপের onCreate() ফাংশনে প্রচুর ভিউ ক্রিয়েশন লজিক ঘটছে।

এখানে UI লজিক সহ কার্যকলাপ-ভিত্তিক একটি উদাহরণ রয়েছে যা আমাদের সরাতে হবে:

কোটলিন

class ProductListActivity : AppCompatActivity() {

    // Views and/or ViewDataBinding references, Adapters...
    private lateinit var productAdapter: ProductAdapter
    private lateinit var binding: ProductListActivityBinding

    ...

    // ViewModels, System Services, other Dependencies...
    private val viewModel: ProductListViewModel by viewModels()

    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // View initialization logic
        DataBindingUtil.setContentView(this, R.layout.product_list_activity)

        // Post view initialization logic
        // Connect adapters
        productAdapter = ProductAdapter(productClickCallback)
        binding.productsList.setAdapter(productAdapter)

        // Initialize view properties, set click listeners, etc.
        binding.productsSearchBtn.setOnClickListener {...}

        // Subscribe to state
        viewModel.products.observe(this, Observer { myProducts ->
            ...
        })

        // ...and so on
    }
   ...
}

জাভা

public class ProductListActivity extends AppCompatActivity {

    // Views and/or ViewDataBinding references, adapters...
    private ProductAdapter productAdapter;
    private ProductListActivityBinding binding;

    ...

    // ViewModels, system services, other dependencies...
    private ProductListViewModel viewModel;

    ...

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // View initialization logic
        DataBindingUtil.setContentView(this, R.layout.product_list_activity);

        // Post view initialization logic
        // Connect adapters
        productAdapter = new ProductAdapter(productClickCallback);
        binding.productsList.setAdapter(productAdapter);

        // Initialize ViewModels and other dependencies
        ProductListViewModel viewModel = new ViewModelProvider(this).get(ProductListViewModel.java);

        // Initialize view properties, set click listeners, etc.
        binding.productsSearchBtn.setOnClickListener(v -> { ... });

        // Subscribe to state
        viewModel.getProducts().observe(this, myProducts ->
            ...
       );

       // ...and so on
   }

ব্যবহারকারী কখন এবং কীভাবে পরবর্তী স্ক্রিনে নেভিগেট করবেন তাও আপনার কার্যকলাপ নিয়ন্ত্রণ করতে পারে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

    // Provided to ProductAdapter in ProductListActivity snippet.
    private val productClickCallback = ProductClickCallback { product ->
        show(product)
    }

    fun show(product: Product) {
        val intent = Intent(this, ProductActivity::class.java)
        intent.putExtra(ProductActivity.KEY_PRODUCT_ID, product.id)
        startActivity(intent)
    }

জাভা

// Provided to ProductAdapter in ProductListActivity snippet.
private ProductClickCallback productClickCallback = this::show;

private void show(Product product) {
    Intent intent = new Intent(this, ProductActivity.class);
    intent.putExtra(ProductActivity.KEY_PRODUCT_ID, product.getId());
    startActivity(intent);
}

আপনার খণ্ডের ভিতরে, আপনি এই কাজটি onCreateView() এবং onViewCreated() এর মধ্যে বিতরণ করেন, শুধুমাত্র নেভিগেশন লজিক কার্যকলাপে অবশিষ্ট থাকে:

কোটলিন

class ProductListFragment : Fragment() {

    private lateinit var binding: ProductListFragmentBinding
    private val viewModel: ProductListViewModel by viewModels()

     // View initialization logic
    override fun onCreateView(inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?): View? {
        binding = DataBindingUtil.inflate(
                inflater,
                R.layout.product_list,
                container,
                false
        )
        return binding.root
    }

    // Post view initialization logic
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // Connect adapters
        productAdapter = ProductAdapter(productClickCallback)
        binding.productsList.setAdapter(productAdapter)

        // Initialize view properties, set click listeners, etc.
        binding.productsSearchBtn.setOnClickListener {...}

        // Subscribe to state
        viewModel.products.observe(this, Observer { myProducts ->
            ...
        })

        // ...and so on
    }

    // Provided to ProductAdapter
    private val productClickCallback = ProductClickCallback { product ->
        if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            (requireActivity() as ProductListActivity).show(product)
        }
    }
    ...
}

জাভা

public class ProductListFragment extends Fragment {

    private ProductAdapter productAdapter;
    private ProductListFragmentBinding binding;

    // View initialization logic
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(
                inflater,
                R.layout.product_list_fragment,
                container,
                false);
        return binding.getRoot();
    }

    // Post view initialization logic
    @Override
    public void onViewCreated(@NonNull View view,
            @Nullable Bundle savedInstanceState) {

        // Connect adapters
        binding.productsList.setAdapter(productAdapter);

        // Initialize ViewModels and other dependencies
        ProductListViewModel viewModel = new ViewModelProvider(this)
                .get(ProductListViewModel.class);

        // Initialize view properties, set click listeners, etc.
        binding.productsSearchBtn.setOnClickListener(...)

        // Subscribe to state
        viewModel.getProducts().observe(this, myProducts -> {
            ...
       });

       // ...and so on

    // Provided to ProductAdapter
    private ProductClickCallback productClickCallback = new ProductClickCallback() {
        @Override
        public void onClick(Product product) {
            if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
                ((ProductListActivity) requireActivity()).show(product);
            }
        }
    };
    ...
}

ProductListFragment এ, লক্ষ্য করুন যে লেআউটটি স্ফীত করতে এবং সংযোগ করতে setContentView() এ কোনও কল নেই। একটি খণ্ডে, onCreateView() রুট ভিউ শুরু করে। onCreateView() একটি LayoutInflater এর একটি উদাহরণ নেয় যা একটি লেআউট রিসোর্স ফাইলের উপর ভিত্তি করে রুট ভিউকে স্ফীত করতে ব্যবহার করা যেতে পারে। এই উদাহরণটি বিদ্যমান product_list লেআউটটি পুনরায় ব্যবহার করে যা কার্যকলাপ দ্বারা ব্যবহৃত হয়েছিল কারণ লেআউটে কিছুই পরিবর্তন করার প্রয়োজন নেই।

যদি আপনার কার্যকলাপের onStart() , onResume() , onPause() বা onStop() ফাংশনে থাকা কোনো UI লজিক থাকে যা নেভিগেশনের সাথে সম্পর্কিত নয়, আপনি সেগুলিকে খণ্ডে একই নামের সংশ্লিষ্ট ফাংশনে স্থানান্তর করতে পারেন।

হোস্ট কার্যকলাপে খণ্ডটি শুরু করুন

একবার আপনি সমস্ত UI লজিককে ফ্র্যাগমেন্টে নিয়ে গেলে, শুধুমাত্র নেভিগেশন লজিক কার্যকলাপে থাকা উচিত।

কোটলিন

class ProductListActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.product_list_host)
    }

    fun show(product: Product) {
        val intent = Intent(this, ProductActivity::class.java)
        intent.putExtra(ProductActivity.KEY_PRODUCT_ID, product.id)
        startActivity(intent)
    }
}

জাভা

public class ProductListActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.product_list_host);
    }

    public void show(Product product) {
        Intent intent = new Intent(this, ProductActivity.class);
        intent.putExtra(ProductActivity.KEY_PRODUCT_ID, product.getId());
        startActivity(intent);
    }
}

শেষ ধাপ হল onCreate() এ খণ্ডের একটি উদাহরণ তৈরি করা, ঠিক কন্টেন্ট ভিউ সেট করার পরে:

কোটলিন

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.product_list_host)

    if (savedInstanceState == null) {
        val fragment = ProductListFragment()
        supportFragmentManager
                .beginTransaction()
                .add(R.id.main_content, fragment)
                .commit()
    }
}

জাভা

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.product_list_host);

    if (savedInstanceState == null) {
        ProductListFragment fragment = new ProductListFragment();
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.main_content, fragment)
                .commit();
    }
}

যেমন এই উদাহরণে দেখানো হয়েছে, FragmentManager স্বয়ংক্রিয়ভাবে কনফিগারেশন পরিবর্তনের উপর টুকরোগুলি সংরক্ষণ এবং পুনরুদ্ধার করে, তাই আপনাকে শুধুমাত্র savedInstanceState শূন্য হলেই খণ্ডটি যোগ করতে হবে।

খণ্ডে অভিপ্রায় অতিরিক্ত পাস

যদি আপনার ক্রিয়াকলাপ একটি অভিপ্রায়ের মাধ্যমে Extras গ্রহণ করে, আপনি এগুলিকে আর্গুমেন্ট হিসাবে সরাসরি টুকরোতে পাঠাতে পারেন৷

এই উদাহরণে, ProductDetailsFragment সরাসরি কার্যকলাপের উদ্দেশ্য অতিরিক্ত থেকে তার আর্গুমেন্ট গ্রহণ করে:

কোটলিন

...

if (savedInstanceState == null) {
    val fragment = ProductDetailsFragment()

    // Intent extras and Fragment Args are both of type android.os.Bundle.
    fragment.arguments = intent.extras

    supportFragmentManager
            .beginTransaction()
            .add(R.id.main_content, fragment)
            .commit()
}

...

জাভা

...

if (savedInstanceState == null) {
    ProductDetailsFragment fragment = new ProductDetailsFragment();

    // Intent extras and fragment Args are both of type android.os.Bundle.
    fragment.setArguments(getIntent().getExtras());

    getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.main_content, fragment)
            .commit();
}

...

এই মুহুর্তে, আপনি একটি টুকরো ব্যবহার করার জন্য আপডেট করা প্রথম স্ক্রীনের সাথে আপনার অ্যাপ চালানোর পরীক্ষা করতে সক্ষম হবেন। আপনার বাকি কার্যকলাপ-ভিত্তিক স্ক্রীনগুলি স্থানান্তর করা চালিয়ে যান, প্রতিটি পুনরাবৃত্তির পরে পরীক্ষা করার জন্য সময় নিয়ে।

নেভিগেশন উপাদান একীভূত

একবার আপনি একটি খণ্ড-ভিত্তিক আর্কিটেকচার ব্যবহার করার পরে, আপনি নেভিগেশন উপাদান সংহত করা শুরু করতে প্রস্তুত।

প্রথমে, নেভিগেশন লাইব্রেরি রিলিজ নোটে নির্দেশাবলী অনুসরণ করে আপনার প্রকল্পে সাম্প্রতিক নেভিগেশন নির্ভরতা যোগ করুন।

একটি নেভিগেশন গ্রাফ তৈরি করুন

নেভিগেশন কম্পোনেন্ট আপনার অ্যাপের নেভিগেশন কনফিগারেশনকে একটি গ্রাফ হিসাবে রিসোর্স ফাইলে উপস্থাপন করে, অনেকটা আপনার অ্যাপের ভিউয়ের মতো। এটি আপনার কোডবেসের বাইরে আপনার অ্যাপের নেভিগেশন সংগঠিত রাখতে সাহায্য করে এবং আপনার অ্যাপ নেভিগেশনকে দৃশ্যত সম্পাদনা করার একটি উপায় প্রদান করে।

একটি নেভিগেশন গ্রাফ তৈরি করতে, navigation নামে একটি নতুন সংস্থান ফোল্ডার তৈরি করে শুরু করুন। গ্রাফ যোগ করতে, এই ডিরেক্টরিতে ডান-ক্লিক করুন, এবং নতুন > নেভিগেশন রিসোর্স ফাইল নির্বাচন করুন।

নেভিগেশন উপাদান নেভিগেশনের জন্য একটি হোস্ট হিসাবে একটি কার্যকলাপ ব্যবহার করে এবং আপনার ব্যবহারকারীরা আপনার অ্যাপের মাধ্যমে নেভিগেট করার সাথে সাথে সেই হোস্টে পৃথক টুকরো অদলবদল করে। আপনি দৃশ্যত আপনার অ্যাপের নেভিগেশন লেআউট করা শুরু করার আগে, এই গ্রাফটি হোস্ট করতে যাচ্ছে এমন কার্যকলাপের ভিতরে আপনাকে একটি NavHost কনফিগার করতে হবে। যেহেতু আমরা টুকরা ব্যবহার করছি, তাই আমরা নেভিগেশন কম্পোনেন্টের ডিফল্ট NavHost বাস্তবায়ন, NavHostFragment ব্যবহার করতে পারি।

একটি NavHostFragment একটি হোস্ট কার্যকলাপের ভিতরে স্থাপন করা FragmentContainerView এর মাধ্যমে কনফিগার করা হয়েছে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

<androidx.fragment.app.FragmentContainerView
   android:name="androidx.navigation.fragment.NavHostFragment"
   app:navGraph="@navigation/product_list_graph"
   app:defaultNavHost="true"
   android:id="@+id/main_content"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />

app:NavGraph বৈশিষ্ট্য এই নেভিগেশন হোস্টের সাথে যুক্ত নেভিগেশন গ্রাফের দিকে নির্দেশ করে। এই প্রপার্টি সেট করা হলে এনএভি গ্রাফ স্ফীত হয় এবং গ্রাফ প্রপার্টি NavHostFragment এ সেট করে। app:defaultNavHost অ্যাট্রিবিউট নিশ্চিত করে যে আপনার NavHostFragment সিস্টেম ব্যাক বোতামটিকে বাধা দেয়।

আপনি যদি শীর্ষ-স্তরের নেভিগেশন ব্যবহার করেন যেমন একটি DrawerLayout বা BottomNavigationView , এই FragmentContainerView আপনার প্রধান বিষয়বস্তু দেখার উপাদানটি প্রতিস্থাপন করে। উদাহরণের জন্য NavigationUI এর সাথে আপডেট UI উপাদান দেখুন।

একটি সাধারণ লেআউটের জন্য, আপনি এই FragmentContainerView উপাদানটিকে রুট ViewGroup একটি শিশু হিসাবে অন্তর্ভুক্ত করতে পারেন:

<FrameLayout
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_height="match_parent"
   android:layout_width="match_parent">

<androidx.fragment.app.FragmentContainerView
   android:id="@+id/main_content"
   android:name="androidx.navigation.fragment.NavHostFragment"
   app:navGraph="@navigation/product_list_graph"
   app:defaultNavHost="true"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />

</FrameLayout>

আপনি যদি নীচের দিকে ডিজাইন ট্যাবে ক্লিক করেন, তাহলে আপনি নীচের চিত্রের মতো একটি গ্রাফ দেখতে পাবেন। গ্রাফের উপরের বাম দিকে, গন্তব্যের অধীনে, আপনি layout_name (resource_id) আকারে NavHost কার্যকলাপের একটি রেফারেন্স দেখতে পারেন।

প্লাস বোতামে ক্লিক করুন এই গ্রাফে আপনার টুকরা যোগ করতে শীর্ষের কাছাকাছি।

নেভিগেশন উপাদান গন্তব্য হিসাবে পৃথক পর্দা উল্লেখ করে। গন্তব্যগুলি টুকরো, কার্যকলাপ বা কাস্টম গন্তব্য হতে পারে। আপনি আপনার গ্রাফে যেকোনো ধরনের গন্তব্য যোগ করতে পারেন, কিন্তু মনে রাখবেন যে কার্যকলাপের গন্তব্যগুলিকে টার্মিনাল গন্তব্য হিসাবে বিবেচনা করা হয়, কারণ আপনি একবার একটি কার্যকলাপের গন্তব্যে নেভিগেট করলে, আপনি একটি পৃথক নেভিগেশন হোস্ট এবং গ্রাফের মধ্যে কাজ করছেন।

নেভিগেশন কম্পোনেন্টটি বোঝায় যেভাবে ব্যবহারকারীরা ক্রিয়া হিসাবে এক গন্তব্য থেকে অন্য গন্তব্যে যায়৷ ক্রিয়াগুলি রূপান্তর অ্যানিমেশন এবং পপ আচরণকেও বর্ণনা করতে পারে।

খণ্ড লেনদেন সরান

এখন আপনি ন্যাভিগেশন উপাদান ব্যবহার করছেন, যদি আপনি একই কার্যকলাপের অধীনে খণ্ড-ভিত্তিক স্ক্রীনগুলির মধ্যে নেভিগেট করেন, আপনি FragmentManager ইন্টারঅ্যাকশনগুলি সরাতে পারেন।

যদি আপনার অ্যাপ একই ক্রিয়াকলাপের অধীনে একাধিক খণ্ড ব্যবহার করে বা শীর্ষ-স্তরের নেভিগেশন যেমন একটি ড্রয়ার লেআউট বা নীচের নেভিগেশন, তাহলে আপনি সম্ভবত আপনার UI এর প্রধান বিষয়বস্তু বিভাগে খণ্ডগুলি যোগ বা প্রতিস্থাপন করতে একটি FragmentManager এবং FragmentTransactions ব্যবহার করছেন৷ এটি এখন আপনার গ্রাফের মধ্যে গন্তব্যগুলিকে লিঙ্ক করার জন্য ক্রিয়া প্রদান করে এবং তারপর NavController ব্যবহার করে নেভিগেট করার মাধ্যমে নেভিগেশন উপাদান ব্যবহার করে প্রতিস্থাপন এবং সরলীকৃত করা যেতে পারে।

প্রতিটি পরিস্থিতির জন্য আপনি কীভাবে মাইগ্রেশনের কাছে যেতে পারেন তার সাথে এখানে কয়েকটি পরিস্থিতির সম্মুখীন হতে পারেন।

একাধিক খণ্ড পরিচালনা করা একক কার্যকলাপ

আপনার যদি একটি একক ক্রিয়াকলাপ থাকে যা একাধিক খণ্ড পরিচালনা করে, তাহলে আপনার কার্যকলাপ কোড দেখতে এইরকম হতে পারে:

কোটলিন

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Logic to load the starting destination
        //  when the Activity is first created
        if (savedInstanceState == null) {
            val fragment = ProductListFragment()
            supportFragmentManager.beginTransaction()
                    .add(R.id.fragment_container, fragment, ProductListFragment.TAG)
                    .commit()
        }
    }

    // Logic to navigate the user to another destination.
    // This may include logic to initialize and set arguments on the destination
    // fragment or even transition animations between the fragments (not shown here).
    fun navigateToProductDetail(productId: String) {
        val fragment = new ProductDetailsFragment()
        val args = Bundle().apply {
            putInt(KEY_PRODUCT_ID, productId)
        }
        fragment.arguments = args

        supportFragmentManager.beginTransaction()
                .addToBackStack(ProductDetailsFragment.TAG)
                .replace(R.id.fragment_container, fragment, ProductDetailsFragment.TAG)
                .commit()
    }
}

জাভা

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Logic to load the starting destination when the activity is first created.
        if (savedInstanceState == null) {
            val fragment = ProductListFragment()
            supportFragmentManager.beginTransaction()
                    .add(R.id.fragment_container, fragment, ProductListFragment.TAG)
                    .commit();
        }
    }

    // Logic to navigate the user to another destination.
    // This may include logic to initialize and set arguments on the destination
    // fragment or even transition animations between the fragments (not shown here).
    public void navigateToProductDetail(String productId) {
        Fragment fragment = new ProductDetailsFragment();
        Bundle args = new Bundle();
        args.putInt(KEY_PRODUCT_ID, productId);
        fragment.setArguments(args);

        getSupportFragmentManager().beginTransaction()
                .addToBackStack(ProductDetailsFragment.TAG)
                .replace(R.id.fragment_container, fragment, ProductDetailsFragment.TAG)
                .commit();
    }
}

উৎস গন্তব্যের ভিতরে, আপনি কিছু ইভেন্টের প্রতিক্রিয়া হিসাবে একটি নেভিগেশন ফাংশন আহ্বান করছেন, যেমনটি নীচে দেখানো হয়েছে:

কোটলিন

class ProductListFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // In this example a callback is passed to respond to an item clicked
        //  in a RecyclerView
        productAdapter = ProductAdapter(productClickCallback)
        binding.productsList.setAdapter(productAdapter)
    }
    ...

    // The callback makes the call to the activity to make the transition.
    private val productClickCallback = ProductClickCallback { product ->
            (requireActivity() as MainActivity).navigateToProductDetail(product.id)
    }
}

জাভা

public class ProductListFragment extends Fragment  {
    ...
    @Override
    public void onViewCreated(@NonNull View view,
            @Nullable Bundle savedInstanceState) {
    // In this example a callback is passed to respond to an item clicked in a RecyclerView
        productAdapter = new ProductAdapter(productClickCallback);
        binding.productsList.setAdapter(productAdapter);
    }
    ...

    // The callback makes the call to the activity to make the transition.
    private ProductClickCallback productClickCallback = product -> (
        ((MainActivity) requireActivity()).navigateToProductDetail(product.getId())
    );
}

শুরুর গন্তব্য সেট করতে আপনার নেভিগেশন গ্রাফ আপডেট করে এটিকে প্রতিস্থাপন করা যেতে পারে এবং আপনার গন্তব্যগুলিকে লিঙ্ক করতে এবং যেখানে প্রয়োজন সেখানে আর্গুমেন্ট সংজ্ঞায়িত করার জন্য অ্যাকশনগুলি সেট করা যেতে পারে:

<navigation 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:id="@+id/product_list_graph"
    app:startDestination="@id/product_list">

    <fragment
        android:id="@+id/product_list"
        android:name="com.example.android.persistence.ui.ProductListFragment"
        android:label="Product List"
        tools:layout="@layout/product_list">
        <action
            android:id="@+id/navigate_to_product_detail"
            app:destination="@id/product_detail" />
    </fragment>
    <fragment
        android:id="@+id/product_detail"
        android:name="com.example.android.persistence.ui.ProductDetailFragment"
        android:label="Product Detail"
        tools:layout="@layout/product_detail">
        <argument
            android:name="product_id"
            app:argType="integer" />
    </fragment>
</navigation>

তারপর, আপনি আপনার কার্যকলাপ আপডেট করতে পারেন:

কোটলিন

class MainActivity : AppCompatActivity() {

    // No need to load the start destination, handled automatically by the Navigation component
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

জাভা

public class MainActivity extends AppCompatActivity {

    // No need to load the start destination, handled automatically by the Navigation component
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

কার্যকলাপের আর একটি navigateToProductDetail() পদ্ধতির প্রয়োজন নেই। পরবর্তী বিভাগে, আমরা পরবর্তী পণ্যের বিস্তারিত স্ক্রীনে নেভিগেট করতে NavController ব্যবহার করতে ProductListFragment আপডেট করি।

নিরাপদে আর্গুমেন্ট পাস

নেভিগেশন কম্পোনেন্টে Safe Args নামে একটি Gradle প্লাগইন রয়েছে যা গন্তব্য এবং কর্মের জন্য নির্দিষ্ট আর্গুমেন্টে টাইপ-নিরাপদ অ্যাক্সেসের জন্য সাধারণ অবজেক্ট এবং বিল্ডার ক্লাস তৈরি করে।

একবার প্লাগইন প্রয়োগ করা হলে, আপনার ন্যাভিগেশন গ্রাফে একটি গন্তব্যে সংজ্ঞায়িত যেকোনো আর্গুমেন্টের কারণে নেভিগেশন কম্পোনেন্ট ফ্রেমওয়ার্ক একটি Arguments ক্লাস তৈরি করে যা লক্ষ্য গন্তব্যে টাইপ নিরাপদ আর্গুমেন্ট প্রদান করে। একটি ক্রিয়া সংজ্ঞায়িত করার ফলে প্লাগইন একটি Directions কনফিগারেশন ক্লাস তৈরি করে যা ব্যবহারকারীকে কীভাবে লক্ষ্য গন্তব্যে নেভিগেট করতে হয় তা NavController কে বলতে ব্যবহার করা যেতে পারে। যখন একটি অ্যাকশন একটি গন্তব্যের দিকে নির্দেশ করে যার জন্য আর্গুমেন্টের প্রয়োজন হয়, তখন জেনারেট করা Directions ক্লাসে কনস্ট্রাক্টর পদ্ধতি অন্তর্ভুক্ত থাকে যার জন্য সেই প্যারামিটারগুলির প্রয়োজন হয়।

খণ্ডের ভিতরে, লক্ষ্য গন্তব্যে টাইপ-সেফ আর্গুমেন্ট প্রদান করতে NavController এবং জেনারেট করা Directions ক্লাস ব্যবহার করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

class ProductListFragment : Fragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // In this example a callback is passed to respond to an item clicked in a RecyclerView
        productAdapter = ProductAdapter(productClickCallback)
        binding.productsList.setAdapter(productAdapter)
    }
    ...

    // The callback makes the call to the NavController to make the transition.
    private val productClickCallback = ProductClickCallback { product ->
        val directions = ProductListDirections.navigateToProductDetail(product.id)
        findNavController().navigate(directions)
    }
}

জাভা

public class ProductListFragment extends Fragment  {
    ...
    @Override
    public void onViewCreated(@NonNull View view,
            @Nullable Bundle savedInstanceState) {
        // In this example a callback is passed to respond to an item clicked in a RecyclerView
        productAdapter = new ProductAdapter(productClickCallback);
        binding.productsList.setAdapter(productAdapter);
    }
    ...

    // The callback makes the call to the activity to make the transition.
    private ProductClickCallback productClickCallback = product -> {
        ProductListDirections.ViewProductDetails directions =
                ProductListDirections.navigateToProductDetail(product.getId());
        NavHostFragment.findNavController(this).navigate(directions);
    };
}

টপ-লেভেল নেভিগেশন

যদি আপনার অ্যাপ একটি DrawerLayout ব্যবহার করে, তাহলে আপনার কার্যকলাপে অনেক কনফিগারেশন লজিক থাকতে পারে যা ড্রয়ার খোলা ও বন্ধ করা এবং অন্যান্য গন্তব্যে নেভিগেট করা পরিচালনা করে।

আপনার ফলাফল কার্যকলাপ এই মত কিছু দেখতে পারে:

কোটলিন

class MainActivity : AppCompatActivity(),
    NavigationView.OnNavigationItemSelectedListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)

        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        val navView: NavigationView = findViewById(R.id.nav_view)
        val toggle = ActionBarDrawerToggle(
                this,
                drawerLayout,
                toolbar,
                R.string.navigation_drawer_open, 
                R.string.navigation_drawer_close
        )
        drawerLayout.addDrawerListener(toggle)
        toggle.syncState()

        navView.setNavigationItemSelectedListener(this)
    }

    override fun onBackPressed() {
        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START)
        } else {
            super.onBackPressed()
        }
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        // Handle navigation view item clicks here.
        when (item.itemId) {
            R.id.home -> {
                val homeFragment = HomeFragment()
                show(homeFragment)
            }
            R.id.gallery -> {
                val galleryFragment = GalleryFragment()
                show(galleryFragment)
            }
            R.id.slide_show -> {
                val slideShowFragment = SlideShowFragment()
                show(slideShowFragment)
            }
            R.id.tools -> {
                val toolsFragment = ToolsFragment()
                show(toolsFragment)
            }
        }
        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        drawerLayout.closeDrawer(GravityCompat.START)
        return true
    }
}

private fun show(fragment: Fragment) {

    val drawerLayout = drawer_layout as DrawerLayout
    val fragmentManager = supportFragmentManager

    fragmentManager
            .beginTransaction()
            .replace(R.id.main_content, fragment)
            .commit()

    drawerLayout.closeDrawer(GravityCompat.START)
}

জাভা

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this,
                drawer,
                toolbar,
                R.string.navigation_drawer_open,
                R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.home) {
            Fragment homeFragment = new HomeFragment();
            show(homeFragment);
        } else if (id == R.id.gallery) {
            Fragment galleryFragment = new GalleryFragment();
            show(galleryFragment);
        } else if (id == R.id.slide_show) {
            Fragment slideShowFragment = new SlideShowFragment();
            show(slideShowFragment);
        } else if (id == R.id.tools) {
            Fragment toolsFragment = new ToolsFragment();
            show(toolsFragment);
        }

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    private void show(Fragment fragment) {

        DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
        FragmentManager fragmentManager = getSupportFragmentManager();

        fragmentManager
                .beginTransaction()
                .replace(R.id.main_content, fragment)
                .commit();

        drawerLayout.closeDrawer(GravityCompat.START);
    }
}

আপনি আপনার প্রকল্পে নেভিগেশন উপাদান যোগ করার পরে এবং একটি নেভিগেশন গ্রাফ তৈরি করার পরে, আপনার গ্রাফ থেকে প্রতিটি বিষয়বস্তুর গন্তব্য যোগ করুন (যেমন হোম , গ্যালারি , স্লাইডশো , এবং উপরের উদাহরণ থেকে সরঞ্জাম )। নিশ্চিত করুন যে আপনার মেনু আইটেম id মানগুলি তাদের সম্পর্কিত গন্তব্য id মানগুলির সাথে মেলে, যেমনটি নীচে দেখানো হয়েছে:

<!-- activity_main_drawer.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/home"
            android:icon="@drawable/ic_menu_camera"
            android:title="@string/menu_home" />
        <item
            android:id="@+id/gallery"
            android:icon="@drawable/ic_menu_gallery"
            android:title="@string/menu_gallery" />
        <item
            android:id="@+id/slide_show"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="@string/menu_slideshow" />
        <item
            android:id="@+id/tools"
            android:icon="@drawable/ic_menu_manage"
            android:title="@string/menu_tools" />
    </group>
</menu>
<!-- activity_main_graph.xml -->
<navigation 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:id="@+id/main_graph"
    app:startDestination="@id/home">

    <fragment
        android:id="@+id/home"
        android:name="com.example.HomeFragment"
        android:label="Home"
        tools:layout="@layout/home" />

    <fragment
        android:id="@+id/gallery"
        android:name="com.example.GalleryFragment"
        android:label="Gallery"
        tools:layout="@layout/gallery" />

    <fragment
        android:id="@+id/slide_show"
        android:name="com.example.SlideShowFragment"
        android:label="Slide Show"
        tools:layout="@layout/slide_show" />

    <fragment
        android:id="@+id/tools"
        android:name="com.example.ToolsFragment"
        android:label="Tools"
        tools:layout="@layout/tools" />

</navigation>

আপনি যদি আপনার মেনু এবং গ্রাফ থেকে id মানগুলির সাথে মেলে, তাহলে আপনি মেনু আইটেমের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে নেভিগেশন পরিচালনা করতে এই কার্যকলাপের জন্য NavController ওয়্যার আপ করতে পারেন। NavController এছাড়াও DrawerLayout খোলা এবং বন্ধ করা এবং আপ এবং ব্যাক বোতাম আচরণ যথাযথভাবে পরিচালনা করে।

আপনার MainActivity তারপর Toolbar এবং NavigationView NavController ওয়্যার আপ করতে আপডেট করা যেতে পারে।

একটি উদাহরণের জন্য নিম্নলিখিত স্নিপেট দেখুন:

কোটলিন

class MainActivity : AppCompatActivity()  {

    val drawerLayout by lazy { findViewById<DrawerLayout>(R.id.drawer_layout) }
    val navController by lazy {
      (supportFragmentManager.findFragmentById(R.id.main_content) as NavHostFragment).navController
    }
    val navigationView by lazy { findViewById<NavigationView>(R.id.nav_view) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)

        // Show and Manage the Drawer and Back Icon
        setupActionBarWithNavController(navController, drawerLayout)

        // Handle Navigation item clicks
        // This works with no further action on your part if the menu and destination id’s match.
        navigationView.setupWithNavController(navController)

    }

    override fun onSupportNavigateUp(): Boolean {
        // Allows NavigationUI to support proper up navigation or the drawer layout
        // drawer menu, depending on the situation
        return navController.navigateUp(drawerLayout)
    }
}

জাভা

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;
    private NavController navController;
    private NavigationView navigationView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        drawerLayout = findViewById(R.id.drawer_layout);
        NavHostFragment navHostFragment = (NavHostFragment)
            getSupportFragmentManager().findFragmentById(R.id.main_content);
        navController = navHostFragment.getNavController();
        navigationView = findViewById(R.id.nav_view);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Show and Manage the Drawer and Back Icon
        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);

        // Handle Navigation item clicks
        // This works with no further action on your part if the menu and destination id’s match.
        NavigationUI.setupWithNavController(navigationView, navController);

    }

    @Override
    public boolean onSupportNavigateUp() {
        // Allows NavigationUI to support proper up navigation or the drawer layout
        // drawer menu, depending on the situation.
        return NavigationUI.navigateUp(navController, drawerLayout);

    }
}

আপনি BottomNavigationView-ভিত্তিক নেভিগেশন এবং মেনু-ভিত্তিক নেভিগেশন উভয়ের সাথে এই একই কৌশলটি ব্যবহার করতে পারেন। আরও উদাহরণের জন্য NavigationUI এর সাথে UI উপাদান আপডেট করুন দেখুন।

কার্যকলাপ গন্তব্য যোগ করুন

একবার আপনার অ্যাপের প্রতিটি স্ক্রীন নেভিগেশন কম্পোনেন্ট ব্যবহার করার জন্য ওয়্যার আপ হয়ে গেলে, এবং আপনি আর ফ্র্যাগমেন্ট-ভিত্তিক গন্তব্যগুলির মধ্যে স্থানান্তর করতে FragmentTransactions ব্যবহার করছেন না, পরবর্তী ধাপ হল startActivity কলগুলি বাদ দেওয়া।

প্রথমে, আপনার অ্যাপে এমন স্থানগুলি চিহ্নিত করুন যেখানে আপনার দুটি পৃথক নেভিগেশন গ্রাফ রয়েছে এবং তাদের মধ্যে স্থানান্তর করতে startActivity ব্যবহার করছেন৷

এই উদাহরণে দুটি গ্রাফ (A এবং B) এবং একটি startActivity() A থেকে B তে রূপান্তরের কল রয়েছে।

কোটলিন

fun navigateToProductDetails(productId: String) {
    val intent = Intent(this, ProductDetailsActivity::class.java)
    intent.putExtra(KEY_PRODUCT_ID, productId)
    startActivity(intent)
}

জাভা

private void navigateToProductDetails(String productId) {
    Intent intent = new Intent(this, ProductDetailsActivity.class);
    intent.putExtra(KEY_PRODUCT_ID, productId);
    startActivity(intent);

এর পরে, এগুলিকে গ্রাফ A-তে একটি কার্যকলাপের গন্তব্যের সাথে প্রতিস্থাপন করুন যা গ্রাফ B-এর হোস্ট কার্যকলাপে নেভিগেশন প্রতিনিধিত্ব করে। যদি আপনার কাছে গ্রাফ B-এর শুরু গন্তব্যে যাওয়ার জন্য যুক্তি থাকে, আপনি সেগুলিকে কার্যকলাপের গন্তব্য সংজ্ঞাতে মনোনীত করতে পারেন।

নিম্নলিখিত উদাহরণে, গ্রাফ A একটি কার্যকলাপের গন্তব্যকে সংজ্ঞায়িত করে যা একটি কর্মের সাথে একটি product_id আর্গুমেন্ট নেয়। গ্রাফ B-এ কোন পরিবর্তন নেই।

গ্রাফ A এবং B এর XML উপস্থাপনা এইরকম দেখতে পারে:

<!-- Graph A -->
<navigation 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:id="@+id/product_list_graph"
    app:startDestination="@id/product_list">

    <fragment
        android:id="@+id/product_list"
        android:name="com.example.android.persistence.ui.ProductListFragment"
        android:label="Product List"
        tools:layout="@layout/product_list_fragment">
        <action
            android:id="@+id/navigate_to_product_detail"
            app:destination="@id/product_details_activity" />
    </fragment>

    <activity
        android:id="@+id/product_details_activity"
        android:name="com.example.android.persistence.ui.ProductDetailsActivity"
        android:label="Product Details"
        tools:layout="@layout/product_details_host">

        <argument
            android:name="product_id"
            app:argType="integer" />

    </activity>

</navigation>
<!-- Graph B -->
<navigation 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"
    app:startDestination="@id/product_details">

    <fragment
        android:id="@+id/product_details"
        android:name="com.example.android.persistence.ui.ProductDetailsFragment"
        android:label="Product Details"
        tools:layout="@layout/product_details_fragment">
        <argument
            android:name="product_id"
            app:argType="integer" />
    </fragment>

</navigation>

আপনি খণ্ড গন্তব্যে নেভিগেট করার জন্য যে প্রক্রিয়াগুলি ব্যবহার করেন একই পদ্ধতি ব্যবহার করে আপনি গ্রাফ B-এর হোস্ট কার্যকলাপে নেভিগেট করতে পারেন:

কোটলিন

fun navigateToProductDetails(productId: String) {
    val directions = ProductListDirections.navigateToProductDetail(productId)
    findNavController().navigate(directions)
}

জাভা

private void navigateToProductDetails(String productId) {
    ProductListDirections.NavigateToProductDetail directions =
            ProductListDirections.navigateToProductDetail(productId);
    Navigation.findNavController(getView()).navigate(directions);

একটি শুরু গন্তব্য খণ্ডে কার্যকলাপ গন্তব্য args পাস করুন

যদি গন্তব্য ক্রিয়াকলাপ অতিরিক্ত গ্রহণ করে, আগের উদাহরণের মতো, আপনি এগুলিকে আর্গুমেন্ট হিসাবে সরাসরি শুরুর গন্তব্যে পাঠাতে পারেন, তবে আপনাকে হোস্ট কার্যকলাপের onCreate() পদ্ধতিতে আপনার হোস্টের নেভিগেশন গ্রাফটি ম্যানুয়ালি সেট করতে হবে যাতে আপনি অভিপ্রায়টি পাস করতে পারেন খণ্ডের আর্গুমেন্ট হিসাবে অতিরিক্ত, নীচে দেখানো হিসাবে:

কোটলিন

class ProductDetailsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.product_details_host)
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.main_content) as NavHostFragment
        val navController = navHostFramgent.navController
        navController
                .setGraph(R.navigation.product_detail_graph, intent.extras)
    }

}

জাভা

public class ProductDetailsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.product_details_host);
        NavHostFragment navHostFragment = (NavHostFragment)
            getSupportFragmentManager().findFragmentById(R.id.main_content);
        NavController navController = navHostFragment.getNavController();
        navController
                .setGraph(R.navigation.product_detail_graph, getIntent().getExtras());
    }

}

নিচের উদাহরণে যেমন দেখানো হয়েছে, জেনারেট করা আর্গস ক্লাস ব্যবহার করে ফ্র্যাগমেন্ট আর্গুমেন্ট Bundle থেকে ডেটা বের করা যেতে পারে:

কোটলিন

class ProductDetailsFragment : Fragment() {

    val args by navArgs<ProductDetailsArgs>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val productId = args.productId
        ...
    }
    ...

জাভা

public class ProductDetailsFragment extends Fragment {

    ProductDetailsArgs args;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        args = ProductDetailsArgs.fromBundle(requireArguments());
    }

    @Override
    public void onViewCreated(@NonNull View view,
            @Nullable Bundle savedInstanceState) {
       int productId = args.getProductId();
       ...
    }
    ...

কার্যক্রম একত্রিত করুন

আপনি এমন ক্ষেত্রে নেভিগেশন গ্রাফগুলি একত্রিত করতে পারেন যেখানে একাধিক ক্রিয়াকলাপ একই বিন্যাস ভাগ করে, যেমন একটি একক খণ্ডযুক্ত একটি সাধারণ FrameLayout । এই বেশিরভাগ ক্ষেত্রে, আপনি প্রতিটি নেভিগেশন গ্রাফ থেকে সমস্ত উপাদান একত্রিত করতে পারেন এবং যেকোন কার্যকলাপের গন্তব্য উপাদানগুলিকে টুকরো গন্তব্যে আপডেট করতে পারেন।

নিম্নলিখিত উদাহরণটি পূর্ববর্তী বিভাগ থেকে A এবং B গ্রাফগুলিকে একত্রিত করে:

একত্রিত করার আগে:

<!-- Graph A -->
<navigation 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:id="@+id/product_list_graph"
    app:startDestination="@id/product_list">

    <fragment
        android:id="@+id/product_list"
        android:name="com.example.android.persistence.ui.ProductListFragment"
        android:label="Product List Fragment"
        tools:layout="@layout/product_list">
        <action
            android:id="@+id/navigate_to_product_detail"
            app:destination="@id/product_details_activity" />
    </fragment>
    <activity
        android:id="@+id/product_details_activity"
        android:name="com.example.android.persistence.ui.ProductDetailsActivity"
        android:label="Product Details Host"
        tools:layout="@layout/product_details_host">
        <argument android:name="product_id"
            app:argType="integer" />
    </activity>

</navigation>
<!-- Graph B -->
<navigation 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:id="@+id/product_detail_graph"
    app:startDestination="@id/product_details">

    <fragment
        android:id="@+id/product_details"
        android:name="com.example.android.persistence.ui.ProductDetailsFragment"
        android:label="Product Details"
        tools:layout="@layout/product_details">
        <argument
            android:name="product_id"
            app:argType="integer" />
    </fragment>
</navigation>

একত্রিত করার পরে:

<!-- Combined Graph A and B -->
<navigation 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:id="@+id/product_list_graph"
    app:startDestination="@id/product_list">

    <fragment
        android:id="@+id/product_list"
        android:name="com.example.android.persistence.ui.ProductListFragment"
        android:label="Product List Fragment"
        tools:layout="@layout/product_list">
        <action
            android:id="@+id/navigate_to_product_detail"
            app:destination="@id/product_details" />
    </fragment>

    <fragment
        android:id="@+id/product_details"
        android:name="com.example.android.persistence.ui.ProductDetailsFragment"
        android:label="Product Details"
        tools:layout="@layout/product_details">
        <argument
            android:name="product_id"
            app:argType="integer" />
    </fragment>

</navigation>

মার্জ করার সময় আপনার অ্যাকশনের নাম একই রাখা এটিকে একটি বিরামহীন প্রক্রিয়া করে তুলতে পারে, আপনার বিদ্যমান কোড বেসে কোনো পরিবর্তনের প্রয়োজন নেই। উদাহরণস্বরূপ, navigateToProductDetail এখানে একই থাকে। শুধুমাত্র পার্থক্য হল যে এই ক্রিয়াটি এখন একটি কার্যকলাপ গন্তব্যের পরিবর্তে একই NavHost মধ্যে একটি খণ্ড গন্তব্যে নেভিগেশন প্রতিনিধিত্ব করে:

কোটলিন

fun navigateToProductDetails(productId: String) {
    val directions = ProductListDirections.navigateToProductDetail(productId)
    findNavController().navigate(directions)
}

জাভা

private void navigateToProductDetails(String productId) {
    ProductListDirections.NavigateToProductDetail directions =
            ProductListDirections.navigateToProductDetail(productId);
    Navigation.findNavController(getView()).navigate(directions);

অতিরিক্ত সম্পদ

আরও নেভিগেশন-সম্পর্কিত তথ্যের জন্য, নিম্নলিখিত বিষয়গুলি দেখুন: