My app has the following view:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" android:layout_gravity="center"> <Button android:id="@+id/rectangle" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="Rectangle" /> <Button android:id="@+id/circle" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="Circle" /> <Button android:id="@+id/triangle" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="Triangle" /> </LinearLayout> <View android:id="@+id/dropzone" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_color"> </View> </LinearLayout>
And the Following activity:
package com.example.dragtest; import androidx.appcompat.app.AppCompatActivity; //import android.graphics.Canvas; //import android.graphics.Paint; //import android.graphics.Path; //import android.graphics.Point; import android.annotation.SuppressLint; import android.app.Fragment; import android.content.ClipData; import android.content.ClipDescription; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Log; import android.view.DragEvent; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.ImageView; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private Button circle=null; private Button rectangle=null; private Button triangle=null; private View dropzone = null; private MyTouchListener touch= new MyTouchListener(); private MyDragListener d =new MyDragListener(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rectangle=(Button)findViewById(R.id.rectangle); rectangle.setOnLongClickListener(touch); // rectangle.setOnDragListener(d); circle=(Button)findViewById(R.id.circle); circle.setOnLongClickListener(touch); // circle.setOnDragListener(d); triangle=(Button)findViewById(R.id.triangle); triangle.setOnLongClickListener(touch); // triangle.setOnDragListener(d); dropzone=(View)findViewById(R.id.dropzone); dropzone.setOnDragListener(d); } private final class MyTouchListener implements View.OnLongClickListener { @SuppressLint("UseCompatLoadingForDrawables") @Override public boolean onLongClick(View v) { final int id = v.getId(); Drawable shadow = null; ClipData.Item shape = null; if(id == R.id.circle) { shape = new ClipData.Item("circle"); shadow = getResources().getDrawable(R.drawable.circle,null); } else if( id == R.id.rectangle) { shape = new ClipData.Item("rectangle"); shadow = getResources().getDrawable(R.drawable.rectangle, null); } else if( id == R.id.triangle ) { shape = new ClipData.Item("circle"); shadow = getResources().getDrawable(R.drawable.triangle, null); } ImageView shadowImage = new ImageView(v.getContext()); shadowImage.setImageDrawable(shadow); Canvas shadowCanvas = new Canvas(); shadow.draw(shadowCanvas); View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v); shadowBuilder.onDrawShadow(shadowCanvas); String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN}; ClipData draggedData = new ClipData(new ClipDescription("ClipData".toString(),mimeTypes),shape); v.startDragAndDrop(draggedData,shadowBuilder,v,0); return true; } } private final class MyDragListener implements View.OnDragListener { public boolean onDrag(View v, DragEvent event) { final int id = v.getId(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: // do nothing Log.v("DROP","Coordinates: "+event.getX()+" , "+event.getY()); break; case DragEvent.ACTION_DRAG_ENTERED: break; case DragEvent.ACTION_DRAG_EXITED: break; case DragEvent.ACTION_DROP: Log.v("DROP","item has been dropped"); ClipData.Item item = event.getClipData().getItemAt(0); String shape = item.getText().toString(); Log.v("DROP","Coordinates: "+event.getX()+" , "+event.getY()); Log.v("DROP","Shape: "+shape); Drawable d = null; switch (shape){ case "cirlce": d = getResources().getDrawable(R.drawable.circle,null); break; case "rectangle": d = getResources().getDrawable(R.drawable.rectangle,null); break; case "triangle": d = getResources().getDrawable(R.drawable.triangle,null); break; } Context ctx = v.getContext(); ImageView img = new ImageView(ctx); img.setImageDrawable(d); img.setX(event.getX()); img.setY(event.getY()); ArrayList<View> items = new ArrayList<View>(); items.add(img); v.addTouchables(items); break; case DragEvent.ACTION_DRAG_ENDED: default: break; } return true; } } }
At the following lines:
Context ctx = v.getContext(); ImageView img = new ImageView(ctx); img.setImageDrawable(d); img.setX(event.getX()); img.setY(event.getY()); ArrayList<View> items = new ArrayList<View>(); items.add(img); v.addTouchables(items);
I try to place an image into a view but I fail to do so. My aim with this activity is to draw and reposition some items on a Custom Layout? What I want is some sort of view where I can position the ImageView.
Do you know how I can do that?
Advertisement
Answer
The appropiate layout is the ConstraintLayout
And the reason why is because it allows you to position an item to specific X and Y positions.
The activity view should be:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" android:layout_gravity="center"> <Button android:id="@+id/rectangle" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="Rectangle" /> <Button android:id="@+id/circle" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="Circle" /> <Button android:id="@+id/triangle" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="Triangle" /> </LinearLayout> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/dropzone" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_color"> </androidx.constraintlayout.widget.ConstraintLayout> </LinearLayout>
So in the onDrag action to be able to do:
public boolean onDrag(View v, DragEvent event) { final int id = v.getId(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: // do nothing Log.v("DROP","Coordinates: "+event.getX()+" , "+event.getY()); break; case DragEvent.ACTION_DRAG_ENTERED: break; case DragEvent.ACTION_DRAG_EXITED: break; case DragEvent.ACTION_DROP: Log.v("DROP","item has been dropped"); ClipData.Item item = event.getClipData().getItemAt(0); String shape = item.getText().toString(); Log.v("DROP","Coordinates: "+event.getX()+" , "+event.getY()); Log.v("DROP","Shape: "+shape); Drawable d = null; switch (shape){ case "circle": d = getResources().getDrawable(R.drawable.circle,null); break; case "rectangle": d = getResources().getDrawable(R.drawable.rectangle,null); break; case "triangle": d = getResources().getDrawable(R.drawable.triangle,null); break; } Context ctx = v.getContext(); ImageView img = new ImageView(ctx); img.setImageDrawable(d); img.setX(event.getX()); img.setY(event.getY()); ConstraintLayout layout = (ConstraintLayout)v; layout.addView(img); break; case DragEvent.ACTION_DRAG_ENDED: default: break; } return true; }
Pay attention to the following lines:
Context ctx = v.getContext(); ImageView img = new ImageView(ctx); img.setImageDrawable(d); img.setX(event.getX()); img.setY(event.getY()); ConstraintLayout layout = (ConstraintLayout)v; layout.addView(img);