it-swarm.com.de

Wie kann man dieses benutzerdefinierte Popup-Menü mit Material Design Android realisieren?

Ich möchte ein benutzerdefiniertes Popup-Menü wie Twitter in Android erstellen, z. B. mit Elementen und Bildern, aber ich weiß nicht, welche Komponente dafür verwendet wird. 

Google präsentiert in der Material Design-Website diese Lösung . Ich denke, es gibt eine native Lösung, um dies zu erreichen.

enter image description here

Ich habe versucht mit Popup-Menü , aber ich kann nicht finden, wie man das Layout dieser Ansicht so anpasst.

25
lopez.mikhael

sie können ein ListPopupWindow verwenden, das Ihren benutzerdefinierten Adapter übermittelt, über den Sie das Layout jeder einzelnen Zeile der ListPopupWindow steuern können. Für eine normale PopupWindow müssen Sie eine Ankersicht bereitstellen und zusätzlich setContentWidth für die Instanz von ListPopupWindow aufrufen, die die Breite des Popup-Fensters durch die Größe des Inhalts bestimmt. Es ist ein kleiner Preis, den Sie zahlen müssen, aber für einen kleinen Datensatz ist das keine große Sache. Ich habe diese Dienstprogrammmethode, um die maximale Breite der Zeile abzurufen:

public int measureContentWidth(ListAdapter adapter) {
    int maxWidth = 0;
    int count = adapter.getCount();
    final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    View itemView = null;
    for (int i = 0; i < count; i++) {
        itemView = adapter.getView(i, itemView, this);
        itemView.measure(widthMeasureSpec, heightMeasureSpec);
        maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
    }
    return maxWidth;
}
25
Blackbelt

Es gibt ein Widget namens PopupMenu, bei dem es sich im Wesentlichen um ein Menü handelt, das mit einer bestimmten Ansicht verankert ist. Ein Nachteil ist, dass standardmäßig keine Symbole angezeigt werden.

Sie können jedoch Reflection verwenden und setForceShowIcon aufrufen, um sie anzuzeigen. Der Code, den Sie benötigen, ist:

  • Da eine Variable PopupMenu an einer bestimmten Ansicht verankert ist, verfügt Ihr Element ActionBar über ein Attribut actionLayout. Dieses Layout (action_item.xml) kann so einfach sein wie:

    <Button
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        style="?attr/actionButtonStyle"
        Android:layout_gravity="center"
        Android:text="Show popup"
        Android:textStyle="bold"
        Android:textSize="12sp"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"/>
    
  • ActionBar Menüstil, der Ihren Artikel mit dem obigen Layout enthält

    <menu
        xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item
            Android:id="@+id/popup_item"
            Android:title="Show popup"
            Android:showAsAction="always"
            Android:actionLayout="@layout/action_item"/>
    </menu>
    
  • Ihr popup_menu.xml, das Layout, das Sie für Ihre PopupMenu aufpumpen

    <menu
        xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item
            Android:id="@+id/item1"
            Android:title="Item1"
            Android:icon="@mipmap/ic_launcher"/>
    </menu>
    
  • Und schließlich Code, um die Inflation durchzuführen, wenn ein ActionBar-Element angeklickt wird

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_add_item:
                PopupMenu popup = new PopupMenu(this, item.getActionView());
                MenuInflater inflater = popup.getMenuInflater();
                inflater.inflate(R.menu.popup_menu, popup.getMenu());
    
                // Use reflection to invoke setForceShowIcon
                try {
                    Field[] fields = popup.getClass().getDeclaredFields();
                    for (Field field : fields) {
                        if ("mPopup".equals(field.getName())) {
                            field.setAccessible(true);
                            Object menuPopupHelper = field.get(popup);
                            Class<?> classPopupHelper = Class
                                    .forName(menuPopupHelper.getClass().getName());
                            Method setForceIcons = classPopupHelper
                                    .getMethod("setForceShowIcon", boolean.class);
                            setForceIcons.invoke(menuPopupHelper, true);
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                popup.show();
                return true;
        }
    
        return super.onOptionsItemSelected(item);
    }
    

Beachten Sie, dass Sie für den mehrzeiligen Text in einem Menü auch eine actionLayout für Ihre Popup-Menüelemente verwenden müssen.

3
Simas

Verwenden Sie ein Pop-Up-Listenfragment . Das Schöne an Fragmenten ist, dass Sie leicht animieren (Wenn Sie Fragmente nicht verstehen, empfehle ich das erste Lesen Fragmenteinführung )

Wenn Sie vollständige Kontrolle über den Popup-Inhalt haben möchten, lesen Sie Dialogfragment .

3

Ich habe dasselbe Problem. Aber schließlich fand ich bei meiner eigenen Lösung, dass ich Ihnen meinen Code freigebe. Hoffe das wird dir helfen. 

popupWindowDogs = popupWindowDogs();
    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            // popupWindowDogs.showAsDropDown(v, -5, 0);
            popupWindowDogs().showAtLocation(v, Gravity.CENTER, 0, 0);
        }
    });
    // Detect touched area
    detector = new SimpleGestureFilter(this, this);

}

public PopupWindow popupWindowDogs()
{

    // initialize a pop up window type
    PopupWindow popupWindow = new PopupWindow(this);

    // the drop down list is a list view
    final ListView listView = new ListView(this);
    // set our adapter and pass our pop up window contents
    listView.setAdapter(dogsAdapter(popUpContents));
    // listView.setBackgroundColor(Color.DKGRAY);
    listView.setBackgroundResource(R.drawable.ss4);
    listView.setPadding(0, 0, 0, 10);
    listView.setDivider(null);
    try {

        listView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                View c = listView.getChildAt(0);
                String cc = listView.getChildAt(0).toString();
                int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight();
                /*
                 * Toast.makeText(getApplicationContext(), scrolly + "", Toast.LENGTH_SHORT)
                 * .show();
                 */}

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                    int totalItemCount) {

            }
        });
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), e.toString() + "", Toast.LENGTH_SHORT)
                .show();
    }
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View v, int arg2,
                long arg3) {
            try {

                // TODO Auto-generated method stub
                Context mContext = v.getContext();
                Swipetouch mainActivity = ((Swipetouch) mContext);
                // add some animation when a list item was clicked
                Animation fadeInAnimation = AnimationUtils.loadAnimation(v.getContext(),
                        Android.R.anim.fade_in);
                fadeInAnimation.setDuration(10);
                v.startAnimation(fadeInAnimation);
                // dismiss the pop up
                mainActivity.popupWindowDogs.dismiss();
                // get the text and set it as the button text
                String val = (String) arg0.getItemAtPosition(arg2);
                // Toast.makeText(mContext, val, Toast.LENGTH_SHORT).show();
                if (val.equals("Signup Now")) {
                    Intent ii = new Intent(getApplicationContext(), Registration.class);
                    startActivity(ii);
                    stopService(new Intent(Swipetouch.this, MyService.class));
                    stopService(new Intent(Swipetouch.this, MyService.class));
                } else if (val.equals("Login")) {
                    Intent ii = new Intent(getApplicationContext(), MyLoginActivity.class);
                    startActivity(ii);
                    stopService(new Intent(Swipetouch.this, MyService.class));

                } else if (val.equals("Exit")) {
                    finish();
                    stopService(new Intent(Swipetouch.this, MyService.class));
                } else if (val.equals("Friends")) {
                    Intent ii = new Intent(getApplicationContext(), MyLoginActivity.class);
                    startActivity(ii);
                } else if (val.equals("Exit")) {
                    stopService(new Intent(Swipetouch.this, MyService.class));
                    finish();
                }

            } catch (Exception e) {
                Toast.makeText(Swipetouch.this, e.toString(), Toast.LENGTH_SHORT).show();
            }
        }

    });
    // some other visual settings
    popupWindow.setFocusable(true);
    popupWindow.setWidth(250);
    // popupWindow.setHeight(300);
    popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);

    // set the list view as pop up window content
    // SET WALLPAPER IMAGE
    /*
     * popupWindow.setBackgroundDrawable(getWallpaper()); popupWindow.setHeight(300);
     */
    // layout.setBackgroundResource(R.drawable.sshadow);
    // layout.setBackgroundColor(Color.TRANSPARENT);
    // popupWindow.setContentView(layout);

    popupWindow.setBackgroundDrawable(new ColorDrawable(
            Android.graphics.Color.TRANSPARENT));
    popupWindow.setContentView(listView);

    return popupWindow;
}
2
parik dhakan
  try {
                    Java.lang.reflect.Field[] fields = popup.getClass().getDeclaredFields();
                    for (Java.lang.reflect.Field field : fields) {
                        if ("mPopup".equals(field.getName())) {
                            field.setAccessible(true);
                            Object menuPopupHelper = field.get(popup);
                            Class<?> classPopupHelper = Class
                                    .forName(menuPopupHelper.getClass().getName());
                            Method setForceIcons = classPopupHelper
                                    .getMethod("setForceShowIcon", boolean.class);
                            setForceIcons.invoke(menuPopupHelper, true);
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
1
Bilel Bouali

Dieser Code funktioniert in meiner App.

Versuche dies :-

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
tools:context=".LocationDetailsActivity">


<item xmlns:tools="http://schemas.Android.com/tools"
    Android:icon="@Android:drawable/ic_menu_mapmode"
    app:showAsAction="ifRoom"
    Android:title="@string/title_of_menu"
    tools:context=".LocationDetailsActivity">
    //the menu list with icon
    <menu>
        <item
            Android:id="@+id/action_map_type_normal"
            Android:orderInCategory="100"
            Android:icon="some_icon" //place your icon here
            Android:title="Vacation spots" />
        <item
            Android:id="@+id/action_map_type_satellite"
            Android:orderInCategory="100"
            Android:icon="some_icon" //place your icon here
            Android:title="Friends and family" />
        <item
            Android:id="@+id/action_map_type_hybrid"
            Android:orderInCategory="100"
            Android:icon="some_icon" //place your icon here
            Android:title="Restaurants" />
    </menu>
</item>

Sie können das Tutorial von diesen verschiedenen Anbietern durchgehen 

http://developer.Android.com/guide/topics/ui/actionbar.html

http://www.vogella.com/tutorials/AndroidActionBar/article.html

http://www.androidhive.info/2013/11/Android-working-with-action-bar/

Alle haben tolle Beispiele und Quellcode, um Ihnen zu helfen

Hoffe das hilft dir :)

1
Biswajit

Einfachere Lösung. Fügen Sie diese unmittelbar vor Ihrer .show () -Methode hinzu.

try {
  Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup");
  mFieldPopup.setAccessible(true);
  MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu);
  mPopup.setForceShowIcon(true);
} catch (Exception e) {}
0
Tommie