Search code examples
androidandroid-recyclerviewspinneradapter

android spinner in recyclerView does not work properly


I am trying to use Spinner ( 3 dots with dropdown menu) in my recyclerView, but when I load this recyclerView function onItemSelected is called automatically and later when I press on item it is not called anymore. Here is my code in adapter:

       @Override
       public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, R.array.my_listing_item_array, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            ((SaleAdapter.SalesViewHolder) holder).overflow.setAdapter(adapter);

            ((SaleAdapter.SalesViewHolder) holder).overflow.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                    Toast.makeText(context, String.valueOf(position) + " item is selected", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {

                }
            });

}

  public static class SalesViewHolder extends RecyclerView.ViewHolder {
      public LinearLayout overflowLayout;
      public Spinner overflow;

      public SalesViewHolder(View itemView, Context context) {
          super(itemView);

          overflowLayout = (LinearLayout) itemView.findViewById(R.id.list_item_overflow_layout);
          overflow = (Spinner) itemView.findViewById(R.id.list_item_overflow);
      }
     }

Here is code of View:

<LinearLayout
    android:id="@+id/list_item_overflow_layout"
    android:layout_width="54dp"
    android:layout_height="54dp"
    android:layout_gravity="center_vertical"
    android:orientation="vertical"
    android:padding="15dp"
    android:background="@drawable/ic_more_vert_24dp_grey"
    >

    <Spinner
        android:id="@+id/list_item_overflow"
        android:layout_width="24dp"
        android:layout_height="24dp"
        />


</LinearLayout>

Does anyone know what is the problem here with my code? Should I export setOnItemSelectedListener somewhere else?


Solution

  • Better use a PopUpMenu for each item in the list. Have an ImageView instead of the Spinner which will display a "3 dot" icon. When someone clicks the dots the PopUpMenu will... pop up!

    In steps:

    1)Replace the Spinner in the xml layout with an ImageView which will display the three dots icon.

    2) Define a listener class inside your RecyclerView.Adapter<SalesViewHolder> and save an instance there.

    3) Inside SalesViewHolder set an OnClickListener to responds to clicks.

    4) Pop up from the Activity.

    Your new adapter should look something like this

    class SalesAdapter extends RecyclerView.Adapter<SalesViewHolder>{
        public interface OnMenuItemClickListener{
            void onMenuItemClicked(ImageView view);
        }
    
        private OnMenuItemClickListener listener;
    
        public void setOnMenuItemClickListener(OnMenuItemClickListener listener){
            this.listener = listener;
        }
    
        public static class SalesViewHolder extends RecyclerView.ViewHolder {
            public LinearLayout overflowLayout;
            public ImageView menu;
    
        public SalesViewHolder(View itemView, Context context) {
            super(itemView);
    
            overflowLayout = (LinearLayout) itemView.findViewById(R.id.list_item_overflow_layout);
            menu= (ImageView) itemView.findViewById(R.id.imageview_id);
            // Make sure to enable lambdas
            menu.setOnClickListener( (view) -> {
                if( listener != null ){
                    listener.onMenuItemClicked(view);
                }
            }
        }
         }
    
    }
    

    Your activity must implement the OnMenuItemClickListener and may look something like this

    class YourActivity extends Activity implements SalesAdapter.OnMenuItemClickListener{
    
        // Don't forget to set the listener to the adapter,  let's suppose that happens in onCreate()
        @Override
        public void onCreate(Bundle arg){
            SalesAdapter adapter = new SalesAdapter();
            adapter.setOnMenuItemClickListener(this);
        }
    
        @Override
        public void onMenuItemClicked(ImageView menu){
            showPopUp(menu);
        }
    
        private void showPopup(View v) {
            PopupMenu popup = new PopupMenu(this, v);
            MenuInflater inflater = popup.getMenuInflater();
            inflater.inflate(R.menu.actions, popup.getMenu());
            popup.show();
        }
    
    }
    

    Don't forget to supply menu actions etc... as mentioned here.