1

I am using 2 RecyclerViews inside a Dialogue. One of the RecyclerView further uses a nested list inside it. Everything's alright till now (no height issues).

However, from the other RecyclerView, I drag an image/view and inside another RecyclerView i wish to drop it.

This functionality works fine but problem occurs here:

I usually highlight a particular Text area when the dragged image enters that area using DragListener's available Drag events (see image below):

http://i.imgur.com/9w57vaw.png

So if I drag the image till "Customer Voice 5" Text header, it'll highlight.

When I drag it to the 5th item, it scrolls down (as coded inside DragListener using smoothScrollBy()) and 6th item with the header "Customer Voice 6" Text header is also visible, BUT it doesn't get highlighted. Neither it scrolls down further to show 7th completely, no code works on this item, as if RecyclerView hasn't yet updated/recognized this item inside it's onBindViewHolder(...) method.

enter image description here

Now I drop the dragged image elsewhere (no action) and again drag image to "Customer Header 6", it highlights! (and scrolls too) That means RecyclerView has updated it after I had dropped my image on the first run.

So while I drag, the Drag Listener's event ACTION_DRAG_LOCATION runs continuously and Recycler View seems to not able to take the control while this happens. So how to get both things DragListener and RecyclerViewAdapter, work together? [I am aware how RV uses the items from holder and re-uses it when invisible from to dirty view list]

I tried notifyDataSetChanged(); but doesn't help. Can't find any other thing on this. Maybe LinearLayoutManager might help but can't link it with my problem. Below are some code blocks from my RV adapter.

 @Override
    public void onBindViewHolder(MyHolder holder, int position) {


        Log.d("Log","OnBindViewHolder"+position);

        holder.customerVoiceTitle.setText(hashMap.get(position));  //Setting Header Text - "Customer Voice [position+1]"

        holder.customerVoiceTitle.setId(position + 100);   // Setting id to be able to detect each header while performing drag actions

        holder.customerVoiceTitle.setOnDragListener(new MyDragListener());

        customerVoiceMainHeaderText.setId(50);  //Neglect this for the time being, this is also a part of the issue.

        customerVoiceMainHeaderText.setOnDragListener(new MyDragListener());

        holder.totalWorkLayoutListView.setId(position + 150); //ListView also is utilized to perform drag actions

        holder.totalWorkLayoutListView.setOnDragListener(new MyDragListener());

        UtilityClass.setListViewHeightBasedOnChildren(holder.totalWorkLayoutListView, "", ""); //To avoid height inflation issues

      /*  if(allFlag) {
            customerVoiceWorkListCustomAdapter = new CustomerVoiceWorkListCustomAdapter(context, 5, true);
        }
        else if(!allFlag) {
            customerVoiceWorkListCustomAdapter = new CustomerVoiceWorkListCustomAdapter(context, 5, false);
        }*/

        holder.totalWorkLayoutListView.setAdapter(customerVoiceWorkListCustomAdapter);
    }




class MyDragListener implements View.OnDragListener {
        Drawable normalShape = context.getResources().getDrawable(R.drawable.bg_fragment_header_with_border);
        Drawable targetShape = context.getResources().getDrawable(R.drawable.target_shape);

        @Override
        public boolean onDrag(View v, DragEvent event) {


            // Handles each of the expected events
            switch (event.getAction()) {


                //signal for the start of a drag and drop operation.
                case DragEvent.ACTION_DRAG_STARTED:
                    // do nothing
                    break;

                //the drag point has entered the bounding box of the View
                case DragEvent.ACTION_DRAG_ENTERED:
                    if(v.getId() >= 100 && v.getId() < 150)  //For Header Text only
                    v.setBackground(targetShape);    //change the shape of the view
                    break;

                //the user has moved the drag shadow outside the bounding box of the View
                case DragEvent.ACTION_DRAG_EXITED:
                    if(v.getId() >= 100 && v.getId() < 150)  //For Header Text only
                    v.setBackground(normalShape);    //change the shape of the view back to normal
                    break;

                //drag shadow has been released,the drag point is within the bounding box of the View
                case DragEvent.ACTION_DROP:

                    Log.d("Log", "" + v.getId());
                    // if the view is the bottomlinear, we accept the drag item
                    if (v.getId() >= 100 && v.getId() < 150) {  //For Header Text only. If dragged image is dropped some changes take place inside the list. Not IMP now

                        TextView workListHeaderText = (TextView) v;
                        LinearLayout containerLayout = (LinearLayout) workListHeaderText.getParent();

                        ListView workLayoutList = (ListView) containerLayout.getChildAt(1);

                        customerVoiceWorkListCustomAdapter = new CustomerVoiceWorkListCustomAdapter(context, 5, true);

                        workLayoutList.setAdapter(customerVoiceWorkListCustomAdapter);

                    } else if (v.getId() == 50) {
                        allFlag = true;
                        TextView workListRootHeaderText = (TextView) v;
                        LinearLayout layout = (LinearLayout) workListRootHeaderText.getParent();

                        RecyclerView technicianAllotment = (RecyclerView) layout.getChildAt(1);

                        int childCount = technicianAllotment.getChildCount();


                        for (int listCount = 0; listCount < childCount; listCount++) {
                            LinearLayout linearLayout = (LinearLayout) technicianAllotment.getChildAt(listCount);
                            ListView workLayoutList = (ListView) linearLayout.getChildAt(1);

                            customerVoiceWorkListCustomAdapter = new CustomerVoiceWorkListCustomAdapter(context, 5, true);

                            workLayoutList.setAdapter(customerVoiceWorkListCustomAdapter);



                            UtilityClass.setListViewHeightBasedOnChildren(workLayoutList, "", "");
                        }

                    }
                    break;

                case DragEvent.ACTION_DRAG_LOCATION:  //This is used to scroll when dragged image is dragged to the bottom of screen


                    LinearLayout dropZoneView = (LinearLayout) v.getParent();

                    int topOfDropZone = dropZoneView.getTop();
                    int bottomOfDropZone = dropZoneView.getBottom();

                    int scrollY = recyclerView.getScrollY();
                    int scrollViewHeight = recyclerView.getMeasuredHeight();

                    Log.d("Log", "location: Scroll Y: " + scrollY + " Scroll Y+Height: " + (scrollY + scrollViewHeight));
                    Log.d("Log", " top: " + topOfDropZone + " bottom: " + bottomOfDropZone);

                    if (bottomOfDropZone > (scrollY + scrollViewHeight - 100)) {  //Manual scrolling down when image is dragged to bottom RV item
                        notifyDataSetChanged();
                        recyclerView.smoothScrollBy(0, 300);
                    }
                    if (topOfDropZone < (scrollY + 50))  //Manual scrolling up
                        recyclerView.smoothScrollBy(0, -50);

                    break;

                //the drag and drop operation has concluded.
                case DragEvent.ACTION_DRAG_ENDED:
                    if(v.getId() >= 100 && v.getId() < 150)
                    v.setBackground(normalShape);    //go back to normal shape

                default:
                    break;
            }
            return true;
        }
    }

EDIT

https://stackoverflow.com/a/14458111/4452231

This so far has worked. Got better solutions? Kindly suggest.

Community
  • 1
  • 1
Shridhar
  • 333
  • 1
  • 3
  • 15
  • Trying to understand - http://stackoverflow.com/a/14458111/4452231 – Shridhar Apr 30 '16 at 05:39
  • Yes, this is the one. The above link is the answer. Compromise so far - Had to replace RV by ListView. Thanks @Vincent Hiribarren – Shridhar Apr 30 '16 at 07:49
  • There's a BUT however with this technique as mentioned in the answer itself on the link. I get itemPosition as -1 in ACTION_DRAG_EXITED event everytime :( – Shridhar Apr 30 '16 at 08:29

0 Answers0