Custom ListView and context menu. How to get it? Custom ListView and context menu. How to get it? android android

Custom ListView and context menu. How to get it?


I got solution, my friend helped me! Hope this information will helpful to someone.This is complete class code with ArrayAdapter and complex list layout and context menu.

   public class ComplexListActivity extends ListActivity {    /**     * Called when the activity is first created.     */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setListAdapter(new ComplexObjectAdapter(this, R.layout.item, getComplexObjects()));        registerForContextMenu(getListView());    }    private List getComplexObjects() {        List<ComplexObject> list = new ArrayList<ComplexObject>();        list.add(new ComplexObject("1", "1", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("2", "2", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("3", "3", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("4", "4", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("5", "5", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("6", "6", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("7", "7", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("8", "8", getResources().getDrawable(R.drawable.icon)));        list.add(new ComplexObject("9", "9", getResources().getDrawable(R.drawable.icon)));        return list;    }    @Override    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {        MenuInflater inflater = getMenuInflater();        inflater.inflate(R.menu.context_menu, menu);    }    @Override    public boolean onContextItemSelected(MenuItem item) {        AdapterView.AdapterContextMenuInfo info;        try {            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();        } catch (ClassCastException e) {            Log.e("", "bad menuInfo", e);            return false;        }        long id = getListAdapter().getItemId(info.position);        Log.d("", "id = " + id);        Toast.makeText(this, "id = " + id, Toast.LENGTH_SHORT).show();        return true;    }    private class ComplexObjectAdapter extends ArrayAdapter<ComplexObject> implements View.OnCreateContextMenuListener {        private List<ComplexObject> objects;        public ComplexObjectAdapter(Context context, int textViewResourceId, List<ComplexObject> objects) {            super(context, textViewResourceId, objects);            this.objects = objects;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            View v = convertView;            if (v == null) {                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);                v = vi.inflate(R.layout.item, null);            }            final ComplexObject o = objects.get(position);            if (o != null) {                TextView textlInfo = (TextView) v.findViewById(R.id.info);                textlInfo.setText(o.getName());                ImageView channelIcon = (ImageView) v.findViewById(R.id.icon);                channelIcon.setAdjustViewBounds(true);                channelIcon.setMaxHeight(30);                channelIcon.setMaxWidth(30);                channelIcon.setImageDrawable(o.getLogo());                ImageButton button = (ImageButton) v.findViewById(R.id.button);                button.setImageResource(R.drawable.icon);                v.setOnCreateContextMenuListener(this);            }            return v;        }         public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {          // empty implementation        }    }}

let me know if someone will find better approach. Thanks!


Following segments of code from nested class ComplexObjectAdapter, listed into Georgy Gobozov's answer, are not really needed:

    @Override    public View getView(int position, View convertView, ViewGroup parent) {        View v = convertView;        if (v == null) {            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);            v = vi.inflate(R.layout.item, null);        }        final ComplexObject o = objects.get(position);        if (o != null) {            TextView textlInfo = (TextView) v.findViewById(R.id.info);            textlInfo.setText(o.getName());            ImageView channelIcon = (ImageView) v.findViewById(R.id.icon);            channelIcon.setAdjustViewBounds(true);            channelIcon.setMaxHeight(30);            channelIcon.setMaxWidth(30);            channelIcon.setImageDrawable(o.getLogo());            ImageButton button = (ImageButton) v.findViewById(R.id.button);            button.setImageResource(R.drawable.icon);            // NOT NEEDED            v.setOnCreateContextMenuListener(this);        }        return v;    }// NOT NEEDEDpublic void onCreateContextMenu(ContextMenu contextMenu, View view,  ContextMenu.ContextMenuInfo contextMenuInfo) {            // empty implementation}

It just works because inside the function setOnCreateContextMenuListener() from class View, it calls the function setLongClickable(true):

/** * Register a callback to be invoked when the context menu for this view is * being built. If this view is not long clickable, it becomes long clickable. * * @param l The callback that will run * */public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {    if (!isLongClickable()) {        setLongClickable(true);    }    mOnCreateContextMenuListener = l;}

It means the problem can be solved setting the Long Clickable property for each child item, after it is created:

    @Override    public View getView(int position, View convertView, ViewGroup parent) {        View v = convertView;        if (v == null) {            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);            v = vi.inflate(R.layout.item, null);            // SET LONG CLICKABLE PROPERTY            v.setLongClickable(true);        }        final ComplexObject o = objects.get(position);        if (o != null) {            TextView textlInfo = (TextView) v.findViewById(R.id.info);            textlInfo.setText(o.getName());            ImageView channelIcon = (ImageView) v.findViewById(R.id.icon);            channelIcon.setAdjustViewBounds(true);            channelIcon.setMaxHeight(30);            channelIcon.setMaxWidth(30);            channelIcon.setImageDrawable(o.getLogo());            ImageButton button = (ImageButton) v.findViewById(R.id.button);            button.setImageResource(R.drawable.icon);            // NOT NEEDED            // v.setOnCreateContextMenuListener(this);        }        return v;    }

or it also can be solved setting this property in the XML layout file of the list view child elements, for example:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:longClickable="true">    <!-- Child elements --></LinearLayout>


Actually, you just need to make View long clickable by calling

v.setLongClickable(true);

It's not needed to set dummy setOnCreateContextMenuListener, because it's does just that - set's the item long clickable.