【问题标题】:Android: After drop, editText that was being dragged disapearsAndroid:放下后,被拖动的editText消失了
【发布时间】:2015-11-12 04:34:12
【问题描述】:

我正在尝试创建一个表单,用户可以在其中移动输入。我有一个 editText 并希望它能够将它移动到我的 relativeLayout 中的新位置。我可以拿起它并移动它,但一旦我放开它,它就会完全消失。我几乎什么都试过了。我认为可能永远不会调用 onDrag 方法,因为我的日志永远不会出现。另外,放开我的editText后,我在logcat中收到此错误消息:Reporting drop result: false

我遇到的另一个问题是,当您点击 editText 时,它认为我正在尝试拖动它,这意味着我实际上无法更改其中的文本。

任何帮助表示赞赏!谢谢!

这是我的相对布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
                xmlns:app = "http://schemas.android.com/apk/res-auto"
                xmlns:tools = "http://schemas.android.com/tools"
                android:layout_width = "match_parent"
                android:layout_height = "match_parent"
                android:paddingBottom = "@dimen/activity_vertical_margin"
                android:paddingLeft = "@dimen/activity_horizontal_margin"
                android:paddingRight = "@dimen/activity_horizontal_margin"
                android:paddingTop = "@dimen/activity_vertical_margin"
                app:layout_behavior = "@string/appbar_scrolling_view_behavior"
                tools:context = "com.supercilex.myapp.NewForm"
                tools:showIn = "@layout/activity_new_form"
    android:id="@+id/relativeLayout">

    <EditText
        android:id = "@+id/editText"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_alignParentStart = "true"
        android:layout_alignParentTop = "true"
        android:ems = "10"
        android:hint = "Enter some text"
        android:inputType = "textPersonName" />
</RelativeLayout>

这是我的课:

import android.content.ClipData;
import android.content.ClipDescription;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.RelativeLayout;

import common.FileManagement;

public class NewForm extends AppCompatActivity
{
    private static EditText editText;
    private android.widget.RelativeLayout.LayoutParams layoutParams;
    String msg;

    @Override
    protected void onCreate ( Bundle savedInstanceState )
    {
        super.onCreate ( savedInstanceState );
        setContentView ( R.layout.activity_new_form );
        Toolbar toolbar = ( Toolbar ) findViewById ( R.id.toolbar );
        setSupportActionBar ( toolbar );
        editText = ( EditText ) findViewById ( R.id.editText );
        FileManagement fileManagement = new FileManagement ();

        editText.setText ( fileManagement.read ( "textViewData", getApplicationContext () ) );

        FloatingActionButton fab = ( FloatingActionButton ) findViewById ( R.id.fab );
        fab.setOnClickListener ( new View.OnClickListener ()
        {
            @Override
            public void onClick ( View view )
            {
                FileManagement fileManagement = new FileManagement ();
                String tmpEditText = editText.getText ().toString ();
                MainActivity.textView.setText ( tmpEditText );
                fileManagement.save ( "textViewData", tmpEditText, getApplicationContext () );
                finish ();
            }
        } );

        editText.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
                String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN};

                ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
                View.DragShadowBuilder myShadow = new View.DragShadowBuilder(editText);

                v.startDrag(dragData,myShadow,null,0);
                return true;
            }
        });

        editText.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                switch(event.getAction())
                {
                    case DragEvent.ACTION_DRAG_STARTED:
                        layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
                        Log.d(msg, "Action is DragEvent.ACTION_DRAG_STARTED");
                        return true;

                    case DragEvent.ACTION_DRAG_ENTERED:
                        Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENTERED");
                        int x_cord = (int) event.getX();
                        int y_cord = (int) event.getY();
                        return true;

                    case DragEvent.ACTION_DRAG_EXITED :
                        Log.d(msg, "Action is DragEvent.ACTION_DRAG_EXITED");
                        x_cord = (int) event.getX();
                        y_cord = (int) event.getY();
                        layoutParams.leftMargin = x_cord;
                        layoutParams.topMargin = y_cord;
                        v.setLayoutParams(layoutParams);
                        return true;

                    case DragEvent.ACTION_DRAG_LOCATION  :
                        Log.d(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
                        x_cord = (int) event.getX();
                        y_cord = (int) event.getY();
                        return true;

                    case DragEvent.ACTION_DRAG_ENDED   :
                        Log.d ( msg, "Action is DragEvent.ACTION_DRAG_ENDED" );

                        return true;

                    case DragEvent.ACTION_DROP:
                        Log.d( msg, "ACTION_DROP event");
                        return true;
                    default:
                        break;
                }
                return true;
            }
        });

        editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    ClipData data = ClipData.newPlainText("", "");
                    View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(editText);

                    editText.startDrag(data, shadowBuilder, editText, 0);
                    editText.setVisibility(View.INVISIBLE);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        });
    }
}

我也用break; 代替return true; 尝试了我的onDrag 方法 我已经尝试过这种方式:

public boolean onDrag(View v, DragEvent event) {
                switch(event.getAction())
                {
                    case DragEvent.ACTION_DRAG_STARTED:
                        break;

                    case DragEvent.ACTION_DRAG_ENTERED:
                        break;

                    case DragEvent.ACTION_DRAG_EXITED :
                        break;

                    case DragEvent.ACTION_DRAG_LOCATION  :
                        break;

                    case DragEvent.ACTION_DRAG_ENDED   :
                        break;

                    case DragEvent.ACTION_DROP:
                        View view = (View) event.getLocalState();
                        ViewGroup owner = (ViewGroup) view.getParent();
                        owner.removeView(view);
                        FrameLayout container = (FrameLayout) v;
                        container.addView(view);
                        view.setVisibility(View.VISIBLE);
                        Log.d( msg, "ACTION_DROP event");
                        break;
                    default:
                        break;
                }
                return true;
            }

编辑: 这是我更新的代码:

以上onCreate()

private EditText editText;
private RelativeLayout.LayoutParams layoutParams; 

剩下的:

findViewById(R.id.yourlayoutname).setOnDragListener( new View.OnDragListener()
            {
                @Override
                public boolean onDrag ( View v, DragEvent event )
                {
                    if ( event.getAction() == DragEvent.ACTION_DROP )
                    {
                        int xCord = ( int ) event.getX();
                        int yCord = ( int ) event.getY();
                        int height = editText.getHeight();
                        int width = editText.getWidth();
                        layoutParams.leftMargin = xCord - width;
                        layoutParams.topMargin = yCord - height;
                        editText.setLayoutParams( layoutParams );
                    }
                    return true;
                }
            });

            editText.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN};

                    ClipData data = ClipData.newPlainText("", "");
                    View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(editText);

                    v.startDrag( data, shadowBuilder, mimeTypes, 0);
                    return true;
                }
            } );

            editText.setOnDragListener( new View.OnDragListener()
            {
                @Override
                public boolean onDrag ( View v, DragEvent event )
                {
                    if ( event.getAction() == DragEvent.ACTION_DRAG_STARTED )
                    {
                        layoutParams = ( RelativeLayout.LayoutParams ) v.getLayoutParams();
                    }
                    return true;
                }
            } );

【问题讨论】:

    标签: android android-studio drag-and-drop android-emulator android-relativelayout


    【解决方案1】:

    I get this error message in logcat: Reporting drop result: false 这不是错误消息。这意味着 Action drop 没有返回 true 作为 View DragListener 的结果。

    您的 EditText 消失了,因为您在 onTouchListener 中将其设置为不可见 View.INVISIBLE 并且从未将其更改回来。

    试试这个: 首先选择是要通过触摸还是通过长按来拖动。你不需要两者。假设您决定通过触摸来完成:

    editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    ClipData data = ClipData.newPlainText("", "");
                    View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(editText);
    
                    editText.startDrag(data, shadowBuilder, editText, 0);
                    editText.setVisibility(View.INVISIBLE);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        });
    

    从代码监听器中删除所有冗余代码,不需要它到拖动,因为系统会为您处理拖动。如果您希望 Drop 的坐标成为 EditText 的新位置,则需要将 DragListener 分配给 EditText 容器 RelativeLayout 并在 `ACTION_DROP.如果没有:

     editText.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                if (event.getAction == DragEvent.ACTION_DRAG_STARTED){
                        layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
                } else if (event.getAction() ==   DragEvent.ACTION_DRAG_ENDED)
                    v.setVisibility(View.VISIBLE)
    
                return true;
            }
        });
    

    要获得放置位置,您需要类似的东西:

    findViewById(R.id.relativeLayout).setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            if (event.getAction() ==   DragEvent.ACTION_DRAG_DROP){
                 int x_cord = (int) event.getX();
                 int  y_cord = (int) event.getY();
                 layoutParams.leftMargin = x_cord;
                 layoutParams.topMargin = y_cord;
                 editText.setLayoutParams(layoutParams);
    
            }
            return true;
        }
    });
    

    【讨论】:

    • If you want the coordinations of the Drop to be the new location of the EditText than you need to assign DragListener to the EditText container RelativeLayout and retrieve them in ACTION_DROP。如果你能告诉我怎么做,我会很高兴的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多