#java #android #touch-event #ontouchlistener
#java #Android #касание-событие #ontouchlistener
Вопрос:
итак, я создал приложение, которое используется bitmap
в canvas
качестве шаблона, и я хочу, чтобы пользователь мог добавлять изображения из галереи, а затем масштабировать, позиционировать и поворачивать. в настоящее время застрял в imageView
правильном позиционировании, когда я перетаскиваю в другую позицию imageView
, она немного отклоняется от позиции, в которую я поместил.
вот xml
мой проект для демонстрации структуры макета:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".search.CreateActivity">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
tools:layout_editor_absoluteX="283dp">
<!-- reault_layout contains layout and imageView:
layout for canvas the contains bitmap
layout for the image added by the user -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@ id/result_layout"
android:layout_width="512dp"
android:layout_height="512dp"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@ id/canvas_layout"
android:layout_width="512dp"
android:layout_height="512dp">
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@ id/iv_promo"
android:layout_width="100dp"
android:layout_height="100dp"
app:srcCompat="..."/>
</androidx.constraintlayout.widget.ConstraintLayout>
</HorizontalScrollView>
<!-- this button to add the image -->
<Button
android:id="@ id/add_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- this button saves whatever in the result layout as image in internal storage-->
<Button
android:id="@ id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
другая проблема заключается в том, imageView
что при прокрутке изображение не может быть помещено в крайнем правом углу, оно размещается только в видимой области экрана перед прокруткой.
Я установил ширину и высоту макета холста на 512dp, потому что его фактическое значение для рисования равно 512dpx512dp, и если я установлю для него значение match_parent, может стать меньше и сложнее размещать небольшие изображения в определенных областях внутри шаблона.
Для отрисовки шаблона я поместил эти две строки внутрь onCreate();
create_canvas = new CreateCanvas(this);
nCanvas_layout.addView(create_canvas);
Я не использовал setContentView();
, чтобы не рисовать шаблон на всем макете, поэтому он будет отображаться внутри canvas_layout
вот CreateCanvas
класс, который рисует шаблон:
public class CreateCanvas extends View {
Drawable temp_drawable
Bitmap temp_bitmap
public CreateCanvas(Context context) {
super(context);
this.context = context;
// DRAWABLE OF THE TEMPLATE
temp_drawable = ContextCompat.getDrawable(context, R.drawable.ic_template_master);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//drawableToBitmap() IS A CUSTOM METHOD TO CONVERT THE DRAWABLE TEMPLATE TO BITMAP
// RETURNS BITMAP
temp_bitmap = drawableToBitmap(temp_drawable);
// DRAWS THE TEMPLATE INTO CANVAS
canvas.drawBitmap(temp_bitmap, left, top, null);
}
// THE CUSTOM METHOD TO CONVERT DRAWABLE TO BITMAP
public Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
bitmap.setHeight(getWidth());
bitmap.setWidth(getWidth());
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
приведенный выше класс помогает в создании шаблона canvas_layout
, ниже canvas_layout
есть imageView
место, где пользователь может загрузить изображение из внутреннего хранилища.
Я добавил их implements
, чтобы получать события касания пользователя implements View.OnTouchListener, View.OnDragListener, GestureDetector.OnGestureListener
затем получил эти @overrides
методы:
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// the imageView that host the image added by user: iv_promo
if (view.getId() == R.id.iv_promo)
{
nGestureDetector.onTouchEvent(motionEvent);
return true;
}
return true;
}
@Override
public boolean onDown(MotionEvent motionEvent) {return false;}
@Override
public void onShowPress(MotionEvent motionEvent) {}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {return false;}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {return false;}
@Override
public void onLongPress(MotionEvent motionEvent) {
View.DragShadowBuilder builder = new View.DragShadowBuilder(nIv_promo);
nIv_promo.startDragAndDrop(null, builder, null, 0);
builder.getView().setOnDragListener(this);
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {return false;}
@Override
public boolean onDrag(View view, DragEvent dragEvent) {
// I was trying thses outside if-statment to check if its working, but did not work
//nIv_promo.setX(dragEvent.getX()-(nIv_promo.getWidth()/2f));
//nIv_promo.setY(dragEvent.getY()-(nIv_promo.getHeight()/2f));
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_STARTED)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION)
{
//nIv_promo.setX(dragEvent.getX());
//nIv_promo.setY(dragEvent.getY());
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_EXITED)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DROP)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_ENDED)
{
nIv_promo.setX(dragEvent.getX()-(nIv_promo.getWidth()/2f));
nIv_promo.setY(dragEvent.getY()-(nIv_promo.getHeight()/2f));
}
return true;
}
Мне не понравился DragShadowBuilder(), я хотел перетащить фактический ImageView
и переместить в другую позицию на экране. но я слишком поглощен точным размещением ImageView. если возможно, пожалуйста, помогите мне с этим тоже