My app has the following view:
JavaScript
x
<?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:
JavaScript
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:
JavaScript
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:
JavaScript
<?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:
JavaScript
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:
JavaScript
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);