עבודה עם AppBar

סרגל האפליקציות העליון מספקת מקום עקבי בחלק העליון של חלון האפליקציה להצגה מידע ופעולות מהמסך הנוכחי.

דוגמה לסרגל אפליקציה מוביל
איור 1. דוגמה לסרגל אפליקציה עליון.

הבעלות על סרגל האפליקציה משתנה בהתאם לצרכים של האפליקציה. מתי באמצעות מקטעים, ניתן להטמיע את סרגל האפליקציה ActionBar בבעלות לפי פעילות המארח או סרגל כלים בפריסת המקטע שלך.

אם בכל המסכים שלך נעשה שימוש באותו סרגל אפליקציות שמופיע תמיד בחלק העליון, מתפרש על רוחב המסך, ויש להשתמש בעיצוב שהוגדר סרגל פעולות שמתארח בפעילות. השימוש בסרגלי אפליקציות של עיצוב עוזר לשמור מראה עקבי ומספק מקום לשמירת תפריטי האפשרויות לחצן 'למעלה'.

להשתמש בסרגל כלים שמתארח בקטע אם רוצים יותר שליטה הגודל, המיקום והאנימציה של סרגל האפליקציה מסכים. לדוגמה, יכול להיות שתצטרכו לכווץ סרגל אפליקציות או סרגל אפליקציות, שמשתרע על פני מחצית מרוחב המסך בלבד והוא ממורכז במאונך.

במצבים שונים יש גישות שונות לדברים כמו ניפוח תפריטים ותגובה לפעולת המשתמש. הבנת ההבדלים גישה לשיטת הבידינג המתאימה ביותר לאפליקציה שלכם, והיא חוסכת לכם זמן לוודא שהאפליקציה פועלת באופן תקין.

הדוגמאות בנושא הזה מתייחסות ל-ExampleFragment שמכיל פרופיל שניתן לעריכה. המקטע מנפח את הרכיבים הבאים תפריט מוגדר-XML בסרגל האפליקציה שלו:

<!-- sample_menu.xml -->
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/ic_settings"
        android:title="@string/settings"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_done"
        android:icon="@drawable/ic_done"
        android:title="@string/done"
        app:showAsAction="ifRoom|withText"/>

</menu>

התפריט מכיל שתי אפשרויות: אחת לניווט למסך פרופיל ופרופיל אחד כדי לשמור את כל השינויים שבוצעו בפרופיל.

סרגל אפליקציות בבעלות הפעילות

בדרך כלל, סרגל האפליקציות נמצא בבעלות הפעילות של המארח. כשהאפליקציה נמצא בבעלות פעילות, מקטעים יכולים ליצור אינטראקציה עם סרגל האפליקציה על ידי שינוי של שיטות framework שנקראות במהלך יצירת מקטעים.

הרשמה לנתוני פעילות

עליך להודיע למערכת שהמקטע של סרגל האפליקציה משתתף באוכלוסייה של תפריט האפשרויות. לשם כך, התקשרו setHasOptionsMenu(true) בשיטה onCreate(Bundle) של המקטע שלך, כפי שמוצג למטה דוגמה:

Kotlin

class ExampleFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }
}

Java

public class ExampleFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
}

setHasOptionsMenu(true) מציין למערכת שהמקטע שלך רוצה לקבל שיחות חוזרות שקשורות לתפריט. כשמודעה שקשורה לתפריט אירוע מתרחש, כמו קליק, שיטת הטיפול באירוע היא בוצעה קריאה קודם לפעילות לפני שנקראה בקטע.

עם זאת, לא כדאי להסתמך על הסדר הזה בלוגיקת האפליקציה. אם אותו הדבר הפעילות מארחת מספר מקטעים, כל מקטע יכול לספק תפריט אפשרויות, במקרה כזה, סדר הקריאה החוזרת תלוי בסדר שבהם המקטעים נוספים.

מתנפח של התפריט

כדי למזג את התפריט עם תפריט האפשרויות של סרגל האפליקציות, משנים את ההגדרה onCreateOptionsMenu() במקטע שלך. השיטה הזו מקבלת את תפריט הסרגל הנוכחי של האפליקציות ו MenuInflater כפרמטרים. כדאי להשתמש ניפוח התפריט כדי ליצור מופע של תפריט המקטעים, ואז למזג אותו בתפריט הנוכחי, כפי שמוצג בדוגמה הבאה:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.sample_menu, menu)
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
       inflater.inflate(R.menu.sample_menu, menu);
    }
}

איור 2 מציג את התפריט המעודכן.

תפריט האפשרויות מכיל עכשיו את קטע התפריט
איור 2. תפריט האפשרויות מכיל עכשיו את התפריט מקטע.

טיפול באירועי קליקים

כל פעילות ומקטע שמשתתפים בתפריט האפשרויות יכולים הם מגיבים לנגיעות. הקטע onOptionsItemSelected() הפונקציה מקבלת כפרמטר את האפשרות שנבחרה בתפריט ומחזירה ערך בוליאני כדי לציין אם המגע נצרך. ברגע פעילות או מקטע מחזירים true מ-onOptionsItemSelected(), לא מקטעים אחרים המשתתפים מקבלים את הקריאה החוזרת.

בהטמעה של onOptionsItemSelected(), צריך להשתמש ב-switch פקודה בitemId של האפשרות בתפריט. אם הפריט שנבחר שלך, עליך לטפל במגע כמו שצריך ולהחזיר את המילה true כדי לציין שאירוע הקליק מטופל. אם הפריט שבחרתם לא שלכם, קראו את ההטמעה של super. כברירת מחדל, super ההטמעה מחזירה false כדי לאפשר להמשך עיבוד התפריט.

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_settings -> {
                // Navigate to settings screen.
                true
            }
            R.id.action_done -> {
                // Save profile changes.
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:  {
                // Navigate to settings screen.
                return true;
            }
            case R.id.action_done: {
                // Save profile changes.
                return true;
            }
            default:
                return super.onOptionsItemSelected(item);
        }

    }

}

שינוי התפריט באופן דינמי

למקם את הלוגיקה להסתרה או להצגה של לחצן או לשינוי הסמל בו onPrepareOptionsMenu() השיטה הזו מופעלת ממש לפני שהתפריט מוצג.

בהמשך לדוגמה הקודמת, הלחצן Save אמור להיות בלתי נראה עד שהמשתמש מתחיל לערוך, והיא אמורה להיעלם לאחר שהמשתמש שומר. הוספת הלוגיקה הזו אל onPrepareOptionsMenu() יוצרת התפריט שמוצג בצורה נכונה:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onPrepareOptionsMenu(menu: Menu){
        super.onPrepareOptionsMenu(menu)
        val item = menu.findItem(R.id.action_done)
        item.isVisible = isEditing
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onPrepareOptionsMenu(@NonNull Menu menu) {
        super.onPrepareOptionsMenu(menu);
        MenuItem item = menu.findItem(R.id.action_done);
        item.setVisible(isEditing);
    }
}

כשצריך לעדכן את התפריט, למשל כשמשתמש לוחץ על לחצן עריכה כדי לערוך את פרטי הפרופיל, מתקשרים invalidateOptionsMenu() בפעילות המארח כדי לבקש שהמערכת תפעיל קריאה ל-onCreateOptionsMenu(). אחרי הביטול אפשר יהיה לבצע את העדכונים דרך onCreateOptionsMenu(). פעם אחת התפריט מתנפח, המערכת קוראת ל-onPrepareOptionsMenu() ומעדכנת את התפריט כדי לשקף את המצב הנוכחי של הקטע.

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun updateOptionsMenu() {
        isEditing = !isEditing
        requireActivity().invalidateOptionsMenu()
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void updateOptionsMenu() {
        isEditing = !isEditing;
        requireActivity().invalidateOptionsMenu();
    }
}

סרגל אפליקציות בבעלות מקטע

אם ברוב המסכים באפליקציה אין צורך בסרגל אפליקציות, או אם יש כזה צריך סרגל אפליקציות שונה מזה של האחרים, אפשר להוסיף Toolbar אל בפריסת מקטעים. למרות שאפשר להוסיף Toolbar בכל מקום ב בהיררכיית התצוגה של מקטעים, בדרך כלל היא נשארת בחלק העליון במסך. כדי להשתמש ב-Toolbar בקטע שלך, עליך לספק מזהה קבלת הפניה אליו בקטע שלכם, כמו בכל דבר אחר צפייה. אפשר גם להוסיף אנימציה של סרגל הכלים באמצעות CoordinatorLayout והתנהגויות.

<androidx.appcompat.widget.Toolbar
    android:id="@+id/myToolbar"
    ... />

כשמשתמשים בסרגל אפליקציות בבעלות של מקטעים, Google ממליצה להשתמש Toolbar ממשקי API באופן ישיר. לא להשתמש setSupportActionBar() וממשקי ה-API של התפריט Fragment, שמתאימים רק לסרגלי אפליקציות בבעלות פעילות.

מתנפח של התפריט

שיטת הנוחות Toolbar inflateMenu(int) מקבלת את המזהה של בתור פרמטר. כדי להגדיל משאב של תפריט XML לתוך בסרגל הכלים, מעבירים את resId לשיטה הזו, כפי שמוצג בהמשך דוגמה:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        viewBinding.myToolbar.inflateMenu(R.menu.sample_menu)
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.inflateMenu(R.menu.sample_menu);
    }

}

כדי להגדיל משאב נוסף בתפריט XML, קוראים שוב ל-method עם הפונקציה resId בתפריט החדש. האפשרויות החדשות בתפריט יתווספו לתפריט. האפשרויות הקיימות בתפריט לא שונו או הוסרו.

כדי להחליף את קבוצת התפריטים הקיימת, צריך לנקות את התפריט לפני התקשרות אל inflateMenu(int) עם מזהה התפריט החדש, כמו בדוגמה הבאה דוגמה:

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun clearToolbarMenu() {
        viewBinding.myToolbar.menu.clear()
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void clearToolbarMenu() {

        viewBinding.myToolbar.getMenu().clear()

    }

}

טיפול באירועי קליקים

אפשר להעביר OnMenuItemClickListener ישירות לסרגל הכלים באמצעות setOnMenuItemClickListener() . ה-listener הזה מופעל כשהמשתמש בוחר פריט בתפריט מלחצני הפעולה שמופיעים בסוף סרגל הכלים, אפשרויות נוספות המשויכות. נבחרו MenuItem מועבר onMenuItemClick() יכול לשמש לביצוע הפעולה, כמו בדוגמה הבאה: דוגמה:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        viewBinding.myToolbar.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.action_settings -> {
                    // Navigate to settings screen.
                    true
                }
                R.id.action_done -> {
                    // Save profile changes.
                    true
                }
                else -> false
            }
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.setOnMenuItemClickListener(item -> {
            switch (item.getItemId()) {
                case R.id.action_settings:
                    // Navigate to settings screen.
                    return true;
                case R.id.action_done:
                    // Save profile changes.
                    return true;
                default:
                    return false;
            }
        });
    }
}

שינוי התפריט באופן דינמי

אם סרגל האפליקציה הוא בבעלות של המקטע שלך, אפשר לשנות את Toolbar בכתובת זמן ריצה, בדיוק כמו בכל תצוגה אחרת.

בהמשך לדוגמה הקודמת, האפשרות Save (שמירה) בתפריט אמורה להיות בלתי נראה עד שהמשתמש מתחיל לערוך, והוא אמור להיעלם שוב כשמקישים על:

Kotlin

class ExampleFragment : Fragment() {
    ...
    fun updateToolbar() {
        isEditing = !isEditing

        val saveItem = viewBinding.myToolbar.menu.findItem(R.id.action_done)
        saveItem.isVisible = isEditing

    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    public void updateToolbar() {
        isEditing = !isEditing;

        MenuItem saveItem = viewBinding.myToolbar.getMenu().findItem(R.id.action_done);
        saveItem.setVisible(isEditing);
    }

}

אם לחצן הניווט מופיע, הוא יופיע בתחילת סרגל הכלים. אם מגדירים סמל ניווט בסרגל הכלים, הוא גלוי. אפשר גם להגדיר onClickListener() ספציפי לניווט, שיתקשר בכל פעם המשתמש לוחץ על לחצן הניווט, כפי שמוצג כאן דוגמה:

Kotlin

class ExampleFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        myToolbar.setNavigationIcon(R.drawable.ic_back)

        myToolbar.setNavigationOnClickListener { view ->
            // Navigate somewhere.
        }
    }
}

Java

public class ExampleFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ...
        viewBinding.myToolbar.setNavigationIcon(R.drawable.ic_back);
        viewBinding.myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Navigate somewhere.
            }
        });
    }
}