it-swarm.com.de

Popup-Menü in der benutzerdefinierten ListView

Was ich erreichen will:

Ich habe einen benutzerdefinierten ListView-Adapter. Zu jedem Listitem möchte ich ein Popup-Menü hinzufügen, das der ListView in der aktuellen Google Play-Anwendung sehr ähnlich ist.

Screenshot of Google Play items

Folgendes habe ich ausprobiert: Der größte Teil meines Codes stammt aus diesem Android-Beispiel samples\Android-19\ui\ActionBarCompat-ListPopupMenu

CustomFragmentPageAdapter.Java :

// create new fragment
mCustomFragment = CustomFragment.newInstance(position);

CustomFragment.Java

public class CustomFragment extends ListFragment implements View.OnClickListener{

...

@Override
public void onClick(final View v) {
    v.post(new Runnable() {
        @Override
        public void run() {
            showPopupMenu(v);
        }
    });
}

private void showPopupMenu(View view) {

    PopupMenu popup = new PopupMenu(getActivity(), view);

    popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());

    popup.show();
}

CustomArrayAdapter :

public class CustomAdapter extends ArrayAdapter<WatchListPlayerItem> {
    ...    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        final View rowView = inflater.inflate(R.layout.watch_list_row, parent, false);

        View popupButton = rowView.findViewById(R.id.imgPopUp);

        popupButton.setTag(getItem(position));

        popupButton.setOnClickListener(mFragment);

        return rowView;
    }
}

popup_menu.xml :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:id="@+id/install"
        Android:title="Install" />
    <item
        Android:id="@+id/addtowishlist"
        Android:title="Add to wishlist" />
</menu>

Logcat-Ausgabe :

Java.lang.RuntimeException: Failed to resolve attribute at index 6
            at Android.content.res.TypedArray.getLayoutDimension(TypedArray.Java:603)
            at Android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.Java:6423)
            at Android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.Java:6591)
            at Android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.Java:735)
...

Der Fehler wird bei popup.show () in meinem CustomFragment ausgelöst.

Dieser Fehler macht mich eindeutig verrückt und JEDE Hilfe zur Lösung dieses Problems wird sehr geschätzt!

9
Al0x

Ich habe endlich die Lösung für mein Problem gefunden, obwohl ich keine Erklärung dafür habe, warum diese Lösung funktioniert.

Beim folgenden Import hatte ich immer den Fehler:

import Android.support.v7.widget.PopupMenu;

Es funktioniert gut mit dem folgenden Import:

import Android.widget.PopupMenu;

Ich habe den von Ric zur Verfügung gestellten Code (Danke für die tolle Hilfe!) Und meinen eigenen getestet. Beide arbeiten jetzt. Vielleicht hat jemand eine Erklärung, warum der Import in diesem Fall wichtig ist.

36
Al0x

Erstellen Sie zuerst eine button in Ihrer custom-item-listview.xml und fügen Sie dann den folgenden Code hinzu:

Button:

<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@string/button_text"
Android:id="@+id/button1"
... />

klasse:

public class CustomAdapter extends ArrayAdapter<CustomItem> {

    private static Activity context = null;
    private final ArrayList<CustomItem> mItemsArrayList;
    private CustomFragment mFragment;


    public CustomAdapter(Activity context, ArrayList<CustomItem> itemsArrayList, CustomFragment fragment) {

        super(context, R.layout.watch_list_row, itemsArrayList);

        CustomAdapter.context = context;
        this.mItemsArrayList = itemsArrayList;
        this.mFragment = fragment;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        final View rowView = inflater.inflate(R.layout.watch_list_row, parent, false);
    final Button popUp_btn = (Button)rowView.findViewById(R.id.button1);
    popUp_btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            final PopupMenu popup = new PopupMenu(context, popUp_btn);
            popup.getMenuInflater().inflate(R.menu.context_menu, popup.getMenu());
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    int i = item.getItemId();
                    if (i == R.id.item1) {
                        //do something
                        return true;
                    }
                    else if (i == R.id.item2){
                        //do something
                        return true;
                    }
                    else if (i == R.id.item3) {
                        //do something
                        return true;
                    }
                    else {
                        return onMenuItemClick(item);
                    }
                }
            });

            popup.show();

EDIT: Das funktioniert gut für mich:

TAB1

public  class TAB1 extends Fragment {
View view;

public TAB1() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.tab1, null);


            ListView list = (ListView) view.findViewById(Android.R.id.list);
            CustomList adapter = new CustomList(getActivity());
            adapter.addAll();
            list.setAdapter(adapter);


    return view;
}

CustomList:

public class CustomList extends ArrayAdapter<YourArrayAdapter> {

private static Activity context = null;

public CustomList(Activity context) {
    super(context, R.layout.custom_listview, web);
    CustomList.context = context;
}
@Override
public View getView(final int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    final View rowView = inflater.inflate(R.layout.custom_listview, null, true);

    //your stuff here

    final Button popUp_btn = (Button)rowView.findViewById(R.id.button1);
    popUp_btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            final PopupMenu popup = new PopupMenu(context, popUp_btn);
            popup.getMenuInflater().inflate(R.menu.context_menu, popup.getMenu());
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    int i = item.getItemId();
                    if (i == R.id.item1) {
                        //do something
                        return true;
                    }
                    else if (i == R.id.item2){
                        //do something
                        return true;
                    }
                    else if (i == R.id.item3) {
                        //do something
                        return true;
                    }
                    else {
                        return onMenuItemClick(item);
                    }
                }
            });

            popup.show();

        }
    });

    return rowView;

}
5
Rick

verwenden Sie this as (Aktivitätskontext) nicht Anwendungskontext oder Kontext

     PopupMenu popup = new PopupMenu(this, v);
3
Uzair
    popup = (Button)findViewById(R.id.button);

    popup.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            PopupMenu popup = new PopupMenu(MainActivity.this,view);
            popup.getMenuInflater().inflate(R.menu.popup_menu,popup.getMenu());
            popup.show();
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    int id = item.getItemId();
                    if(id==R.id.install){
                        show_toast("Install Clicked");
                    }else{
                        show_toast("WishList Clicked");                            
                    }
                    return true;
                }
            });
        }
    });



    public void show_toast(String message){
        Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
    }

Hinweis:
Vergessen Sie nicht, dies zu importieren ....

import Android.support.v7.widget.PopupMenu;
import Android.view.MenuItem;
2
Karthick

Rick's Zeilencode funktioniert perfekt, solange Sie Folgendes importieren: 

import Android.widget.PopupMenu;

Nicht die folgende: 

import Android.support.v7.widget.PopupMenu;
1
Josi

Ich hatte gerade das gleiche Problem, als ich den übergeordneten Stil des Themes änderte: Von

<style name="MainAppTheme" parent="@style/Theme.AppCompat.Light">

zu

<style name="MainAppTheme" parent="@style/Theme.Base.AppCompat.Light">

Möglicherweise verwendet Ihre App den Style "Theme.Base", der nicht den erforderlichen 6. Parameter definiert, der von PopupMenu verwendet wird. Aus SO question Verwendung von ActionBarActivity mit Theme.Material , Theme.AppCompat erweitert Theme.Base.AppCompat

1
Philippe

Ich habe einen ähnlichen Fehler behoben, indem ich als Parameter eine statische Aktivität übergeben habe. Zum Beispiel:

static AppCompatActivity sActivity;

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

    sActivity = this;

yourLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        PopupMenu popup = new PopupMenu(sActivity, v);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.my_popup_menu, popup.getMenu());
        popup.show();
        }
   });
}

Möglicherweise ist das folgende Problem: Problem 152141

Hoffentlich hilft es Ihnen, den Android.support.v7.widget.PopupMenu-Import zu respektieren.

Grüße.

0
mlopezv86