Search code examples
androidinterfaceonlongclicklistener

Android adapter supplies default onLongClick if parent doesn't supply interface


I have several activities that could use the same array adapter. I would like to supply a default onLongClick if the activity doesn't implement it something like:

public class BookAdapter extends ArrayAdapter<Book> {
...
    private View.OnLongClickListener onLongClickListener;
    public BookAdapter(Context context, ArrayList<Book> aBooks) {
        super(context, 0, aBooks);
        Log.i(TAG, "caller:" + context.getClass().getSimpleName());
        if (context instanceof View.OnLongClickListener) {
            Log.i(TAG, "yes");
            onLongClickListener = (View.OnLongClickListener)
                     context.onLongClickListener();
        }
        else {
            onLongClickListener = new View.OnLongClickListener() {
                public boolean onLongClick(View v)
                   String title = 
                           ((TextView)(v.findViewById(R.id.tvTitle)))
                          .getText().toString();
                   Log.v(TAG, "view onLongClick pressed for title \""
                             + title + "\"");
                   return true;
                }
            };
        }
    }
    @Override
    public View getView(
        int position, View convertView, ViewGroup parent) {
        ...
        convertView.setOnLongClickListener(onLongClickListener);
        ...
    }
...
}

But I can't seem to assign the caller onClickListener to the local onLongClickListener.

How would I do this?


Solution

  • Got it. I dug through the source of View.java to see how it was implemented and the key was to wrap the call to the parent method in the default method I supply.

    public class BookAdapter extends ArrayAdapter<Book> {
        ...
        // Ref. to parent if it implements the OnLongClick interface.
        private View.OnLongClickListener mOnLongClickListener;
        public BookAdapter(Context context, ArrayList<Book> aBooks) {
            super(context, 0, aBooks);
            // save a ref. to the parent if it implements the OnLongClick interface.
            if (context instanceof View.OnLongClickListener) {
                mOnLongClickListener = (View.OnLongClickListener)context;
            }
        }
        ...
        // supply a OnLongClick method.
        private View.OnLongClickListener getOnLongClickListener() {
        if (mOnLongClickListener!= null) {
            return new View.OnLongClickListener() {
                public boolean onLongClick(View v) {
                    // Call the parent method if it is implemented.
                    return mOnLongClickListener.onLongClick(v);
                }
            };
        }
        else {
            return new View.OnLongClickListener() {
                public boolean onLongClick(View v) {
                    String title
                        = ((TextView)(v.findViewById(R.id.tvTitle)))
                            .getText().toString();
                    Log.v(TAG, "view onLongClick pressed for title \""
                        + title + "\"");
                    return true;
                }
            };
        }
    }
        ...
        public View getView(int position, View convertView, ViewGroup parent) {
        ...
            convertView.setOnLongClickListener(getOnLongClickListener());
            ...    
        }
        ...
    }
    

    If there's a cleaner way to do this, I'd love to hear it.

    Thanks Steve Smith