samedi 18 juin 2016

Scale and position in bitmap overlay

I am working on a screen that allows user to drag and drop one image onto another. After that the code should be able to redisplay the resulting image and (later) share the resulting image. I am having a hard time making the reddit image normal size and positioned where the user droppped it. More details about it is in bold next to screen 3 below.

Note: all of my images so far are in the drawable folder.

Initial screen: initial screen

After the reddit image was dragged and dropped onto another image: after the reddit image was dragged and dropped onto another image

Here is what the screen looks like after I create an overlay bitmap with 2 bitmaps combined (notice the reddit image that is now smaller and not positioned as in screenshot 2). I am trying to capture the position that user dropped the reddit image to and create an image based on that.

enter image description here

Here is my layout file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:weightSum="1"
android:orientation="vertical"
tools:context=".LobbyActivity">

<FrameLayout
    android:id="@+id/source_layout"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight=".5">

    <ImageView
        android:id="@+id/flatStanleyImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/reddit" />

    <ImageView
        android:id="@+id/postcardImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:visibility="gone" />

</FrameLayout>

<FrameLayout
    android:id="@+id/target_layout"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight=".5">

    <ImageView
        android:id="@+id/attractionImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/attraction"
        android:layout_marginBottom="50dp" />

    <Button
        android:id="@+id/resetButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="reset"
        android:layout_gravity="bottom|left"/>

    <Button
        android:id="@+id/doneButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="done"
        android:layout_gravity="bottom|right"/>
</FrameLayout>
</LinearLayout>

And here is the Java code:

public class LobbyActivity extends AppCompatActivity {

private static final String TAG = "LobbyActivity";

@BindView(R.id.flatStanleyImage)
protected ImageView flatStanleyImageView;

@BindView(R.id.postcardImage)
protected ImageView postcardImageView;

@BindView(R.id.target_layout)
protected FrameLayout targetLayout;

@BindView(R.id.source_layout)
protected FrameLayout sourceLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_lobby);

    ButterKnife.bind(this);

    View.OnLongClickListener longClickListener = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            ClipData clipData = ClipData.newPlainText("", "");
            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
            v.startDrag(clipData, shadowBuilder, v, 0);
            v.setVisibility(View.INVISIBLE); // we are dragging the shadow
            return true;
        }
    };
    flatStanleyImageView.setOnLongClickListener(longClickListener);

    View.OnDragListener dragListener = new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch(event.getAction())
            {
                case DragEvent.ACTION_DRAG_STARTED:
                    Log.d(TAG, "Action is DragEvent.ACTION_DRAG_STARTED");

                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.d(TAG, "Action is DragEvent.ACTION_DRAG_ENTERED");

                case DragEvent.ACTION_DRAG_EXITED:
                    Log.d(TAG, "Action is DragEvent.ACTION_DRAG_EXITED");

                case DragEvent.ACTION_DRAG_LOCATION:
                    Log.d(TAG, "Action is DragEvent.ACTION_DRAG_LOCATION");

                case DragEvent.ACTION_DRAG_ENDED:
                    Log.d(TAG, "Action is DragEvent.ACTION_DRAG_ENDED. DragEvent.getResult() " + event.getResult());
                    if (!event.getResult()) {
                        Log.d(TAG, "Drag was not successful.");
                        flatStanleyImageView.setVisibility(View.VISIBLE);
                    }
                    return true;

                case DragEvent.ACTION_DROP:
                    Log.d(TAG, "Action is DragEvent.ACTION_DROP");

                    FrameLayout draggedImageParentViewLayout = (FrameLayout) flatStanleyImageView.getParent();
                    Log.d(TAG, "draggedImageParentViewLayout: " + draggedImageParentViewLayout.getId());
                    Log.d(TAG, "targetLayout: " + targetLayout.getId());

                    View view = (View) event.getLocalState();
                    float x = event.getX();
                    float y = event.getY();
                    view.setX(x-(view.getWidth()/2));
                    view.setY(y-(view.getWidth()/2));
                    if (draggedImageParentViewLayout != targetLayout) {
                        draggedImageParentViewLayout.removeView(flatStanleyImageView);
                        targetLayout.addView(flatStanleyImageView);
                    }
                    sourceLayout.invalidate();
                    targetLayout.invalidate();
                    return true;

                default:
                    break;
            }
            return false;
        }
    };
    targetLayout.setOnDragListener(dragListener);
}

@OnClick(R.id.resetButton)
protected void handleResetButtonClick() {
    Log.d(TAG, "Begin handleResetButtonClick");

    Intent intent = getIntent();
    finish();
    startActivity(intent);

    Log.d(TAG, "End handleResetButtonClick");
}

@OnClick(R.id.doneButton)
protected void handleDoneButtonClick() {
    Log.d(TAG, "Begin handleDoneButtonClick");

    Bitmap attractionBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.attraction);
    Bitmap flatStanleyBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.reddit);

    Bitmap bitmapOverlay = Bitmap.createBitmap(attractionBitmap.getWidth(), attractionBitmap.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmapOverlay);
    canvas.drawBitmap(attractionBitmap, new Matrix(), null);
    canvas.drawBitmap(flatStanleyBitmap, new Matrix(), null);

    postcardImageView.setImageBitmap(bitmapOverlay);
    postcardImageView.setVisibility(View.VISIBLE);

    Log.d(TAG, "End handleDoneButtonClick");
}
}

Aucun commentaire:

Enregistrer un commentaire