मेनू बटन वाले उपकरणों पर अतिप्रवाह मेनू के उपयोग को कैसे मजबूर करें


159

मैं उन सभी मेनू आइटमों को पसंद करना चाहूंगा, जो ActionBar में फिट नहीं होते हैं, वे ओवरफ़्लो मेनू में जाते हैं (एक जो एक्शन बार से मेन्यू बटन तक नहीं पहुंचता है) यहां तक ​​कि उन डिवाइसों पर भी, जिनमें मेनू बटन होता है । यह उपयोगकर्ताओं के लिए उन्हें एक अलग मेनू सूची में फेंकने की तुलना में बहुत अधिक सहज लगता है, जिसके लिए उपयोगकर्ता को एक टच (स्क्रीन) इंटरैक्शन से बटन आधारित इंटरैक्शन में कूदने की आवश्यकता होती है, क्योंकि एक्शनबार का लेआउट उन्हें बार पर फिट नहीं कर सकता है।

एमुलेटर पर मैं "हार्डवेयर बैक / होम कीज़" मान "नहीं" पर सेट कर सकता हूं और यह प्रभाव प्राप्त कर सकता हूं। मैंने एक वास्तविक डिवाइस के लिए कोड में ऐसा करने का तरीका खोजा है जिसमें मेनू बटन है, लेकिन ठीक नहीं हो सकता। क्या कोई मेरी मदद कर सकता है?

जवाबों:


54

संपादित करें: भौतिक मेनू बटन की स्थिति के लिए उत्तर देने के लिए संशोधित।

यह वास्तव में डिजाइन द्वारा रोका गया है। Android डिज़ाइन गाइड की संगतता अनुभाग के अनुसार ,

"... एक्शन ओवरफ़्लो मेनू हार्डवेयर कुंजी से उपलब्ध है। परिणामी एक्शन पॉपअप ... स्क्रीन के निचले भाग में प्रदर्शित होता है।"

आप स्क्रीनशॉट में ध्यान देंगे, फिजिकल मेन्यू बटन वाले फोन में एक्शनबार में ओवरफ्लो मेनू नहीं है। यह उपयोगकर्ता के लिए अस्पष्टता से बचा जाता है, अनिवार्य रूप से सटीक एक ही मेनू खोलने के लिए दो बटन उपलब्ध हैं।

उपकरणों में निरंतरता के मुद्दे को संबोधित करने के लिए: अंततः यह उपयोगकर्ता के अनुभव के लिए अधिक महत्वपूर्ण है कि आपका ऐप एक ही डिवाइस पर हर दूसरे ऐप के साथ लगातार व्यवहार करता है, क्योंकि यह सभी डिवाइसों में स्वयं के साथ लगातार व्यवहार करता है।


1
अलेक्जेंडर - नहीं, मैंने शोएशन के सभी मूल्यों और कई संयोजनों की कोशिश की है और उनमें से कोई भी चाल (कम से कम एमुलेटर पर) नहीं करता है। यदि मैं मेनू बटन के बिना किसी डिवाइस का अनुकरण करता हूं, तो एक्शन बार पर ओवरफ्लो मेनू केवल दिखाता है । मुझे लगता है कि खड़ी अंडाकार देखना चाहते हैं और आइटम बह निकला उपकरणों पर वहां प्रदर्शित किया है के साथ एक मेनू बटन। मैंने अपना प्रश्न संपादित किया है ताकि थोड़ा स्पष्ट हो सके।
पॉलप

41
आइए इस वार्तालाप में कदम रखें और चर्चा करें: मुझे पता है कि इसे डिज़ाइन द्वारा रोका गया है (मैं डिज़ाइन दिशानिर्देशों को पढ़ता हूं)। लेकिन ऐसा लगता है कि $% /% # +, मुझे लगता है। उदाहरण के लिए: उपयोगकर्ता गैलेक्सी नेक्सस (-> w ओवरफ्लो) से नेक्सस वन (w 4.0 / -> नो ओवरफ्लो) पर स्विच कर रहा है। मुझे यकीन है कि उपयोगकर्ता को अब मेनू आइटम नहीं मिलेंगे। इस कारण से मैं सभी उपकरणों के लिए समान उपयोग चाहता हूं। तो, मैं एक ही समस्या के साथ समाप्त कर रहा हूँ paulp। क्या कोई स्वच्छ वर्कअराउंड उपलब्ध नहीं है?
स्प्रीगग

10
मैंने भी पहले Design Guide को पढ़ा। मेरे लिए यह समर्थन पैकेज में डिजाइन का एक बुरा विकल्प था। उपयोगकर्ताओं को बटन से अवगत कराने के लिए एक बेहतर रणनीति (उद्देश्य, सही?) इसे बेमानी बनाने के लिए होगी, स्क्रीन पर और साथ ही बटन पर कार्यक्षमता डालनी होगी। जैसा कि चीजें अब हैं, बटन सभी मेनू विकल्पों को सूचीबद्ध नहीं करता है, केवल उन पर नहीं जो एक्शनबार पर हैं, इसलिए यह डिज़ाइन न तो एक्शनबार को एक चिकनी संक्रमण का समर्थन करता है और न ही यह करता है कि एक्शनबार जोड़ने से पहले यह क्या करता था ( सभी मेनू प्रदर्शित करें विकल्प)। मुझे संदेह है कि आप सही हैं और कोई सरल समाधान नहीं है।
पॉल

18
Google अपने नए Google + ऐप्स में इसके विरुद्ध जाता है। यह डिवाइस की परवाह किए बिना आइटम को ओवरफ्लो करता है .. फिर भी वे डेवलपर्स को ऐसा करने से रोकते हैं और इसके खिलाफ सलाह देते हैं, मेरी जानकारी के लिए।
कार्ल

10
ईमानदारी से, मैंने देखा है कि बहुत से उपयोगकर्ताओं ने कभी भी उनसे उम्मीद करने के लिए मेनू हार्ड की कोशिश नहीं की। यदि डिज़ाइन कहता है कि किसी भी फोन पर किसी भी उपयोगकर्ता के पास स्क्रीन संकेतक नहीं होना चाहिए जो मेनू विकल्प मौजूद है, तो वह डिज़ाइन खराब सूचना है।
लांस नानक

323

आप यहाँ इस छोटी सी हैक का उपयोग कर सकते हैं:

try {
    ViewConfiguration config = ViewConfiguration.get(this);
    Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
    if (menuKeyField != null) {
        menuKeyField.setAccessible(true);
        menuKeyField.setBoolean(config, false);
    }
} catch (Exception ignored) {
}

इसे लगाने के लिए अच्छी जगह onCreateआपके एप्लिकेशन वर्ग की -Method होगी ।

यह एप्लिकेशन को अतिप्रवाह मेनू दिखाने के लिए मजबूर करेगा। मेनू बटन अभी भी काम करेगा, लेकिन यह शीर्ष दाएं कोने में मेनू खोल देगा।

[संपादित करें] चूंकि अब यह कई बार आ चुका है: यह हैक केवल एंड्रॉइड 3.0 में शुरू किए गए देशी ActionBar के लिए काम करता है, ActionBarSherlock नहीं। बाद वाला अपने स्वयं के आंतरिक तर्क का उपयोग करता है यह तय करने के लिए कि अतिप्रवाह मेनू को दिखाना है या नहीं। यदि आप ABS का उपयोग करते हैं, तो सभी प्लेटफार्मों <4.0 को ABS द्वारा नियंत्रित किया जाता है और इस प्रकार इसके तर्क के अधीन हैं। हैक अभी भी एंड्रॉइड 4.0 या उससे अधिक वाले सभी उपकरणों के लिए काम करेगा (आप एंड्रॉइड 3.x को सुरक्षित रूप से अनदेखा कर सकते हैं, क्योंकि मेनू बटन के साथ वास्तव में कोई टैबलेट नहीं है)।

इसमें एक विशेष ForceOverflow-Theme मौजूद है जो मेनू को ABS में बाध्य करेगा, लेकिन भविष्य में जटिलताओं के कारण इसे भविष्य के संस्करणों में हटा दिया जाएगा


4
मैंने सोर्स कोड के माध्यम से देखा। अनिर्दिष्ट सुविधाओं का खज़ाना :) बस यह सुनिश्चित करें कि आपके पास इस तरह की चीजों के लिए एक व्यावहारिक वापसी है।
टिमो ओह्र

4
आपका बहुत बहुत धन्यवाद! यह वास्तव में बहुत अच्छा है। मैं समीक्षा करना चाहता था, बग्रेपोर्ट और कार्रवाई को अतिप्रवाह में साझा करना चाहता था, लेकिन यह नेक्सस एस पर नहीं दिख रहा था। उपयोगकर्ता मेनू बटन पर भी क्लिक नहीं करेंगे। ओवरफ्लो के साथ उपयोगकर्ता देखता है कि अतिरिक्त क्रियाएं उपलब्ध हैं।
यूरी कुलिकोव

4
@Ewoks मैं यहाँ टिप्पणी पर बहुत देर हो चुकी हूँ, लेकिन मैंने अभी ActionBarCompat के सबसे हाल के संस्करण के साथ यह कोशिश की, और यह काम किया।
जकॉफिनेटेड

3
यह सैमसंग गैलेक्सी एस 3 और एस 4 पर काम करता है, लेकिन एलजी जी 2 पर नहीं (संदेह है कि वे अतिप्रवाह मेनू बटन दिखाने के लिए चेक को हार्ड कोडिंग कर रहे हैं)
डीवीडी

18
सुंदर! ग्रहण के लिए से चुनने के लिए 6 अलग आयात की तरह आप देता है Fieldयह एक का चयन java.lang.reflect.Field);
डर मर्वे यूजीन वैन

35

मैं इस तरह से अपने मेनू को परिभाषित करके इसका उपयोग करने का उपयोग करता हूं (मेरे उदाहरण में उपयोग किए गए ActionBarSherlock आइकन के साथ भी):

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

    <item
        android:id="@+id/menu_overflow"
        android:icon="@drawable/abs__ic_menu_moreoverflow_normal_holo_light"
        android:orderInCategory="11111"
        android:showAsAction="always">
        <menu>
            <item
                android:id="@+id/menu_overflow_item1"
                android:showAsAction="never"
                android:title="@string/overflow_item1_title"/>
            <item
                android:id="@+id/menu_overflow_item2"
                android:showAsAction="never"
                android:title="@string/overflow_item2_title"/>
        </menu>
    </item>

</menu>

मैं मानता हूं कि आपके xml में मैनुअल "अतिप्रवाह-प्रबंधन" की आवश्यकता हो सकती है, लेकिन मुझे यह समाधान उपयोगी लगा।

आप अपनी गतिविधि में, अतिप्रवाह मेनू को खोलने के लिए HW बटन का उपयोग करने के लिए डिवाइस को बाध्य कर सकते हैं:

private Menu mainMenu;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // TODO: init menu here...
    // then:
    mainMenu=menu;
    return true;
}

@Override
public boolean onKeyUp(int keycode, KeyEvent e) {
    switch(keycode) {
        case KeyEvent.KEYCODE_MENU:
            if (mainMenu !=null) {
                mainMenu.performIdentifierAction(R.id.menu_overflow, 0);
            }
    }

    return super.onKeyUp(keycode, e);
}

:-)


2
कैसे अतिप्रवाह मेनू खोलने के लिए HW बटन का उपयोग करें?
ब्लेडफ्यू

1
HW बटन के साथ अतिप्रवाह मेनू खोलने के लिए मेरा अद्यतन उत्तर देखें। :)
बेरोक

11

यदि आप समर्थन लाइब्रेरी से एक्शन बार का उपयोग कर रहे हैं ( android.support.v7.app.ActionBar), निम्नलिखित का उपयोग करें:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:yorapp="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/menu_overflow"
        android:icon="@drawable/icon"
        yourapp:showAsAction="always"
        android:title="">
        <menu>
            <item
                android:id="@+id/item1"
                android:title="item1"/>
            <item
                android:id="@+id/item2"
                android:title="item2"/>
        </menu>
    </item>

</menu>

समर्थन पुस्तकालय का उपयोग करते समय मैंने इसे भी लागू किया और यह प्री और पोस्ट 3.0 डिवाइस दोनों पर ठीक काम करता है
लीफकटर

7

इस तरह की विधि को Android Developers Design System द्वारा रोका जाता है, लेकिन मुझे इसे पास करने का एक तरीका मिला:

इसे अपनी XML मेनू फ़ाइल में जोड़ें:

<item android:id="@+id/pick_action_provider"
    android:showAsAction="always"
    android:title="More"
    android:icon="@drawable/ic_action_overflow"
    android:actionProviderClass="com.example.AppPickActionProvider" />

अगला, 'AppPickActionProvider' नाम का एक वर्ग बनाएं, और इसके लिए निम्न कोड कॉपी करें:

    package com.example;

import android.content.Context;
import android.util.Log;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.view.View;

public class AppPickActionProvider extends ActionProvider implements
        OnMenuItemClickListener {

    static final int LIST_LENGTH = 3;

    Context mContext;

    public AppPickActionProvider(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    public View onCreateActionView() {
        Log.d(this.getClass().getSimpleName(), "onCreateActionView");

        return null;
    }

    @Override
    public boolean onPerformDefaultAction() {
        Log.d(this.getClass().getSimpleName(), "onPerformDefaultAction");

        return super.onPerformDefaultAction();
    }

    @Override
    public boolean hasSubMenu() {
        Log.d(this.getClass().getSimpleName(), "hasSubMenu");

        return true;
    }

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        Log.d(this.getClass().getSimpleName(), "onPrepareSubMenu");

        subMenu.clear();

        subMenu.add(0, 1, 1, "Item1")
        .setIcon(R.drawable.ic_action_home).setOnMenuItemClickListener(this);

        subMenu.add(0, 2, 1, "Item2")
            .setIcon(R.drawable.ic_action_downloads).setOnMenuItemClickListener(this);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch(item.getItemId())
        {
            case 1:

                // What will happen when the user presses the first menu item ( 'Item1' )

                break;
            case 2:

                // What will happen when the user presses the second menu item ( 'Item2' )

                break;

        }

        return true;
    }
}

इस विधि का उपयोग करने और केवल एक सबमेनू का उपयोग करने के बीच अंतर क्या है, जैसा कि यहां दिखाया गया है: stackoverflow.com/a/14634780/878126 ?
Android डेवलपर

5

वैसे मुझे लगता है कि अलेक्जेंडर लुकास ने (दुर्भाग्य से) सही उत्तर प्रदान किया है इसलिए मैं इसे "सही" के रूप में चिह्नित कर रहा हूं। वैकल्पिक उत्तर जो मैं यहां जोड़ रहा हूं , वह है कि एंड्रॉइड डेवलपर्स ब्लॉग में इस पोस्ट पर किसी भी नए पाठकों को इंगित करने के लिए विषय के बजाय कुछ विशिष्ट सुझावों के साथ विषय की पूरी चर्चा के रूप में पूर्व-स्तर 11 से संक्रमण करते समय अपने कोड से कैसे निपटें नए एक्शन बार में।

मुझे अभी भी विश्वास है कि यह एक डिज़ाइन की गलती थी, मेनू बटन में निरर्थक "एक्शन ओवरफ़्लो" बटन के रूप में व्यवहार नहीं किया गया था मेनू बटन सक्षम डिवाइसों को उपयोगकर्ता के अनुभव को बदलने के लिए एक बेहतर तरीका है, लेकिन इस बिंदु पर पुल के नीचे इसका पानी।


मैं डिजाइन की गलती के बारे में आपके साथ पूरी तरह सहमत हूं - और इस निराशा को पा रहा हूं!
बजे पॉल हुननिसेट

1
मैं इस पर आपसे सहमत होता, अगर यह इस तथ्य के लिए नहीं था कि Google ने अपने हालिया G + ऐप में उस नियम का उल्लंघन करना शुरू कर दिया था। और ठीक ही तो है। मेनू बटन विरासत नहीं है, यहां तक ​​कि एसजीएस 3 जैसे नए उपकरणों में भी है। यह यहाँ रहने के लिए है, दुर्भाग्य से। और यह गंभीरता से प्रयोज्यता को बाधित करता है।
टिमो ओह्र

4

मुझे यकीन नहीं है कि यह वही है जो आप खोज रहे हैं, लेकिन मैंने एक्शनबार के मेनू के भीतर एक सबमेनू बनाया और इसके आइकन को ओवरफ्लो मेनू के आइकन से मिलान करने के लिए सेट किया। यद्यपि यह अभ्यस्त आइटमों को स्वचालित रूप से इसे भेजा जाता है, (IE आपको यह चुनना होगा कि हमेशा क्या दिखाई दे रहा है और क्या हमेशा बह निकला है) यह मुझे लगता है कि यह दृष्टिकोण आपकी मदद कर सकता है।


2

ICS प्री-इंस्टॉल के साथ आने वाले gmail ऐप में, मेनू बटन को निष्क्रिय कर दिया जाता है जब आपके पास कई आइटम चयनित होते हैं। ओवरफ्लो मेनू यहाँ "मजबूर" है जिसे भौतिक मेनू बटन के बजाय ओवरफ्लो बटन के उपयोग से चालू किया जा सकता है। Theres एक 3-पार्टी lib जिसे ActionBarSherlock कहा जाता है, जो आपको अतिप्रवाह मेनू को "मजबूर" करने देता है। लेकिन यह केवल एपीआई स्तर 14 या उससे कम (प्री-आईसीएस) पर काम करेगा


2

यदि आप टूलबार का उपयोग करते हैं , तो आप सभी संस्करणों और सभी उपकरणों पर अतिप्रवाह दिखा सकते हैं, मैंने कुछ 2.x उपकरणों पर कोशिश की है, यह काम करता है।


1

क्षमा करें यदि यह समस्या मृत है।

यहाँ मैंने त्रुटि को हल करने के लिए क्या किया। मैं लेआउट में गया और टूलबार वाले दो बनाए। एक sdk संस्करण 8 के लिए एक लेआउट था और दूसरा sdk संस्करण 21 के लिए था। 8 संस्करण पर, मैंने android.support.v7.widget.Toolbar का उपयोग किया, जबकि मैंने sdk 21 लेआउट पर android.widget.Toolbar का उपयोग किया।

फिर मैं अपनी गतिविधि में टूलबार को बढ़ाता हूं। मैं यह देखने के लिए sdk की जांच करता हूं कि क्या यह 21 या अधिक था। मैं फिर संबंधित लेआउट को फुलाता हूं। यह हार्डवेयर बटन को आपके द्वारा वास्तव में डिज़ाइन किए गए टूलबार पर मैप करने के लिए मजबूर करता है।


0

नए का उपयोग करने वाले किसी के लिए Toolbar:

private Toolbar mToolbar;

@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);

    ...
}


@Override
public boolean onKeyUp(int keycode, KeyEvent e) {
    switch(keycode) {
        case KeyEvent.KEYCODE_MENU:
            mToolbar.showOverflowMenu();
            return true;
        }

    return super.onKeyUp(keycode, e);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.