2016-12-16 7 views
19

में एक साधारण छवि दृश्य को खींच और छोड़ नहीं सकता है मैं एंड्रॉइड स्टूडियो में एक साधारण ड्रैग और ड्रॉप छवि बनाने की कोशिश कर रहा हूं। मैं छवि को स्क्रीन के चारों ओर खींचने के लिए प्राप्त कर सकता हूं, जैसे ही मैं इसे रिलीज़ करता हूं, गायब हो जाता है। कंसोल में, मैं एक "रिपोर्टिंग ड्रॉप परिणाम: झूठी" मिलएंड्रॉइड स्टूडियो

यहाँ मेरी कोड है:

ImageView mImageView; 
String mString; 

private android.widget.RelativeLayout.LayoutParams mLayoutParams; 

    mImageView.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(mImageView); 

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

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

        // Do nothing 
        break; 

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

       case DragEvent.ACTION_DRAG_EXITED : 
        Log.d(mString, "Action is DragEvent.ACTION_DRAG_EXITED"); 
        x_cord = (int) event.getX(); 
        y_cord = (int) event.getY(); 
        mLayoutParams.leftMargin = x_cord; 
        mLayoutParams.topMargin = y_cord; 
        v.setLayoutParams(mLayoutParams); 
        break; 

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

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

        // Do nothing 
        break; 

       case DragEvent.ACTION_DROP: 
        Log.d(mString, "ACTION_DROP event"); 

        // Do nothing 
        break; 
       default: break; 
      } 
      return true; 
     } 
    }); 

    mImageView.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(mImageView); 

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

}

उत्तर

5

कोड है कि दिया जाता है कि ठीक करने के लिए आसान हो जाएगा के साथ एक समस्या नहीं है। OnDragListener() गंतव्य (या किसी भी संभावित गंतव्य) दृश्य के लिए सेट किया जाना चाहिए। तो OnLongClickListener() और OnTouchListener() स्रोत दृश्य, imageView पर सेट हैं, तो imageView2OnDragListener() के लिए होना चाहिए। यह एक लंबी व्याख्या है लेकिन एक आसान फिक्स होना चाहिए।

एक अच्छा उदाहरण के लिए drag-drop देखें।

यदि समाधान ठीक से किया जाता है तो शेष समाधान अधिक शामिल होता है (हालांकि, आसपास एक काम है)।

ड्रैग शुरू करते समय, मूल रूप से आपको क्लिपबोर्ड पर छवि कॉपी करने की आवश्यकता होती है, फिर इसे ड्रॉप व्यू में पेस्ट करें। इसके लिए ContentProvider बनाने के बाद ContentResolver (link) का उपयोग करना आवश्यक है।

क्लिपबोर्ड प्रलेखन: ClipData

मैं एप्लिकेशन के लिए यह करने के लिए भविष्य की योजनाओं है, लेकिन है कि जल्द ही इसलिए किसी भी समय हो रहा हो नहीं होगा, दुर्भाग्य से, मैं नहीं किसी भी कोड प्रदान करने के लिए सक्षम हो जाएगा।

हालांकि, एक ऐसा कामकाज है जो बहुत कम शामिल है।

संभावित रूप से स्थानांतरित होने वाली किसी भी छवि पर टैग सेट करें।

imageView.setTag("ImageTag1"); 

onLongClick() में, item और dragData सेट के रूप में प्रश्न में किया जाता है।

फिर OnDragListener() में, टैग पढ़ें, निर्धारित करें कि कौन सी छवि गिराई जा रही है, फिर उस छवि को दृश्य में सेट करें। कुछ ऐसा:

case DragEvent.ACTION_DROP: 
    ClipData.Item item = event.getClipData().getItemAt(0); 
    CharSequence dragData = item.getText(); 

    if(dragData.equals("ImageTag1")) { 
     // this gets jpg image from "drawable" folder, 
     //  set ImageView appropriately for your usage 
     ((ImageView)v).setImageResource(R.drawable.image1);        
    } else if(dragData.equals("ImageTag2")) { 
     ((ImageView)v).setImageResource(R.drawable.image2); 
    } 
    break; 

आपको "ACTION_DRAG_EXITED" मामले में कुछ ऐसा करने की भी आवश्यकता है। अगर छवि किसी अमान्य क्षेत्र में गिरा दी गई है, तो यह छवि को मूल दृश्य में वापस रखती है।

8

संपादित: ऑन टच का उपयोग कर रिलेवेटिवआउट में निहित सभी विचारों को स्थानांतरित करने के तरीके के एक उदाहरण के साथ बदल दिया गया। मुझे लगता है कि ऑन-ड्रैग इवेंट दृश्य वस्तुओं को खींचने के लिए डेटा आइटम खींचने और छोड़ने के लिए बेहतर लागू होता है।

public class MainActivity extends AppCompatActivity implements View.OnTouchListener { 
    private RelativeLayout mRelLay; 
    private float mInitialX, mInitialY; 
    private int mInitialLeft, mInitialTop; 
    private View mMovingView = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mRelLay = (RelativeLayout) findViewById(R.id.relativeLayout); 

     for (int i = 0; i < mRelLay.getChildCount(); i++) 
      mRelLay.getChildAt(i).setOnTouchListener(this); 
    } 

    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) { 
     RelativeLayout.LayoutParams mLayoutParams; 

     switch (motionEvent.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       mMovingView = view; 
       mLayoutParams = (RelativeLayout.LayoutParams) mMovingView.getLayoutParams(); 
       mInitialX = motionEvent.getRawX(); 
       mInitialY = motionEvent.getRawY(); 
       mInitialLeft = mLayoutParams.leftMargin; 
       mInitialTop = mLayoutParams.topMargin; 
       break; 

      case MotionEvent.ACTION_MOVE: 
       if (mMovingView != null) { 
        mLayoutParams = (RelativeLayout.LayoutParams) mMovingView.getLayoutParams(); 
        mLayoutParams.leftMargin = (int) (mInitialLeft + motionEvent.getRawX() - mInitialX); 
        mLayoutParams.topMargin = (int) (mInitialTop + motionEvent.getRawY() - mInitialY); 
        mMovingView.setLayoutParams(mLayoutParams); 
       } 
       break; 

      case MotionEvent.ACTION_UP: 
       mMovingView = null; 
       break; 
     } 

     return true; 
    } 
} 
0

यह कैसे मैं अपने अनुप्रयोग में यह करना है: onTouchListener में इस

"दृश्य" है कि आप खींचें के लिए, सेट करें:

public final class ChoiceTouchListener implements OnTouchListener { 
    Context context; 
    //int index; 
    public static float offsetX = 0,offsetY = 0; 

    DragShadowBuilder shadowBuilder; 

    public ChoiceTouchListener(Context context) { 
     super(); 
     this.context = context; 
     //this.index = index; 
    } 




    public boolean onTouch(View view, MotionEvent motionEvent) { 
     if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 

      //view.setTag("option"+index); 
      ClipData data = ClipData.newPlainText("tag", view.getTag().toString()); 
      shadowBuilder = new View.DragShadowBuilder(view); 

      //start dragging the item touched 
      view.startDrag(data, shadowBuilder, view, 0); 

      offsetX = view.getLeft();//(int)view.getX();//(int)motionEvent.getX(); 
      offsetY = view.getTop();//(int)view.getY();//motionEvent.getY(); 
      view.setVisibility(View.INVISIBLE); 
      Log.v("here","it is ::" + (int)motionEvent.getX() + " , "+(int)motionEvent.getY()); 

      return false; 



     } 

     return true; 

    } 
} 

और यहाँ एक RelativeLayout है कि मध्य में गंतव्य "दृश्य" सेट है और ड्रैग और ड्रॉप ईवेंट के लिए सुनता है:

public class DragLayout extends RelativeLayout { 

    boolean DEBUG = true; 

    AnimationDrawable blenderAnim; 
    Handler handlerAnim2; 
    Context context; 

    private int dimensionInPixel = 200; 
    int screenWidth,screenHeight; 

    public DragLayout(Context context) { 
     super(context); 

     this.context = context; 

     //not to include in main program 
     getDimensionsofScreen(); 

     setLayout(); 
     setViews(); 

    } 



    private void setLayout() { 


     // set according to parent layout (not according to current layout) 
     RelativeLayout.LayoutParams rLp = new RelativeLayout.LayoutParams(
       LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
     rLp.topMargin = 2 * (screenHeight/25); // calculating 1/10 of 4/5 
     // screen 


     this.setLayoutParams(rLp); 

    } 

    void setViews() { 

     ImageView img2 = new ImageView(context); 

     int dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics()); 

     RelativeLayout.LayoutParams rLp = new RelativeLayout.LayoutParams(
       (screenWidth/5), (screenHeight/5)); 
     rLp.topMargin = (screenHeight/10); 
     rLp.leftMargin = (4*screenWidth/10); 
     rLp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); 

     img2.setLayoutParams(rLp); 
     img2.getLayoutParams().height = dimensionInDp; 
     img2.getLayoutParams().width = dimensionInDp; 
     img2.setImageDrawable(getResources().getDrawable(R.drawable.blender_anim)); 
     img2.setOnDragListener(new ChoiceDragListener(context)); 
     this.addView(img2); 

     blenderAnim = (AnimationDrawable)img2.getDrawable(); 
     blenderAnim.setOneShot(true); 
     blenderAnim.stop(); 

    } 


    public ArrayList<Integer> getDimensionsofScreen() { 

     //metrics that holds the value of height and width 
     DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();; 
     ArrayList<Integer> vals = new ArrayList<Integer>(); 

     vals.add(displayMetrics.widthPixels); 
     vals.add(displayMetrics.heightPixels); 
     screenHeight = displayMetrics.heightPixels; 
     screenWidth = displayMetrics.widthPixels; 

     return vals; 
    } 



    @SuppressLint("NewApi") 
    @Override 
    public boolean onDragEvent(DragEvent event) { 

     int mCurX = (int) event.getX(); 
     int mCurY = (int) event.getY(); 

     if(event.getAction() == DragEvent.ACTION_DRAG_STARTED || event.getAction() == DragEvent.ACTION_DRAG_ENTERED) { 
      if (blenderAnim.isRunning()) { 
       blenderAnim.stop(); 
      } else { 
       blenderAnim.run(); 

       handlerAnim2 = new Handler(); 
       handlerAnim2.postDelayed(
         new Runnable(){ 

          @Override 
          public void run() { 
           blenderAnim.stop(); 

          }}, 
         getAnimationDuration(blenderAnim)); 
      } 
     } 

     if(event.getAction() == DragEvent.ACTION_DROP || event.getAction() == DragEvent.ACTION_DRAG_EXITED) { 

      if (blenderAnim.isRunning()) { 
       blenderAnim.stop(); 
      } else { 
       blenderAnim.run(); 

       handlerAnim2 = new Handler(); 
       handlerAnim2.postDelayed(
         new Runnable(){ 

          @Override 
          public void run() { 
           blenderAnim.stop(); 

          }}, 
         getAnimationDuration(blenderAnim)); 
      } 

      Log.v("here", "it is :: " + mCurX + ", " + mCurY); 

      View view1 = (View) event.getLocalState(); 
      view1.setVisibility(View.VISIBLE); 
      ObjectAnimator animationx = ObjectAnimator.ofFloat(view1,"translationX", mCurX - ChoiceTouchListener.offsetX-(screenWidth/10),0.0f); 
      ObjectAnimator animationy = ObjectAnimator.ofFloat(view1, "translationY", mCurY - ChoiceTouchListener.offsetY - (screenHeight/10), 0.0f); 
      AnimatorSet animSet = new AnimatorSet(); 
      animSet.setDuration(500); 
      animSet.playTogether(animationx,animationy); 

      animSet.start(); 

     } 
     if(event.getAction() == DragEvent.ACTION_DROP || event.getAction() == DragEvent.ACTION_DRAG_ENDED){ 
      if(blenderAnim.isRunning()){ 
       blenderAnim.stop(); 
      } 
     } 
     return true; 


    } 

    private int getAnimationDuration(AnimationDrawable src){ 
     int dur = 0; 
     for(int i=0; i<src.getNumberOfFrames(); i++){ 
      dur += src.getDuration(i); 
     } 
     return dur; 
    } 
} 

यह ड्रैग लिस है DragLayout में ImageView के लिए tener:

public class ChoiceDragListener implements View.OnDragListener { 

    boolean DEBUG = true; 
    Context context; 
    public String TAG = "Drag Layout:"; 

    public ChoiceDragListener(Context context){ 
     this.context = context; 
    } 

    @Override 
    public boolean onDrag(View v, DragEvent event) { 
     switch (event.getAction()) { 
      case DragEvent.ACTION_DRAG_STARTED: 
       if(DEBUG) Log.v("here","drag started"); 
       break; 
      case DragEvent.ACTION_DRAG_ENTERED: 
       break; 
      case DragEvent.ACTION_DRAG_LOCATION: 
       int mCurX = (int) event.getX(); 
       int mCurY = (int) event.getY(); 

       if(DEBUG) Log.v("Cur(X, Y) : " ,"here ::" + mCurX + ", " + mCurY); 

       break; 
      case DragEvent.ACTION_DRAG_EXITED: 

       if(DEBUG) 
        Log.v("here","drag exits"); 

       break; 
      case DragEvent.ACTION_DROP: 

       //handle the dragged view being dropped over a drop view 
       View view = (View) event.getLocalState(); 
       ClipData cd = event.getClipData(); 
       ClipData.Item item = cd.getItemAt(0); 
       String resp = item.coerceToText(context).toString(); 

       //view dragged item is being dropped on 
       ImageView dropTarget = (ImageView) v; 

       //view being dragged and dropped 
       final ImageView dropped = (ImageView) view; 

       dropped.setEnabled(false); 

       //if an item has already been dropped here, there will be a tag 
       final Object tag = dropTarget.getTag(); 

       LayoutInflater li = LayoutInflater.from(context); 
       View promptsView = li.inflate(R.layout.ns_scoop_dialog, null); 

       AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
         context); 

       // set prompts.xml to alertdialog builder 
       alertDialogBuilder.setView(promptsView); 

       final EditText userInput = (EditText) promptsView 
         .findViewById(R.id.edit1); 

       // set dialog message 
       alertDialogBuilder 
         .setIcon(R.mipmap.ic_launcher) 
         .setTitle(dropped.getTag().toString()) 
         .setCancelable(false) 
         .setPositiveButton("OK", 
           new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog,int id) { 
             // get user input and set it to result 
             // edit text 
             String inAmt = userInput.getText().toString(); 

             CreateSmoothie.nsList.add(inAmt + " Green Scoops " + dropped.getTag().toString()); 
             Log.d(TAG, inAmt + " Green Scoops " + dropped.getTag().toString() + " added to list"); 

             dialog.dismiss(); 

             //dropped.setEnabled(true); 
            } 
           }) 
         .setNegativeButton("Cancel", 
           new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog, int id) { 
             dialog.cancel(); 

             int existingID = dropped.getId(); 

             //set the original view visible again 
             ((Activity) context).findViewById(existingID).setVisibility(View.VISIBLE); 

             dropped.setEnabled(true); 

            } 
           }); 

       // create alert dialog 
       AlertDialog alertDialog = alertDialogBuilder.create(); 

       // show it 
       alertDialog.show(); 
       //Button nButton = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); 
       //nButton.setBackgroundColor(Color.GREEN); 
       //Button pButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE); 
       //pButton.setBackgroundColor(Color.GREEN); 

       if(tag!=null) 
       { 
        //the tag is the view id already dropped here 
        int existingID = (Integer)tag; 

        //set the original view visible again 
        ((Activity) context).findViewById(existingID).setVisibility(View.VISIBLE); 
       } 

       break; 
      case DragEvent.ACTION_DRAG_ENDED: 

       if(DEBUG) Log.i("drag event", "ended::" + ChoiceTouchListener.offsetX + "," + ChoiceTouchListener.offsetY); 

       /** 
       * returning false so that goes to parentView onDrag function 
       */ 
       return false; 
      //break; 
      default: 
       break; 
     } 
     return true; 
    } 

} 

आशा है कि मदद करता है।

संबंधित मुद्दे