รายการเมนู Android 4.3 showAsAction = ละเว้น "เสมอ"


116

ฉันใช้ไลบรารี v7 appcompat ใหม่ที่มีให้ตั้งแต่ Android 4.3 (API ระดับ 18)

ไม่ว่าจะระบุไว้ใน showAsAction สำหรับรายการเมนูใดก็ตามจะไม่แสดง - โดยจะสร้างไอคอนเมนูรายการเพิ่มเติมเสมอและใส่แม้แต่รายการเมนูเดียวไว้ใต้เมนู

พยายามเพิ่มเมนูในกิจกรรมเช่นนี้:

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

และนี่คือเมนู xml ของฉัน:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

มันเป็นบั๊กของไลบรารีการสนับสนุน v7 ใหม่หรือมีอะไรผิดปกติกับโค้ด? ฉันเคยใช้รหัสที่คล้ายกันนี้กับ ActionBarSherlock หลายครั้งก่อนหน้านี้


2
เพื่อจุดประสงค์ในการให้ข้อมูล - "... "always"ไม่แนะนำให้ใช้"ifRoom"และปล่อยให้ระบบปฏิบัติการตัดสินใจจะดีกว่า"
ChiefTwoPencils

คำตอบ:


313

อาจเป็นไปได้ว่าคุณไม่มีเนมสเปซที่จำเป็น:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:[yourapp]="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        [yourapp]:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

แทนที่[yourapp]ด้วยชื่อแอปของคุณหรือเนมสเปซที่คุณต้องการได้ทุกที่

สิ่งอื่น ๆ ที่ควรตรวจสอบ:

  • ดูว่าชั้นกิจกรรมของคุณขยายออกไปหรือไม่ ActionBarActivity

ตรวจสอบว่าปัญหายังคงมีอยู่หรือไม่


เอกสารอ้างอิง Android: การเพิ่มปุ่มปฏิบัติการ นี่คือข้อความที่เกี่ยวข้อง:

หากแอปของคุณใช้ไลบรารีการสนับสนุนสำหรับความเข้ากันได้ในเวอร์ชันต่ำสุดที่เป็น Android 2.1 แอตทริบิวต์ showAsAction จะใช้ไม่ได้จาก android: namespace แต่แอตทริบิวต์นี้มีให้โดย Support Library และคุณต้องกำหนดเนมสเปซ XML ของคุณเองและใช้เนมสเปซนั้นเป็นคำนำหน้าแอตทริบิวต์ (เนมสเปซ XML ที่กำหนดเองควรเป็นไปตามชื่อแอปของคุณ แต่อาจเป็นชื่อใดก็ได้ที่คุณต้องการและสามารถเข้าถึงได้ภายในขอบเขตของไฟล์ที่คุณประกาศเท่านั้น)


2
นั่นคือสิ่งที่ฉันค้นพบเช่นกัน ขอบคุณ - รับแน่นอน แต่ showAsAction ควรใช้เนมสเปซที่กำหนดเองนั้น
Mcingwe

5
'yourapp' หมายถึงใน String.xml <string name = "app_name"> yourapp </string> ใช่ไหม
LOG_TAG

4
ใครช่วยอธิบายได้ไหมว่าทำไมถึงได้ผล เหตุใดจึงจำเป็นต้องขยายเนมสเปซที่กำหนดเอง สับสนเล็กน้อย
รับประทานอาหาร

8
@dineth appcompat ใช้เป็นโครงการห้องสมุด ซึ่งหมายความว่าทรัพยากรทั้งหมด (สตริง, drawable, แอตทริบิวต์ ... ) จะถูกประกาศในเนมสเปซแอปพลิเคชันของคุณแทนที่จะเป็นเนมสเปซ Android เนื่องจากไม่มีshowAsActionแอตทริบิวต์ใน Android-7 คุณต้องใช้เนมสเปซแอปของคุณ
nicopico

22
ทุกคนพูดว่า "เนมสเปซที่กำหนดเอง" หรือ "เนมสเปซที่ตรงกับแอปของคุณ" แต่เนมสเปซจะอยู่http://schemas.android.com/apk/res-autoในทุกตัวอย่างเสมอ นั่นไม่ใช่แบบกำหนดเองหรือแบบที่ตรงกับแอปของคุณ นั่นคือเนมสเปซที่แท้จริงจากเอกสารประกอบ ฉันคิดว่าทุกคนหมายถึงคำนำหน้าแบบกำหนดเองและจริงๆแล้วอาจเป็นอะไรก็ได้ที่คุณต้องการ นี่คือเรื่องจริง?
Andrew Arnott

52

คิดออกเอง. ด้วยไลบรารีการสนับสนุน v7 showAsAction ควรอยู่ภายใต้เนมสเปซที่กำหนดเองดังนี้:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:balloonberry="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        balloonberry:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

1
'balloonberry' หมายถึงใน String.xml "<string name =" app_name "> balloonberry </string>" ใช่ไหม
LOG_TAG

5
@LOG_TAG - ไม่ควรเป็นตามที่ป้อนด้านบน นี่ไม่ใช่สตริง แต่เป็นเนมสเปซ
BeccaP

ohhh support v7 errr ... มันใช้ได้กับการสนับสนุน v4
Yasitha Waduge

ขอบคุณสำหรับคำอธิบาย Mcingwe
Sachidananda Naik

32

ตรวจสอบให้แน่ใจว่าคุณใช้ Inflater ที่ถูกต้องในเมธอด ActionBarActivity.onCreateOptionsMenu ()

วิธีแก้ไขที่ถูกต้อง:

MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_example, menu);

วิธีแก้ปัญหาไม่ถูกต้อง:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);

1
ฉันได้ส่งคำตอบข้างต้นทั้งหมดและคำตอบอื่น ๆ ใน stackoverflow แต่สิ่งเดียวที่ฉันขาดหายไปคือคุณตอบ - getMenuInflater () ขอบคุณสำหรับการแบ่งปันสิ่งนี้
87

ขอบคุณมากสำหรับสิ่งนี้ ฉันแปลงเมนูทั้งหมดกว่า 100 เมนูเพื่อใช้เนมสเปซที่กำหนดเองและ 1 หน้าจอที่เหม็นยังไม่ทำงาน ... ปรากฎว่า 1 กิจกรรมใช้ "MenuInflater ใหม่" แทน getMenuInflater () ขอบคุณมาก!
DiscDev

สิ่งนี้สำคัญมาก ฉันใช้การสร้าง menuInflater (2 ทาง) ขอบคุณ
wtk

24

สำหรับFragments

เมนูที่มีเนมสเปซแบบกำหนดเองจะป้องกันไม่ให้ showAsAction แสดง

การใช้คำนำหน้า "android:" สำหรับ showAsAction จะได้ผลแม้ว่า Android Studio จะตั้งข้อสังเกตว่าคุณควรใช้พื้นที่ชื่อที่กำหนดเอง

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_add_checkin"
          android:title="Add Checkin"
          android:orderInCategory="10"
          android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add"/>
</menu>

นี่คือการใช้ Android SDK 22 และ Support v4 fragments ในกรณีที่สร้างความแตกต่าง


นั่นเป็นสิ่งเดียวที่แก้ไขปัญหาของฉัน (แม้ว่าจะแสดงข้อผิดพลาดนี้) ขอบคุณ!
user2630165

3
คุณสามารถระงับข้อผิดพลาด / คำเตือนในเค้าโครง XML ได้ด้วยเครื่องมือ: ละเว้น = "AppCompatResource" ภายใน <item> เอกสารที่นี่: tools.android.com/tips/lint/suppressing-lint-warnings
Baker

คำตอบของคุณและ Anton Kizema เป็นคำตอบที่เหมาะสมสำหรับฉัน tools:ignoreและยังขอบคุณสำหรับเคล็ดลับ
hata

16

มีปัญหาเดียวกัน แต่ใน Android 5 ฉันมี 3 รายการ แต่ OS ไม่สนใจแอตทริบิวต์ "always" ของฉันและแสดงเพียง 2 รายการ นี่คือทางออกของฉัน:

  @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    Log.d(TAG, "onCreateOptionsMenu()");
    inflater.inflate(R.menu.your_menu, menu);
    for (int j = 0; j < menu.size(); j++) {
        MenuItem item = menu.getItem(j);
        Log.d(TAG, "set flag for " + item.getTitle());
        item.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
    }
}

1
setShowAsActionFlags()ต้องใช้ API 14 แต่นี่ก็ยังเป็นทางออกที่ดีที่สุดสำหรับฉัน
Mr. Bungle

6

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

ฉันมี

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:myapp="http://schemas.android.com/res-auto">

แทน

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:myapp="http://schemas.android.com/apk/res-auto">

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


6

ในกรณีของฉันฉันต้องลบ build.gradle compile ของแอปของฉัน 'com.android.support:appcompat-v7:21.0.3'

หมายเหตุ : sdk ขั้นต่ำของฉัน = 14 และโปรเจ็กต์ที่สร้างโดย android studio แทรกการพึ่งพาที่ไม่จำเป็นของฉัน

หลังจากการแทนที่นี้คุณสามารถเขียน android: showAsAction = "always"


ขอบคุณที่ช่วยแก้ปัญหาให้ฉัน! วันนี้อาจเป็นทางออกที่ดีที่สุดในกรณีส่วนใหญ่เนื่องจากไม่จำเป็นต้องรองรับ Android เวอร์ชันก่อน 4.0
pinyin_samu

คำตอบของคุณและ Baker เป็นคำตอบที่เหมาะสมสำหรับฉัน
hata

4

นี่อาจไม่ใช่กรณีของคุณ แต่ฉันใช้

new MenuInflater(this).inflate(R.menu.my_menu, menu);

เปลี่ยนเป็น

getMenuInflater().inflate(R.menu.my_menu, menu);

แก้ไขปัญหา!


0
<?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/back"
        android:icon="@drawable/back"
        app:showAsAction="always"
        android:title="@string/back"/>
    <item
        android:id="@id/save"
        android:icon="@drawable/le_top_btn_icon_add"
        app:showAsAction="ifRoom"
        android:title="@string/save"/>
</menu>

ไม่ทำงานด้วย supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

ดู "คำเตือน"

ควรใช้ app: showAsAction กับไลบรารี appcompat ด้วย xmlns: app = "http://schemas.android.com/apk/res-auto" น้อยกว่า ... (Ctrl + F1)

เมื่อใช้ไลบรารี appcompat ทรัพยากรเมนูควรอ้างถึง showAsAction ในแอป: namespace ไม่ใช่ android: namespace

ในทำนองเดียวกันเมื่อไม่ได้ใช้ไลบรารี appcompat คุณควรใช้แอตทริบิวต์ android: showAsAction

ฉันคิดว่าคำเตือนสามารถเพิกเฉยได้


0

เพิ่มเนมสเปซที่กำหนดเองเช่นนี้เพื่อ showAsAction และ actionViewClass:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
    android:title="@string/search"
    android:icon="@drawable/ic_search"
    app:showAsAction="collapseActionView|ifRoom"
    app:actionViewClass="android.widget.SearchView" />


0

ฉันได้แก้ไขโดยการแทนที่

android:showAsAction="ifRoom"

กับ

app:showAsAction="ifRoom"

นั่นคือmenuitme xml มีลักษณะดังนี้

<item android:id="@+id/action_refresh"
      android:title="Refresh"
      android:icon="@drawable/refresh2"
      app:showAsAction="ifRoom" />

0

วิธีที่ง่ายที่สุดคือแก้ไขรหัสของคุณโดยการเพิ่ม

xmlns:app="http://schemas.android.com/apk/res-auto"

และเปลี่ยนรหัสนี้

android:showAsAction="always"

ถึง

app:showAsAction="always"

และในที่สุดก็

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        app:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.