1

background

i'm trying to allow any view to show a drop down list (not a dialog, but a list that is shown below/above the view), as shown for spinners (starting from API 11 , as shown here) .

for this, i'm using IcsListPopupWindow.java from actionBarSherlock library.

the problem

i can't get it to show a list of items well:

  1. the list doesn't show the thumb (of the scrollbar) when it get too large to be shown.

  2. when selecting an item, it sometimes has the normal selection effect, and sometimes it make a lot of gray background, as shown here:

enter image description here

the question

what am i doing wrong? i've looked at the code of IcsListPopupWindow.java and it's quite hard to understand and see what is needed and what is not.

here's my sample code:

public class MainActivity extends Activity {

    private PopupMenuAdapter mAdapter;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //prepare popup menu:
        final PopupMenuItem[] items = new PopupMenuItem[10];
        for (int i = 0; i < items.length; ++i) 
            items[i] = new PopupMenuItem(android.R.drawable.sym_def_app_icon, R.string.hello_world);
        mAdapter = new PopupMenuAdapter(this, android.R.layout.simple_list_item_1, items);
        final IcsListPopupWindow popupWindow = new IcsListPopupWindow(this, null, R.attr.popupMenuStyle);       popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.abs__menu_dropdown_panel_holo_light));
        popupWindow.setAdapter(mAdapter);
        popupWindow.setModal(true);
        popupWindow.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(final AdapterView<?> arg0, final View arg1, final int arg2, final long arg3) {
                popupWindow.dismiss();
            }
        });
        //upon clicking on a button, show the popup menu :
        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(final View v) {
                // show popup menu:
                popupWindow.setContentWidth(MainActivity.this.getWindowManager().getDefaultDisplay().getWidth() / 2);
                mAdapter.notifyDataSetChanged(); // if you change anything
                popupWindow.setAnchorView(v);
                popupWindow.show();
            }
        });
    }

    // //////////////////////////////////////////////////////////
    // PopupMenuAdapter //
    // ///////////////////
    private class PopupMenuAdapter extends ArrayAdapter<PopupMenuItem> {

        Context context;
        int layoutResourceId;
        PopupMenuItem data[] = null;

        public PopupMenuAdapter(final Context context, final int layoutResourceId, final PopupMenuItem[] data) {
            super(context, layoutResourceId, data);
            this.layoutResourceId = layoutResourceId;
            this.context = context;
            this.data = data;
        }

        @Override
        public View getView(final int position, final View convertView, final ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                final LayoutInflater inflater = ((Activity) context).getLayoutInflater();
                view = inflater.inflate(layoutResourceId, parent, false);
            }
            final PopupMenuItem pItem = data[position];
            final TextView text = (TextView) view.findViewById(android.R.id.text1);
            text.setText(pItem.textResId);
            text.setCompoundDrawablesWithIntrinsicBounds(pItem.iconResId, 0, 0, 0);
            return view;
        }
    }

    private static class PopupMenuItem {
        public int iconResId;
        public int textResId;

        public PopupMenuItem(final int iconResId, final int textResId) {
            this.iconResId = iconResId;
            this.textResId = textResId;
        }
    }
}

EDIT: i've now tried the ListPopupWindow.java file from HoloEverywhere library (and also imported just the files that it needs) , and it has the exact same problems.


EDIT: for the second problem (the selection effect), i've used my own customized listView item, which has a the next attribute for its root view:

android:background="@android:drawable/list_selector_background"

still no idea how to show the scrollbar. if i use :

mPopup.getListView().setVerticalScrollBarEnabled(true);
mPopup.getListView().setScrollbarFadingEnabled(false);

than for actionBarSherlock nothing happens, while for holoEverywhere i get an NPE :

07-03 14:28:09.359: E/AndroidRuntime(1869): java.lang.NullPointerException
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.View.onDrawScrollBars(View.java:5976)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.View.draw(View.java:6939)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.widget.AbsListView.draw(AbsListView.java:3030)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.View.draw(View.java:6936)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.ViewRoot.draw(ViewRoot.java:1529)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1265)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.os.Looper.loop(Looper.java:130)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at android.app.ActivityThread.main(ActivityThread.java:3687)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at java.lang.reflect.Method.invokeNative(Native Method)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at java.lang.reflect.Method.invoke(Method.java:507)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
07-03 14:28:09.359: E/AndroidRuntime(1869):     at dalvik.system.NativeStart.main(Native Method)
android developer
  • 114,585
  • 152
  • 739
  • 1,270

1 Answers1

0

Works nicely with HoloEverywhere :P Screenshot

package org.holoeverywhere.dropdowntest;

import org.holoeverywhere.app.Activity;
import org.holoeverywhere.widget.ListPopupWindow;
import org.holoeverywhere.widget.TextView;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class MainActivity extends Activity implements OnClickListener {
    private final class DummyAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return 500;
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.item, parent, false);
            }
            ((TextView) convertView).setText("I'm dummy item #" + position);
            return convertView;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.halfSize).setOnClickListener(this);
        findViewById(R.id.fullSize).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        ListPopupWindow lpw = new ListPopupWindow(this);
        lpw.setAdapter(new DummyAdapter());
        lpw.setAnchorView(v);
        int contentWidth = getResources().getDisplayMetrics().widthPixels;
        if (v.getId() == R.id.halfSize) {
            contentWidth /= 2;
        } else {
            // Hardcoded padding, i know
            contentWidth -= 20;
        }
        lpw.setContentWidth(contentWidth);
        lpw.show();
    }
}
Prototik
  • 935
  • 4
  • 7
  • did you have any changes compared to my sample? also, did you try putting the buttons on different locations? i've played with the drop downs on multiple locations on the screen (on the same session) and then it showed the weird selection effect. did you also try to set the items views as i did? – android developer Jul 03 '13 at 14:36
  • anyway, can you please try to achieve the same result with the class i've mentioned (of actionBarSherlock) ? i was told not to use the holoEverywhere so for the testing i only copied files i thought are needed from there. maybe something just broke with it. – android developer Jul 03 '13 at 21:18
  • IcsListPopupWindow - internal class of ABS. You shouldn't use it /or anything from internal package/. Also some part of framework (eg. ListPopupWindow) implicitly depends on other parts of framework. /Just/ coping of files not fully correct. First try with full version of library, then copy needed files. – Prototik Jul 04 '13 at 01:51