3

我正在嘗試創建一個表單,用戶可以在其中移動輸入。我有一個editText,並希望它能夠將它移動到我的relativeLayout中的新位置。我能夠把它撿起來並移動它,但是一旦我放開它,它就會完全消失。我已經嘗試了幾乎所有的東西。我認爲onDrag方法可能永遠不會被調用,因爲我的日誌從不出現。另外,放開我的editText後,我在logcat中得到這個錯誤信息:Reporting drop result: falseAndroid:拖放後,被拖動的editText消失

我一直在遇到的另一個問題是,當你點擊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; 
       } 
      } 
     }); 
    } 
} 

我也試過ondrag當我與方法的break;代替return true; 我已經試過了這個方式:

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

回答

0

I get this error message in logcat: Reporting drop result: false 這不是錯誤消息。這意味着由於ViewDragListener的結果,Action drop不返回true

您的EditText消失,因爲您將其設置爲不可見View.INVISIBLE在您的onTouchListener之內並且永不改變它。

試試這個: 首先選擇是否要觸摸拖動或長按。你不需要兩個。比方說,你決定通過觸摸來做到這一點:

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

從代碼監聽器刪除所有reduntant代碼,不需要它來拖動作爲系統處理拖累你。如果您希望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; 
    } 
}); 
+0

'如果你想刪除的配位是EditText上的新位置比你需要分配DragListener到EditText容器的RelativeLayout並在ACTION_DROP'中檢索它們。如果你能告訴我該怎麼做,我會很喜歡它。 – SUPERCILEX

+1

謝謝!我將您的答案標記爲已接受並+1。 :) – SUPERCILEX