کار با AppBar

نوار بالای برنامه مکانی ثابت در امتداد بالای پنجره برنامه شما برای نمایش اطلاعات و اقدامات از صفحه فعلی فراهم می کند.

یک نمونه نوار برنامه بالا
شکل 1. نمونه نوار بالای برنامه.

مالکیت نوار برنامه بسته به نیاز برنامه شما متفاوت است. هنگام استفاده از قطعات، نوار برنامه را می توان به عنوان یک ActionBar که متعلق به فعالیت میزبان یا نوار ابزار در طرح بندی قطعه شما است، پیاده سازی کرد.

اگر همه صفحه‌های شما از نوار برنامه یکسانی استفاده می‌کنند که همیشه در بالا قرار دارد و عرض صفحه را می‌پوشاند، از نوار اقدام ارائه‌شده با موضوع که توسط فعالیت میزبانی می‌شود، استفاده کنید. استفاده از نوارهای برنامه تم به حفظ ظاهری ثابت کمک می کند و مکانی برای میزبانی منوهای گزینه و دکمه Up فراهم می کند.

اگر می‌خواهید کنترل بیشتری روی اندازه، محل قرارگیری و انیمیشن نوار برنامه در چندین صفحه داشته باشید، از نوار ابزار میزبانی شده توسط قطعه استفاده کنید. به عنوان مثال، ممکن است به یک نوار برنامه در حال جمع شدن نیاز داشته باشید یا نواری که فقط نصف عرض صفحه را بپوشاند و به صورت عمودی در مرکز قرار گیرد.

موقعیت‌های مختلف به رویکردهای متفاوتی برای مواردی مانند افزایش منوها و پاسخ به تعامل کاربر نیاز دارند. درک رویکردهای مختلف و استفاده از بهترین روش برای برنامه شما در زمان شما صرفه جویی می کند و به شما کمک می کند تا مطمئن شوید که برنامه شما به درستی کار می کند.

مثال‌های موجود در این مبحث به یک 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>

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

نوار برنامه متعلق به فعالیت

نوار برنامه معمولاً متعلق به فعالیت میزبان است. هنگامی که نوار برنامه متعلق به یک فعالیت است، قطعات می توانند با نادیده گرفتن روش های چارچوبی که در هنگام ایجاد قطعه فراخوانی می شوند، با نوار برنامه تعامل داشته باشند.

ثبت نام با فعالیت

باید به سیستم اطلاع دهید که قطعه نوار برنامه شما در جمعیت منوی گزینه ها شرکت می کند. برای انجام این کار، setHasOptionsMenu(true) را در متد onCreate(Bundle) قطعه خود فراخوانی کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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

setHasOptionsMenu(true) به سیستم می گوید که قطعه شما می خواهد تماس های مربوط به منو را دریافت کند. هنگامی که یک رویداد مرتبط با منو رخ می دهد، مانند یک کلیک، روش مدیریت رویداد ابتدا در اکتیویتی فراخوانی می شود، قبل از اینکه روی قطعه فراخوانی شود.

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

منو را باد کنید

برای ادغام منوی خود در منوی گزینه های نوار برنامه، onCreateOptionsMenu() را در قطعه خود لغو کنید. این روش منوی نوار برنامه فعلی و یک MenuInflater به عنوان پارامتر دریافت می کند. برای ایجاد نمونه ای از منوی قطعه خود از منوی بادکننده استفاده کنید و سپس آن را در منوی فعلی ادغام کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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() آیتم منوی انتخاب شده را به عنوان پارامتر دریافت می‌کند و یک Boolean برمی‌گرداند تا نشان دهد لمس مصرف شده است یا خیر. هنگامی که یک اکتیویتی یا قطعه true از onOptionsItemSelected() برمی گرداند، هیچ فرگمنت شرکت کننده دیگری پاسخ تماس را دریافت نمی کند.

در اجرای onOptionsItemSelected() از عبارت switch در itemId آیتم منو استفاده کنید. اگر مورد انتخاب شده متعلق به شماست، لمس را به طور مناسب مدیریت کنید و برای نشان دادن اینکه رویداد کلیک انجام شده است، true را برگردانید. اگر مورد انتخاب شده مال شما نیست، با اجرای super تماس بگیرید. به طور پیش فرض، اجرای super false را برمی گرداند تا پردازش منو ادامه یابد.

کاتلین

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)
        }
    }
}

جاوا

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() باعث می شود منو به درستی نمایش داده شود:

کاتلین

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

جاوا

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);
    }
}

هنگامی که نیاز به به روز رسانی منو دارید، مانند زمانی که کاربر دکمه Edit را برای ویرایش اطلاعات نمایه فشار می دهد، invalidateOptionsMenu() را در فعالیت میزبان فراخوانی کنید تا از سیستم درخواست کنید که onCreateOptionsMenu() فراخوانی کند. پس از ابطال، می توانید به روز رسانی ها را در onCreateOptionsMenu() انجام دهید. هنگامی که منو باز شد، سیستم onPrepareOptionsMenu() را فراخوانی می کند و منو را به روز می کند تا وضعیت فعلی قطعه را منعکس کند.

کاتلین

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

جاوا

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 به این روش ارسال کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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

}

برای افزایش یک منبع منوی XML دیگر، روش را دوباره با resId منوی جدید فراخوانی کنید. آیتم های منوی جدید به منو اضافه می شوند و آیتم های منوی موجود تغییر یا حذف نمی شوند.

اگر می‌خواهید مجموعه منوی موجود را جایگزین کنید، قبل از فراخوانی inflateMenu(int) با شناسه منوی جدید، منو را پاک کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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

        viewBinding.myToolbar.getMenu().clear()

    }

}

رویدادهای کلیک را مدیریت کنید

با استفاده از متد setOnMenuItemClickListener() می توانید یک OnMenuItemClickListener مستقیماً به نوار ابزار ارسال کنید. این شنونده زمانی فراخوانی می شود که کاربر یک آیتم منو را از دکمه های عملکرد ارائه شده در انتهای نوار ابزار یا سرریز مربوطه انتخاب کند. MenuItem انتخاب شده به متد onMenuItemClick() شنونده منتقل می شود و می توان از آن برای مصرف عمل استفاده کرد، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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
            }
        }
    }
}

جاوا

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 menu باید تا زمانی که کاربر شروع به ویرایش کند نامرئی باشد و با ضربه زدن دوباره ناپدید شود:

کاتلین

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

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

    }
}

جاوا

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

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

}

در صورت وجود، دکمه ناوبری در ابتدای نوار ابزار ظاهر می شود. تنظیم یک نماد ناوبری در نوار ابزار آن را قابل مشاهده می کند. همچنین می‌توانید یک onClickListener() مخصوص ناوبری تنظیم کنید که هر زمان که کاربر روی دکمه ناوبری کلیک می‌کند، فراخوانی می‌شود، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

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

جاوا

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.
            }
        });
    }
}