android: การเปลี่ยนรายการเมนูตัวเลือกโดยทางโปรแกรม


89

สามารถเปลี่ยนรายการเมนูตัวเลือกโดยใช้โปรแกรมได้หรือไม่? ใครช่วยยกตัวอย่างให้ฉันหน่อยได้ไหม

นอกจากนี้ฉันต้องการปิดการใช้งานบางรายการเพื่อไม่ให้ฟังคลิกเป็นไปได้หรือไม่?

คำตอบ:


212

สำหรับใครก็ตามที่ต้องการเปลี่ยนตัวเลือกของเมนูแบบไดนามิก:

private Menu menu;

// ...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    this.menu = menu;
    getMenuInflater().inflate(R.menu.options, menu);
    return true;
}

// ...

private void hideOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(false);
}

private void showOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(true);
}

private void setOptionTitle(int id, String title)
{
    MenuItem item = menu.findItem(id);
    item.setTitle(title);
}

private void setOptionIcon(int id, int iconRes)
{
    MenuItem item = menu.findItem(id);
    item.setIcon(iconRes);
}

8
ข้อแม้อย่างหนึ่งคือคุณต้องตรวจสอบให้แน่ใจว่าmenuได้ตั้งค่าไว้ก่อนที่จะพยายามMenuItemเอาออก ตัวอย่างเช่นหากคุณมีบางอย่างเช่นactionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS)แท็บจะโหลดก่อนเมนูดังนั้นการโทรhideOption/ showOptionภายในจะonTabSelectedทำให้เกิดข้อยกเว้นของตัวชี้ค่าว่าง
SaltyNuts

เมื่อฉันใช้item.setVisible(false);รายการจะถูกซ่อนเมื่อฉันคลิกที่เมนูเท่านั้น หากฉันใช้invalidateOptionsMenu();รายการไม่ตอบสนองต่อการคลิก ขอขอบคุณหากคุณสามารถช่วยฉันในปัญหาที่คล้ายกันที่ฉันกำลังเผชิญอยู่ stackoverflow.com/questions/54756799/…
Aliton Oliveira

@AlitonOliveira คุณควรใส่ส่วน item.setVisibility (false) ของคุณไว้ในเมธอด onCreateOptionsMenu โดยการตรวจสอบสถานะตัวแปรแฟล็กของคุณและคุณควรเปลี่ยนค่าบูลของแฟล็กและ invalidateOptionsMenu มันจะทำงาน.
Kidus Tekeste

เอกสารของsetVisibleรัฐที่คุณควรโทรหาsetEnabled(false)มิฉะนั้นรายการนี้ยังสามารถเรียกใช้ผ่านทางลัดได้
Florian Walther

34

menu.xml

  <item 
    android:id="@+id/item1"
    android:title="your Item">
  </item>

ใส่ไฟล์ java ของคุณ

  public void onPrepareOptionsMenu(Menu menu) {

    menu.removeItem(R.id.item1);
}

นี่คือสิ่งที่ฉันกำลังมองหาเพราะฉันต้องการตัดสินใจครั้งเดียวในรันไทม์ แต่ไม่จำเป็นต้องเปลี่ยนตัวเลือกหลังจากนั้น ฉันใช้: @Override บูลีนสาธารณะ onPrepareOptionsMenu (เมนูเมนู) {if (! showItemName) {menu.removeItem (R.id.itemname); } กลับจริง; }
notmystyle

20

เช่นเดียวกับที่ Nikolay กล่าวว่าทำใน onPrepareOptionsMenu ()

สำหรับรายการเมนูในแถบการดำเนินการคุณต้องยกเลิกเมนูด้วย activity.invalidateOptionsMenu();

นี่คือรายละเอียดเพิ่มเติมที่นี่ฉันจะรีเฟรช ActionBar ได้อย่างไรเมื่อ onPrepareOptionsMenu เปลี่ยนรายการเมนู


7

หากฉันต้องเปลี่ยนเนื้อหาของเมนูตัวเลือกฉันจะดำเนินการในระหว่าง onMenuOpened () สิ่งนี้ช่วยให้ฉันตรวจสอบสถานะการทำงานในขณะที่ผู้ใช้กำลังเข้าถึงเมนู

public boolean onMenuOpened(int featureid, Menu menu)
    {
        menu.clear();
        if (!editable)
        {
            MenuItem itemAdd = menu.add(0, REASSIGN, Menu.NONE, context.getString(R.string.reassign));
            MenuItem itemMod = menu.add(1, EDIT, Menu.NONE, context.getString(R.string.modify));
            MenuItem itemDel = menu.add(2, DELETE, Menu.NONE, context.getString(R.string.delete));
            itemAdd.setShortcut('0', 'a');
            itemMod.setShortcut('1', 'm');
            itemDel.setShortcut('2', 'd');
        }
        else
        {
            MenuItem itemSave = menu.add(3, SAVE, Menu.NONE, context.getString(R.string.savechanges));
            itemSave.setShortcut('0', 'S');
        }


        return true;
    }

ความคิดเห็นสองสามคำ onMenuOpened ถูกเรียกสองครั้ง var เมนูครั้งแรกเป็นโมฆะเมนู var ครั้งที่สองถูกเตรียมไว้สำหรับการใช้งาน ฉันมักจะใช้ประโยค 'if' เพื่อตรวจสอบว่าเมนู var ไม่เป็นโมฆะหรือไม่
Ksiądz Pistolet

7

ในการปิดใช้งานบางรายการ:

MenuItem item = menu.findItem(R.id.ID_ASSING_TO_THE_ITEM_IN_MENU_XML);
item.setEnabled(false);

เมื่อฉันตั้งค่าitem.setVisible(false);รายการของฉันจะซ่อนก็ต่อเมื่อฉันคลิกที่เมนู (จุดสามจุด) หากฉันใช้invalidateOptionsMenu();บางรายการไม่ตอบสนองต่อการคลิก ขอขอบคุณหากคุณสามารถช่วยฉันในปัญหาที่คล้ายกันที่ฉันกำลังเผชิญอยู่ stackoverflow.com/questions/54756799/…
Aliton Oliveira

4

โดยใช้บรรทัดต่อไปนี้ฉันได้เพิ่มค่าในเมนู

getActivity().invalidateOptionsMenu();

ลองทำงานนี้เป็นเสน่ห์สำหรับฉัน


3

ลองใช้รหัสนี้:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu=menu;
    updateMenuItems(menu);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.document_list_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    if (item.getItemId() == android.R.id.home) {
        onHomeButtonPresssed();
    }else if (item.getItemId() == R.id.action_delete) {
        useCheckBoxAdapter=false;
        deleteDocuments();
    } else if (item.getItemId() == R.id.share) {
        useCheckBoxAdapter=false;
        shareDocuments();
    } else if (item.getItemId() == R.id.action_tick) {
        useCheckBoxAdapter=true;
        onShowCheckboxes();
    }
    updateMenuItems(menu);
    return true;
}

private void updateMenuItems(Menu menu){
    if (useCheckBoxAdapter && menu != null) {
        menu.findItem(R.id.action_delete).setVisible(true);
        menu.findItem(R.id.share).setVisible(true);
        menu.findItem(R.id.action_tick).setVisible(false);
    } else {
        menu.findItem(R.id.action_delete).setVisible(false);
        menu.findItem(R.id.share).setVisible(false);
        menu.findItem(R.id.action_tick).setVisible(true);
    }
    invalidateOptionsMenu();
}

เมื่อฉันใช้invalidateOptionsMenu();รายการที่มองเห็นได้ตลอดเวลาของฉันจะหยุดทำงาน (ฉันหมายถึงรายการไม่ตอบสนองต่อการคลิก) ขอขอบคุณหากคุณสามารถช่วยฉันในปัญหาที่คล้ายกันที่ฉันกำลังเผชิญอยู่ stackoverflow.com/questions/54756799/…
Aliton Oliveira

2

คุณสามารถทำอะไรง่ายๆเหมือนที่ฉันทำ เพียงแค่เปลี่ยนข้อความเป็นสิ่งที่จำเป็นเมื่อแตะรายการเมนู ฉันจำเป็นต้องปิดและเปิดเสียงรวมถึงความสามารถในการดำเนินการโดยการสัมผัส นี่คือรหัสของฉัน:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.audioOn:
        audioOn = !audioOn;
        if (audioOn)
            item.setTitle("Audio Off");
        else
            item.setTitle("Audio On");
        return true;

    case R.id.touchOn:
        touchOn = !touchOn;
        if (touchOn)
            item.setTitle("Touch Off");
        else
            item.setTitle("Touch On");
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

audioOn และ touchOn คือบูลีนที่ตรวจสอบในส่วนอื่น ๆ ของโค้ด หวังว่านี่จะช่วยได้


ฉันจะทำแบบไดนามิกได้อย่างไร ฉันหมายถึง ... เรียกใช้บริการเว็บในการเลือกรายการตัวเลือกจากนั้นในการตอบสนองที่ประสบความสำเร็จ ... ต้องทำอย่างไร?
Narendra Singh

1

คุณสามารถทำงานให้สำเร็จได้ง่ายๆโดยดำเนินการดังนี้:

private Menu menu;

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.drive_menu, menu);
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu = menu;
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_toggle_grid) {
        handleMenuOption(id);
        return true;

    } else if(id == R.id.action_toggle_list){
        handleMenuOption(id);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void handleMenuOption(int id) {
    MenuItem item = menu.findItem(id);
    if (id == R.id.action_toggle_grid){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_list).setVisible(true);
    }else if (id == R.id.action_toggle_list){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_grid).setVisible(true);
    }
}

1

ในกรณีที่คุณมี BottomBar:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    if (mBottomBar.getCurrentTabId() == R.id.tab_more) {
        getMenuInflater().inflate(R.menu.more_menu, menu);
    }

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.preferences:
            startActivity(new Intent(this, PreferenceActivity.class));
            break;
    }

    return super.onOptionsItemSelected(item);
}

จากนั้นคุณต้องโทร:

@Override
public void onBottomBarClick(int tabId) {
    supportInvalidateOptionsMenu();
}

1

รหัส Kotlin สำหรับการเข้าถึงแถบเครื่องมือตัวเลือกรายการเมนูโดยทางโปรแกรมและเปลี่ยนข้อความ / ไอคอน, .. :

1- เรามีรายการเมนูของเราในไฟล์รายการเมนูเช่น menu.xml โค้ดตัวอย่างสำหรับสิ่งนี้:

 <?xml version="1.0" encoding="utf-8"?> 
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/balance"
      android:title="0"
      android:orderInCategory="100"
      app:showAsAction="always" />
 </menu>

2- กำหนดตัวแปรสำหรับการเข้าถึงวัตถุเมนูในคลาส:

var menu: Menu? = null

3- เริ่มต้นใน onCreateOptionsMenu:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    this.menu = menu
    return true
}

4- เข้าถึงรายการเมนูภายในรหัสของคุณหรือสนุก:

private fun initialBalanceMenuItemOnToolbar() {
var menuItemBalance = menu?.findItem(R.id.balance)
    menuItemBalance?.title = Balance?.toString() ?: 0.toString()
    // for change icon : menuWalletBalance?.icon
}

1
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.calendar, menu);
        if(show_list == true) {         

        if(!locale.equalsIgnoreCase("sk")) menu.findItem(R.id.action_cyclesn).setVisible(false);

        return true;
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.