开发者

Android drag and drop in tab view stops working after tab index changes

开发者 https://www.devze.com 2023-03-20 03:47 出处:网络
Ok, I\'ve implemented a android datagrid that amongst other things, lets you drag and drop columns around. This functionality works beautifully (better than I expected).

Ok, I've implemented a android datagrid that amongst other things, lets you drag and drop columns around. This functionality works beautifully (better than I expected).

I noticed recently that if the grids were placed in tabcontents... it seems like zindex isnt taken into account (even though my ACTION_DRAG_STARTED will return false for column headers further back in the z-index, I still see those column headers responding to some events (like ACTION_DRAG_EXITED).

Attempting to have a controlled environment, I went ahead and built a stand alone project that demonstrates this problem.

I am hoping its something simple I missed, or perhaps ideas on how to work around it. Pretty simple to reproduce... run project, drag buttons around with long press... change tabs, drag those around, change back to first tab, drag around. It should start drag process, but as soon as you drag out of the control you were just in, you see "Reporting drop result:false".

Any pointers would be greatly appreciated... I suspect the underlying views are cancelling the drag event.

BrokeDragNDropActivity.java

package cm.mc.busteddnd;


import android.app.Activity;
import android.content.ClipData;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.View.OnLongClickListener;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;
import android.widget.Toast;

public class BrokeDragNDropActivity extends Activity {
public static int selectedTab =0;
Extendedbutton button1;
Extendedbutton button2;
Extendedbutton button3;
Extendedbutton button4;
Extendedbutton button5;
Extendedbutton button6;
Extendedbutton button7;
Extendedbutton button8;
Extendedbutton button9;


@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
    final TabHost tabs = (TabHost) this.findViewById(R.id.my_tabhost);

    tabs.setOnTabChangedListener(new OnTabChangeListener() {
        @Override
        public void onTabChanged(String arg0) {         
            selectedTab = tabs.getCurrentTab();
            Log.i("***Selected Tab", "Im currently in tab with index::" + tabs.getCurrentTab());
        }       
    });  
    tabs.setup();
    TabSpec tspec1 = tabs.newTabSpec("First Tab");
    tspec1.setIndicator("One");
    tspec1.setContent(R.id.content);
    tabs.addTab(tspec1);
    TabSpec tspec2 = tabs.newTabSpec("Second Tab");
    tspec2.setIndicator("Two");
    tspec2.setContent(R.id.content2);
    tabs.addTab(tspec2);
    TabSpec tspec3 = tabs.newTabSpec("Third Tab");
    tspec3.setIndicator("Three");
    tspec3.setContent(R.id.content3);
    tabs.addTab(tspec3);

    //wire up buttons
    button1 = (Extendedbutton)findViewById(R.id.button1);
    button2 = (Extendedbutton)findViewById(R.id.button2);
    button3 = (Extendedbutton)findViewById(R.id.button3);
    button4 = (Extendedbutton)findViewById(R.id.button4);
    button5 = (Extendedbutton)findViewByI开发者_高级运维d(R.id.button5);
    button6 = (Extendedbutton)findViewById(R.id.button6);
    button7 = (Extendedbutton)findViewById(R.id.button7);
    button8 = (Extendedbutton)findViewById(R.id.button8);
    button9 = (Extendedbutton)findViewById(R.id.button9);

    //wire up listeners

    button1.setGroup(1);
    wireListeners(button1);

    button2.setGroup(1);
    wireListeners(button2);

    button3.setGroup(1);
    wireListeners(button3);


    button4.setGroup(2);
    wireListeners(button4);

    button5.setGroup(2);
    wireListeners(button5);

    button6.setGroup(2);
    wireListeners(button6);


    button7.setGroup(3);
    wireListeners(button7);

    button8.setGroup(3);
    wireListeners(button8);

    button9.setGroup(3);
    wireListeners(button9);

}

public void wireListeners(Extendedbutton button){
    button.setOnLongClickListener(new OnLongClickListener() {

        @Override
        public boolean onLongClick(View paramView) {
            Extendedbutton v = (Extendedbutton)paramView;
            ClipData data = ClipData.newPlainText("group_"+v.getGroup(), v.getDesc());
            paramView.startDrag(data,  // the data to be dragged
                        new View.DragShadowBuilder(paramView),  // the drag shadow builder
                        null,      // no need to use local data
                        0          // flags (not currently used, set to 0)
            );
            return true;
        }
    });

    button.setOnDragListener(new OnDragListener(){

        @Override
        public boolean onDrag(View v, DragEvent event) {
             // Defines a variable to store the action type for the incoming event
            final int action = event.getAction();

            // Handles each of the expected events
            CharSequence dragData;
            switch(action) {

                case DragEvent.ACTION_DRAG_STARTED:

                    // Determines if this View can accept the dragged data
                    if (event.getClipDescription().getLabel().equals("group_"+(selectedTab+1))) {

                        // As an example of what your application might do,
                        // applies a blue color tint to the View to indicate that it can accept
                        // data.
                        v.setBackgroundColor(Color.BLUE);

                        // Invalidate the view to force a redraw in the new tint
                        v.invalidate();

                        // returns true to indicate that the View can accept the dragged data.
                        return(true);

                        } else {

                        // Returns false. During the current drag and drop operation, this View will
                        // not receive events again until ACTION_DRAG_ENDED is sent.
                        return(false);

                        }

                case DragEvent.ACTION_DRAG_ENTERED: {

                    // Applies a green tint to the View. Return true; the return value is ignored.

                    v.setBackgroundColor(Color.GREEN);

                    // Invalidate the view to force a redraw in the new tint
                    v.invalidate();

                    return(true);
                }


                    case DragEvent.ACTION_DRAG_LOCATION:

                    // Ignore the event
                        return(true);

                    case DragEvent.ACTION_DRAG_EXITED:

                        // Re-sets the color tint to blue. Returns true; the return value is ignored.
                        v.setBackgroundColor(Color.BLUE);

                        // Invalidate the view to force a redraw in the new tint
                        v.invalidate();

                        return(true);


                    case DragEvent.ACTION_DROP:

                        // Gets the item containing the dragged data
                        ClipData.Item item = event.getClipData().getItemAt(0);

                        // Gets the text data from the item.
                        dragData = item.getText();

                        // Displays a message containing the dragged data.
                        Toast.makeText(BrokeDragNDropActivity.this, "Dragged data is " + dragData, Toast.LENGTH_LONG);

                        // Turns off any color tints
                        v.setBackgroundColor(Color.BLACK);

                        // Invalidates the view to force a redraw
                        v.invalidate();

                        // Returns true. DragEvent.getResult() will return true.
                        return(true);


                    case DragEvent.ACTION_DRAG_ENDED:

                        // Turns off any color tinting
                        v.setBackgroundColor(Color.BLACK);

                        // Invalidates the view to force a redraw
                        v.invalidate();

                        // Does a getResult(), and displays what happened.
                        if (event.getResult()) {
                            Toast.makeText(BrokeDragNDropActivity.this, "The drop was handled.", Toast.LENGTH_LONG);

                        } else {
                            Toast.makeText(BrokeDragNDropActivity.this, "The drop didn't work.", Toast.LENGTH_LONG);

                        };

                        // returns true; the value is ignored.
                        return(true);


                    // An unknown action type was received.
                    default:
                        Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
                        return false;
            }
            }

    });
}

}

ExtendedButton.java (needed this to handle the group filtering)

package cm.mc.busteddnd;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;

public class Extendedbutton extends Button {
    private int group;
    private String desc;



    public int getGroup() {
        return group;
    }



    public void setGroup(int group) {
        this.group = group;
    }



    public String getDesc() {
        return desc;
    }



    public void setDesc(String desc) {
        this.desc = desc;
    }



    public Extendedbutton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }



    public Extendedbutton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }



    public Extendedbutton(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }






}

and finally... main.xml

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="65px"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="200px"
android:paddingTop="65px">
<LinearLayout
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="horizontal">
    <cm.mc.busteddnd.Extendedbutton android:text="Button1" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
    <cm.mc.busteddnd.Extendedbutton android:text="Button2" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
    <cm.mc.busteddnd.Extendedbutton android:text="Button3" android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
</LinearLayout>
<LinearLayout
android:id="@+id/content2"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="horizontal">
     <cm.mc.busteddnd.Extendedbutton android:text="Button4" android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
    <cm.mc.busteddnd.Extendedbutton android:text="Button5" android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
    <cm.mc.busteddnd.Extendedbutton android:text="Button6" android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
</LinearLayout>
<LinearLayout
android:id="@+id/content3"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="horizontal">
    <cm.mc.busteddnd.Extendedbutton android:text="Button7" android:id="@+id/button7" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
    <cm.mc.busteddnd.Extendedbutton android:text="Button8" android:id="@+id/button8" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
    <cm.mc.busteddnd.Extendedbutton android:text="Button9" android:id="@+id/button9" android:layout_width="wrap_content" android:layout_height="wrap_content"></cm.mc.busteddnd.Extendedbutton>
</LinearLayout>
</FrameLayout>
</TabHost>
0

精彩评论

暂无评论...
验证码 换一张
取 消