Sobes.tech
Middle

Πώς θα υλοποιούσες την πλοήγηση με κουμπιά ώστε να διατηρεί το στοίβα;

sobes.tech AI

Απάντηση από AI

Θα χρησιμοποιούσα το Navigation Architecture Component.

  1. Δημιουργία NavGraph: Θα ορίζαμε τους Προορισμούς ( fragments ή Activity ) και τις Actions (μεταβάσεις μεταξύ τους) σε ένα πόρο XML.

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/nav_graph"
        app:startDestination="@id/fragmentA"> // Αρχική θέση
    
        <fragment
            android:id="@+id/fragmentA"
            android:name="com.example.FragmentA"
            android:label="FragmentA" >
            <action
                android:id="@+id/action_fragmentA_to_fragmentB"
                app:destination="@id/fragmentB" />
        </fragment>
        <fragment
            android:id="@+id/fragmentB"
            android:name="com.example.FragmentB"
            android:label="FragmentB" >
            <action
                android:id="@+id/action_fragmentB_to_fragmentC"
                app:destination="@id/fragmentC" />
        </fragment>
         <fragment
            android:id="@+id/fragmentC"
            android:name="com.example.FragmentC"
            android:label="FragmentC" />
    </navigation>
    
  2. Τοποθέτηση NavHost: Θα πρόσθετα ένα NavHost (π.χ., NavHostFragment) στο layout της δραστηριότητας, συνδεδεμένο με το NavGraph.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" /> // Σύνδεση με το NavGraph
    
        <!-- Εδώ μπορούν να υπάρχουν κουμπιά πλοήγησης -->
    </LinearLayout>
    
  3. Προσθήκη κουμπιών πλοήγησης: Θα χρησιμοποιούσα BottomNavigationView ή ξεχωριστά κουμπιά. Για το BottomNavigationView, θα το συνδέαμε με το NavController.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" />
    
        <Button
            android:id="@+id/button_go_to_b"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Πήγαινε στο B" />
    
        <Button
            android:id="@+id/button_go_to_c"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Πήγαινε στο C" />
    </LinearLayout>
    
  4. Επεξεργασία πατήματος κουμπιών στον κώδικα: Θα έπαιρνα το αντικείμενο NavController και θα καλούσα navigate() όταν πατιόταν το κουμπί. Το NavController διαχειρίζεται αυτόματα το back stack, διατηρώντας τον προηγούμενο Προορισμό.

    // Στο Activity ή Fragment
    import androidx.navigation.findNavController
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        val navController = findNavController(R.id.nav_host_fragment) // Απόκτηση NavController
    
        view.findViewById<Button>(R.id.button_go_to_b).setOnClickListener {
            navController.navigate(R.id.action_fragmentA_to_fragmentB) // Μετάβαση μέσω Action
        }
    
        view.findViewById<Button>(R.id.button_go_to_c).setOnClickListener {
            // Άμεση μετάβαση σε Προορισμό, μπορεί να χρησιμοποιηθεί το `action_fragmentA_to_fragmentC` αν υπάρχει
             navController.navigate(R.id.fragmentC)
        }
    }
    

Για πιο πολύπλοκη πλοήγηση με πολλαπλές καρτέλες (BottomNavigationView, DrawerLayout), θα χρησιμοποιούσα το setupWithNavController().

// Στο Activity με BottomNavigationView
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView

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

    val navController = findNavController(R.id.nav_host_fragment)
    val bottomNavView = findViewById<BottomNavigationView>(R.id.bottom_nav_view)
    bottomNavView.setupWithNavController(navController) // Σύνδεση BottomNavigationView με NavController
}

Το Navigation Component διαχειρίζεται από προεπιλογή το back stack. Το πάτημα του κουμπιού "Πίσω" θα επιστρέψει τον χρήστη στον προηγούμενο προορισμό στο back stack. Για τον έλεγχο της συμπεριφοράς του back stack κατά το navigate(), μπορεί να χρησιμοποιηθεί το NavOptions με popUpTo.