9

我已经给出了我拥有的完整代码。

下面的代码可以非常流畅地拖放,但它不像我需要的那样工作,就像下面的描述一样。

  1. 拖动数据是(Apple、Orage、Ball)
  2. 放置目标位置是 (A for, O for, B for)

因此,如果将“Apple”拖放到“A for”,它将是正确的,并且将文本更新为“A for Apple”,并且拖动时的文本“Apple”将被隐藏......但是如果我们将“Apple”拖放到“O” for”或“B for”将失败,因为“O for Orange”和“B for Ball”。

根据下面的代码,我应该添加什么。

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp" >


<TextView
    android:id="@+id/option_1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/option"
    android:gravity="center"
    android:text="Apple"
    android:textStyle="bold" />

<TextView
    android:id="@+id/option_2"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/option"
    android:gravity="center"
    android:text="Orange"
    android:textStyle="bold" />

<TextView
    android:id="@+id/option_3"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/option"
    android:gravity="center"
    android:text="Ball"
    android:textStyle="bold" />

<TextView
    android:id="@+id/choice_1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/choice"
    android:gravity="center"
    android:text="A for " />

<TextView
    android:id="@+id/choice_2"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/choice"
    android:gravity="center"
    android:text="O for" />

<TextView
    android:id="@+id/choice_3"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/choice"
    android:gravity="center"
    android:text="B for " />

</LinearLayout>

活动:

public class picture_to_word_24_color extends Activity {

//text views being dragged and dropped onto
private TextView option1, option2, option3, choice1, choice2, choice3;
public CharSequence dragData;

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

    //get both sets of text views

    //views to drag
    option1 = (TextView)findViewById(R.id.option_1);
    option2 = (TextView)findViewById(R.id.option_2);
    option3 = (TextView)findViewById(R.id.option_3);

    //views to drop onto
    choice1 = (TextView)findViewById(R.id.choice_1);
    choice2 = (TextView)findViewById(R.id.choice_2);
    choice3 = (TextView)findViewById(R.id.choice_3);

    //set touch listeners
    option1.setOnTouchListener(new ChoiceTouchListener());
    option2.setOnTouchListener(new ChoiceTouchListener());
    option3.setOnTouchListener(new ChoiceTouchListener());

    //set drag listeners
    choice1.setOnDragListener(new ChoiceDragListener());
    choice2.setOnDragListener(new ChoiceDragListener());
    choice3.setOnDragListener(new ChoiceDragListener());
}

/**
 * ChoiceTouchListener will handle touch events on draggable views
 *
 */
private final class ChoiceTouchListener implements OnTouchListener {
    @SuppressLint("NewApi")
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            /*
             * Drag details: we only need default behavior
             * - clip data could be set to pass data as part of drag
             * - shadow can be tailored
             */
            ClipData data = ClipData.newPlainText("", "");
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            //start dragging the item touched
            view.startDrag(data, shadowBuilder, view, 0);
            return true;
        } else {
            return false;
        }
    }
} 

/**
 * DragListener will handle dragged views being dropped on the drop area
 * - only the drop action will have processing added to it as we are not
 * - amending the default behavior for other parts of the drag process
 *
 */
@SuppressLint("NewApi")
private class ChoiceDragListener implements OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
            //no action necessary
            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            //no action necessary
            Toast.makeText(picture_to_word_24_color.this, "ACTION_DRAG_ENTERED", Toast.LENGTH_SHORT).show();
            break;
        case DragEvent.ACTION_DRAG_EXITED:        
            //no action necessary
            Toast.makeText(picture_to_word_24_color.this, "ACTION_DRAG_EXITED", Toast.LENGTH_SHORT).show();
            break;
        case DragEvent.ACTION_DROP:
            
            Toast.makeText(picture_to_word_24_color.this, "ACTION_DROP", Toast.LENGTH_SHORT).show();
            //handle the dragged view being dropped over a drop view
            View view = (View) event.getLocalState();
            //stop displaying the view where it was before it was dragged
            view.setVisibility(View.INVISIBLE);
            //view dragged item is being dropped on
            TextView dropTarget = (TextView) v;
            //view being dragged and dropped
            TextView dropped = (TextView) view;
            //update the text in the target view to reflect the data being dropped
            dropTarget.setText(dropped.getText());
            //make it bold to highlight the fact that an item has been dropped
            dropTarget.setTypeface(Typeface.DEFAULT_BOLD);
            //if an item has already been dropped here, there will be a tag
            Object tag = dropTarget.getTag();
            //if there is already an item here, set it back visible in its original place
            if(tag!=null)
            {
                //the tag is the view id already dropped here
                int existingID = (Integer)tag;
                //set the original view visible again
                findViewById(existingID).setVisibility(View.VISIBLE);
            }
            //set the tag in the target view being dropped on - to the ID of the view being dropped
            dropTarget.setTag(dropped.getId());
            break;
        case DragEvent.ACTION_DRAG_ENDED:
            //no action necessary
            Toast.makeText(picture_to_word_24_color.this, "ACTION_DRAG_ENDED", Toast.LENGTH_SHORT).show();
            break;
        default:
            break;
        }
        return true;
    }
} 
}
4

1 回答 1

24

尝试以下代码,它应该根据您在问题中的描述工作。我添加了一个额外的东西,即重置按钮,因为我觉得有必要。

picture_to_word_24_color.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp" >


<TextView
android:id="@+id/option_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/option"
android:gravity="center"
android:text="Apple"
android:textStyle="bold" />

<TextView
android:id="@+id/option_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/option"
android:gravity="center"
android:text="Orange"
android:textStyle="bold" />

<TextView
android:id="@+id/option_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/option"
android:gravity="center"
android:text="Ball"
android:textStyle="bold" />

<TextView
android:id="@+id/choice_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/choice"
android:gravity="center"
android:text="A for " />

<TextView
android:id="@+id/choice_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/choice"
android:gravity="center"
android:text="O for " />

<TextView
android:id="@+id/choice_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/choice"
android:gravity="center"
android:text="B for " />

<Button 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset"
android:onClick="reset"/>

</LinearLayout>

Picture_to_word_24_color.java

package com.example.touchanddrag;

import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ClipData;
import android.graphics.Typeface;
import android.view.DragEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.widget.TextView;
import android.widget.Toast;

@SuppressLint("NewApi")
public class Picture_to_word_24_color extends Activity {

private TextView option1, option2, option3, choice1, choice2, choice3;
public CharSequence dragData;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.picture_to_word_24_color);

    //get both sets of text views

    //views to drag
    option1 = (TextView)findViewById(R.id.option_1);
    option2 = (TextView)findViewById(R.id.option_2);
    option3 = (TextView)findViewById(R.id.option_3);

    //views to drop onto
    choice1 = (TextView)findViewById(R.id.choice_1);
    choice2 = (TextView)findViewById(R.id.choice_2);
    choice3 = (TextView)findViewById(R.id.choice_3);

    //set touch listeners
    option1.setOnTouchListener(new ChoiceTouchListener());
    option2.setOnTouchListener(new ChoiceTouchListener());
    option3.setOnTouchListener(new ChoiceTouchListener());

    //set drag listeners
    choice1.setOnDragListener(new ChoiceDragListener());
    choice2.setOnDragListener(new ChoiceDragListener());
    choice3.setOnDragListener(new ChoiceDragListener());
}

/**
 * ChoiceTouchListener will handle touch events on draggable views
 *
 */
private final class ChoiceTouchListener implements OnTouchListener {
    @SuppressLint("NewApi")
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            /*
             * Drag details: we only need default behavior
             * - clip data could be set to pass data as part of drag
             * - shadow can be tailored
             */
            ClipData data = ClipData.newPlainText("", "");
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            //start dragging the item touched
            view.startDrag(data, shadowBuilder, view, 0);
            return true;
        } else {
            return false;
        }
    }
} 

/**
 * DragListener will handle dragged views being dropped on the drop area
 * - only the drop action will have processing added to it as we are not
 * - amending the default behavior for other parts of the drag process
 *
 */
@SuppressLint("NewApi")
private class ChoiceDragListener implements OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
            //no action necessary
            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            //no action necessary
            break;
        case DragEvent.ACTION_DRAG_EXITED:        
            //no action necessary
            break;
        case DragEvent.ACTION_DROP:

            //handle the dragged view being dropped over a drop view
            View view = (View) event.getLocalState();
            //view dragged item is being dropped on
            TextView dropTarget = (TextView) v;
            //view being dragged and dropped
            TextView dropped = (TextView) view;
            //checking whether first character of dropTarget equals first character of dropped
            if(dropTarget.getText().toString().charAt(0) == dropped.getText().toString().charAt(0))
            {
                //stop displaying the view where it was before it was dragged
                view.setVisibility(View.INVISIBLE);
                //update the text in the target view to reflect the data being dropped
                dropTarget.setText(dropTarget.getText().toString() + dropped.getText().toString());
                //make it bold to highlight the fact that an item has been dropped
                dropTarget.setTypeface(Typeface.DEFAULT_BOLD);
                //if an item has already been dropped here, there will be a tag
                Object tag = dropTarget.getTag();
                //if there is already an item here, set it back visible in its original place
                if(tag!=null)
                {
                    //the tag is the view id already dropped here
                    int existingID = (Integer)tag;
                    //set the original view visible again
                    findViewById(existingID).setVisibility(View.VISIBLE);
                }
                //set the tag in the target view being dropped on - to the ID of the view being dropped
                dropTarget.setTag(dropped.getId());
                //remove setOnDragListener by setting OnDragListener to null, so that no further drag & dropping on this TextView can be done
                dropTarget.setOnDragListener(null);
            }
            else
                //displays message if first character of dropTarget is not equal to first character of dropped
                Toast.makeText(Picture_to_word_24_color.this, dropTarget.getText().toString() + "is not " + dropped.getText().toString(), Toast.LENGTH_LONG).show();
            break;
        case DragEvent.ACTION_DRAG_ENDED:
            //no action necessary
            break;
        default:
            break;
        }
        return true;
    }
} 

public void reset(View view)
{
    option1.setVisibility(TextView.VISIBLE);
    option2.setVisibility(TextView.VISIBLE);
    option3.setVisibility(TextView.VISIBLE);

    choice1.setText("A for ");
    choice2.setText("O for ");
    choice3.setText("B for ");

    choice1.setTag(null);
    choice2.setTag(null);
    choice3.setTag(null);

    choice1.setTypeface(Typeface.DEFAULT);
    choice2.setTypeface(Typeface.DEFAULT);
    choice3.setTypeface(Typeface.DEFAULT);

    choice1.setOnDragListener(new ChoiceDragListener());
    choice2.setOnDragListener(new ChoiceDragListener());
    choice3.setOnDragListener(new ChoiceDragListener());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.picture_to_word_24_color, menu);
    return true;
}

}

不要忘记检查目标 API 级别。正如我必须添加的@SuppressLint("NewApi")

于 2013-06-27T17:02:55.890 回答