@1q1

Как установить setOnItemLongClickListener для элементов spinera?

Я хочу повесить контекстное меню, типа "удалить, редактировать" на элементы спинера при долгом нажатии.
Но, как выяснилось, без дополнительных приседаний такую возможность не реализовать. Нашёл на оверфлоу похожую проблему: stackoverflow.com/questions/2730610/how-can-i-use-spinner-setonitemlongclicklistener
Предпоследний ответ предлагает рабочее решение, но я, похоже, слишком тупой, чтобы его понять без дополнительной помощи.
1) Create a custom spinner class by extending spinner
Понятно как, но не понятно зачем
2) Define an interface to handle clicks,
Ок, определил
3) In your spinner adapter class do these stuffs in getView and getDropDownView
Я использую такой адаптер:
ArrayAdapter<Category> adapter;
adapter = new ArrayAdapter<Category>(this, android.R.layout.simple_spinner_item,  lCategory);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

Не понимаю как выполнить этот пункт.
Следующие пункты 4 и 5 тоже вызывают затруднения.
Может кто-нибудь разжевать более подробно, или сделать демку?
  • Вопрос задан
  • 96 просмотров
Решения вопроса 1
@terminator-light
Он отнаследовался от Spinner, потому что метод onDetachedFromWindow() protected, а значит, он не доступен извне, поэтому он сделал его public. Если не вызвать данный метод, дропдаун не закроется после клика на итем. Если не хотите наследоваться, можно воспользоваться рефлексией как здесь https://stackoverflow.com/a/35759475
Приведенный код работает:
SpinnerAdapter
public class SpinnerAdapter extends BaseAdapter {

    private List<String> items;
    private LayoutInflater inflater;
    private ItemClickListener clickListener;

    public SpinnerAdapter(Context context, List<String> items, ItemClickListener clickListener){
        inflater = LayoutInflater.from(context);
        this.items = items;
        this.clickListener = clickListener;
    }

    @Override
    public int getCount() {
        return items.size();
    }

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

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

    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            convertView = inflater.inflate(R.layout.spinner_item, parent, false);
        }
        ((TextView)convertView).setText(items.get(position));
        convertView.setTag(position);
        convertView.setClickable(false);
        convertView.setLongClickable(false);
        
        return convertView;
    }


    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        convertView = getView(position, convertView, parent);
        convertView.setTag(position);

        convertView.setOnClickListener(v -> {
            if (clickListener != null) {
                clickListener.onItemClicked(v);
            }
        });

        convertView.setOnLongClickListener(v -> {
            if (clickListener != null) {
                clickListener.onItemLongClicked(v);
            }
            return true;
        });

        return convertView;
    }
}

ItemClickListener
public interface ItemClickListener {
    void onItemLongClicked(View view);
    void onItemClicked(View view);
}

MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        List<String> strings = new ArrayList<String>(){{
            add("John");
            add("James");
            add("Jake");
            add("Jane");
        }};

        CustomSpinner spinner = findViewById(R.id.spinner);

        spinner.setAdapter(new SpinnerAdapter(this, strings, new ItemClickListener() {
            @Override
            public void onItemLongClicked(View view) {
                spinner.onDetachedFromWindow();
                final int pos = (int) view.getTag();
                spinner.setSelection(pos);
                Toast.makeText(MainActivity.this, "regular click: "+strings.get(pos), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemClicked(View view) {
                spinner.onDetachedFromWindow();
                final int pos = (int) view.getTag();
                spinner.setSelection(pos);
                Toast.makeText(MainActivity.this, "long click: "+strings.get(pos), Toast.LENGTH_SHORT).show();
            }

        }));
    }
}

spinner_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:layout_height="wrap_content">
</TextView>
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы