Android grid view unable to drag view after first successful drag and drop





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I am adding buttons dynamically into a grid view through its adapter. Each button has the following listeners:




  • on click listener: at the moment just printing into the console that the button was clicked

  • on long click listener: starts a drag event

  • on drag listener: handles the drag event
    In the grid adapter, I have an Arraylist<Button> which I add the buttons to it. My getView() method returns the appropriate view from the list.


The first drag and drop event is handled as expected. However, if I click on the buttons after that, they are unresponsive. I have to click ~10 times before all 10 messages get clicked into the console. Even then, I cannot long click on the buttons to drag them.



I followed many tutorials and many other suggestions related to using ViewHolders and inflating views in the getView() method of the BaseAdapter but non actually suits me since I am receiving my data from a database.



Here are my code snippets:



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;
}
}


And finally the 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);
}
}


Any idea what might be happening? I used to get an exception after some number of long clicks related to NPE but I am unable to reproduce it now to show the exception unfortunately.



I appreciate any help.










share|improve this question





























    0















    I am adding buttons dynamically into a grid view through its adapter. Each button has the following listeners:




    • on click listener: at the moment just printing into the console that the button was clicked

    • on long click listener: starts a drag event

    • on drag listener: handles the drag event
      In the grid adapter, I have an Arraylist<Button> which I add the buttons to it. My getView() method returns the appropriate view from the list.


    The first drag and drop event is handled as expected. However, if I click on the buttons after that, they are unresponsive. I have to click ~10 times before all 10 messages get clicked into the console. Even then, I cannot long click on the buttons to drag them.



    I followed many tutorials and many other suggestions related to using ViewHolders and inflating views in the getView() method of the BaseAdapter but non actually suits me since I am receiving my data from a database.



    Here are my code snippets:



    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;
    }
    }


    And finally the 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);
    }
    }


    Any idea what might be happening? I used to get an exception after some number of long clicks related to NPE but I am unable to reproduce it now to show the exception unfortunately.



    I appreciate any help.










    share|improve this question

























      0












      0








      0








      I am adding buttons dynamically into a grid view through its adapter. Each button has the following listeners:




      • on click listener: at the moment just printing into the console that the button was clicked

      • on long click listener: starts a drag event

      • on drag listener: handles the drag event
        In the grid adapter, I have an Arraylist<Button> which I add the buttons to it. My getView() method returns the appropriate view from the list.


      The first drag and drop event is handled as expected. However, if I click on the buttons after that, they are unresponsive. I have to click ~10 times before all 10 messages get clicked into the console. Even then, I cannot long click on the buttons to drag them.



      I followed many tutorials and many other suggestions related to using ViewHolders and inflating views in the getView() method of the BaseAdapter but non actually suits me since I am receiving my data from a database.



      Here are my code snippets:



      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;
      }
      }


      And finally the 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);
      }
      }


      Any idea what might be happening? I used to get an exception after some number of long clicks related to NPE but I am unable to reproduce it now to show the exception unfortunately.



      I appreciate any help.










      share|improve this question














      I am adding buttons dynamically into a grid view through its adapter. Each button has the following listeners:




      • on click listener: at the moment just printing into the console that the button was clicked

      • on long click listener: starts a drag event

      • on drag listener: handles the drag event
        In the grid adapter, I have an Arraylist<Button> which I add the buttons to it. My getView() method returns the appropriate view from the list.


      The first drag and drop event is handled as expected. However, if I click on the buttons after that, they are unresponsive. I have to click ~10 times before all 10 messages get clicked into the console. Even then, I cannot long click on the buttons to drag them.



      I followed many tutorials and many other suggestions related to using ViewHolders and inflating views in the getView() method of the BaseAdapter but non actually suits me since I am receiving my data from a database.



      Here are my code snippets:



      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;
      }
      }


      And finally the 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);
      }
      }


      Any idea what might be happening? I used to get an exception after some number of long clicks related to NPE but I am unable to reproduce it now to show the exception unfortunately.



      I appreciate any help.







      android gridview drag-and-drop baseadapter






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 20:53









      user3396919user3396919

      114




      114
























          0






          active

          oldest

          votes












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452831%2fandroid-grid-view-unable-to-drag-view-after-first-successful-drag-and-drop%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452831%2fandroid-grid-view-unable-to-drag-view-after-first-successful-drag-and-drop%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()