Вид сетки Android не может перетащить вид после первого успешного перетаскивания - PullRequest
0 голосов
/ 23 ноября 2018

Я добавляю кнопки динамически в вид сетки через его адаптер.У каждой кнопки есть следующие прослушиватели:

  • при прослушивании щелчка: в данный момент просто печатает в консоли, что кнопка была нажата
  • при прослушивании при длинном щелчке: запускает событие перетаскивания
  • on слушатель перетаскивания: обрабатывает событие перетаскивания. В сеточном адаптере у меня есть Arraylist<Button>, к которому я добавляю кнопки.Мой метод getView() возвращает соответствующий вид из списка.

Первое событие перетаскивания обрабатывается, как и ожидалось.Однако, если я нажимаю на кнопки после этого, они не отвечают.Я должен нажать ~ 10 раз, прежде чем все 10 сообщений попадут в консоль.Даже тогда я не могу долго нажимать на кнопки, чтобы перетаскивать их.

Я следовал многим учебным пособиям и многим другим советам, связанным с использованием ViewHolders и надуванием представлений в методе getView() метода BaseAdapter, но на самом деле не подходитменя, так как я получаю свои данные из базы данных.

Вот мои фрагменты кода:

MainActivity.java

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

    GridView gridView = findViewById(R.id.gridView);
    GridAdapter adapter = new GridAdapter();
    gridView.setAdapter(adapter);

    for(int i = 0; i < 2; i++) {
        final String text = "Hello " + (i + 1);
        Button button = new Button(MainActivity.this);
        button.setText(text);
        adapter.addView(button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("TAG", "Button " + text + " pressed");
            }
        });

        button.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                View.DragShadowBuilder myShadow = new View.DragShadowBuilder(v);
                v.startDrag(null, myShadow, v, 0);
                return true;
            }
        });

        button.setOnDragListener(new DragEventListener());
        button.setTag("1" + i);
    }
}

DragEventListener.java

private class DragEventListener implements View.OnDragListener {
    @Override
    public boolean onDrag(View v, DragEvent event) {
        final int action = event.getAction();

        switch(action) {
            case DragEvent.ACTION_DRAG_STARTED:
                return v instanceof Button;
            case DragEvent.ACTION_DRAG_ENTERED:
                v.setVisibility(View.INVISIBLE);
                return true;
            case DragEvent.ACTION_DRAG_LOCATION:
                return true;
            case DragEvent.ACTION_DRAG_EXITED:
                v.setVisibility(View.VISIBLE);
                return true;
            case DragEvent.ACTION_DROP:
                if(event.getLocalState() == v) {
                    return false;
                }

                // this is the actual view being dropped
                View itemBeingDragged = (View) event.getLocalState();
                GridView itemsParent = (GridView) itemBeingDragged.getParent();

                GridAdapter adapter = (GridAdapter) itemsParent.getAdapter();
                adapter.swap(itemBeingDragged, v);

                return true;
            case DragEvent.ACTION_DRAG_ENDED:
                v.setVisibility(View.VISIBLE);
                return true;
        }
        return true;
    }
}

И, наконец, GridAdapter.java

public class GridAdapter extends BaseAdapter {
    private volatile ArrayList<View> children = new ArrayList<>();

    public void addView(View view) {
        children.add(view);
        notifyDataSetChanged();
    }

    public void swap(View v1, View v2){
        int indexOfV1 = children.indexOf(v1);
        int indexOfV2 = children.indexOf(v2);
        Collections.swap(children, indexOfV1, indexOfV2);
        notifyDataSetChanged();
    }

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

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

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

    // create a new ImageView for each item referenced by the Adapter
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return children.get(position);
    }
}

Есть идеи, что может произойти?Раньше я получал исключение после некоторого количества длинных кликов, связанных с NPE, но сейчас я не могу воспроизвести его, чтобы показать исключение, к сожалению.

Я ценю любую помощь.

...