Question

I have a surfaceview that displays a background image and a crosshair that appears on the coordinates where the user touches the screen.

I have two problems.

1) The screen is black until I touch the screen, and at that moment both images are drawn on the screen and it works fine. Why is the screen black until I touch it?

2) How can I use my own xml layout?

I have tried using setContentView(R.layout.image_edit_activity);

and having a framelayout like this:

   <?xml version="1.0" encoding="utf-8"?>
   <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent" >

 <com.effbe.accelerometer.ImageEditActivity.Crosshair
    android:id="@+id/surfaceView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="114dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/ok_button"
        android:padding="10dp"
        android:paddingLeft="10dip"
        android:text="OK"
        android:textColor="#ffffff" />
    </LinearLayout>

    </FrameLayout>

But I have not been able to solve this problem.

     public class ImageEditActivity extends Activity {

public String reportDate;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    reportDate = intent.getStringExtra("reportDate");

    int w = getWindowManager().getDefaultDisplay().getWidth() - 25;
    int h = getWindowManager().getDefaultDisplay().getHeight() - 25;

    Crosshair crosshairView = new Crosshair(this, w, h, reportDate);

    setContentView(crosshairView);
      }
       } 

    class Crosshair extends SurfaceView implements SurfaceHolder.Callback {
private Bitmap bitmap;
private int x = 20, y = 20;
int width, height;
String reportDate1;

public Crosshair(Context context, int w, int h, String reportDate) {
    super(context);

    reportDate1 = reportDate;
    width = w;
    height = h;
    getHolder().addCallback(this);
    setFocusable(true);
}

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

}

public Crosshair(Context context, int w, int h) {
    super(context);

}

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    String path = Environment.getExternalStorageDirectory()
            .getAbsolutePath()
            + "/VibrationMeasurement/"
            + reportDate1
            + ".machine" + ".jpg";

    Bitmap bitmap2 = BitmapFactory.decodeFile(path);

    Bitmap scaled = Bitmap.createScaledBitmap(bitmap2, width, height, true);

    bitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.crosshair);

    // canvas.drawColor(Color.BLUE);//To make background
    canvas.drawBitmap(scaled, 0, 0, null);
    canvas.drawBitmap(bitmap, x - (bitmap.getWidth() / 2),
            y - (bitmap.getHeight() / 2), null);

    // canvas.drawBitmap(;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    x = (int) event.getX();
    y = (int) event.getY();

    if (x < 25)
        x = 25;
    if (x > width)
        x = width;
    if (y < 25)
        y = 25;
    if (y > height)
        y = height;

    updateCrosshair();

    return true;
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
}

private void updateCrosshair() {
    Canvas canvas = null;
    try {
        canvas = getHolder().lockCanvas(null);
        synchronized (getHolder()) {
            this.onDraw(canvas);
        }
    } finally {
        if (canvas != null) {
            getHolder().unlockCanvasAndPost(canvas);
        }
    }

}

}

Was it helpful?

Solution

This should sort you out.

activity_image_edit.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <view
        class="com.effbe.accelerometer.ImageEditActivity$CrosshairView"
        android:id="@+id/crosshairView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <Button
            android:id="@+id/button1"
            android:layout_width="114dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:padding="10dp"
            android:paddingLeft="10dip"
            android:background="@drawable/ok_button"
            android:text="OK"
            android:textColor="#ffffff"
            />
    </LinearLayout>
</FrameLayout>

ImageEditActivity.java

package com.effbe.accelerometer;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Toast;


public class ImageEditActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        String reportDate = getIntent().getStringExtra("reportDate");
        String reportPath = Environment.getExternalStorageDirectory().getAbsolutePath() + 
            "/VibrationMeasurement/" + reportDate + ".machine" + ".jpg";

        setContentView(R.layout.activity_image_edit);

        CrosshairView crosshairView = (CrosshairView)findViewById(R.id.crosshairView);
        crosshairView.setImagePath(reportPath);
        crosshairView.setOnCrosshairChanged(new CrosshairView.OnCrosshairChanged()
        {
            @Override
            public void onCrosshairChanged(CrosshairView view, int x, int y, int w, int h)
            {
                Toast.makeText(view.getContext(), "Pos: " + x + ", " + y, Toast.LENGTH_SHORT).show();
            }
        });
    }


    public static class CrosshairView extends ImageView
    {
        private static final String TAG = CrosshairView.class.getSimpleName();

        private Drawable mCrosshairDrawable;
        private int mCrosshairX = -1;
        private int mCrosshairY = -1;

        private OnCrosshairChanged mListener;

        private String mImagePath;


        public CrosshairView(Context context)
        {
            super(context);
            initView(context, null);
        }

        public CrosshairView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            initView(context, attrs);
        }

        public CrosshairView(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            initView(context, attrs);
        }

        protected void initView(Context context, AttributeSet attrs)
        {
            mCrosshairDrawable = getResources().getDrawable(R.drawable.crosshair);
        }

        public void setOnCrosshairChanged(OnCrosshairChanged listener)
        {
            mListener = listener;
        }

        public void setImagePath(String imagePath)
        {
            mImagePath = imagePath;
            updateImage();
        }

        public String getImagePath()
        {
            return mImagePath;
        }

        public int getCrosshairX()
        {
            return mCrosshairX;
        }

        public int getCrosshairY()
        {
            return mCrosshairY;
        }

        private void updateImage()
        {
            int width = getWidth();
            int height = getHeight();

            if(width == 0 || height == 0){
                return;
            }

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(mImagePath, options);
            options.inSampleSize = calculateInSampleSize(options, width, height);
            options.inJustDecodeBounds = false;
            setImageBitmap(BitmapFactory.decodeFile(mImagePath, options));
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh)
        {
            super.onSizeChanged(w, h, oldw, oldh);
            if(mCrosshairX < 0 || mCrosshairY < 0){
                mCrosshairX = w / 2;
                mCrosshairY = h / 2;
            }
            updateImage();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            final int action = event.getAction();
            if(action != MotionEvent.ACTION_CANCEL){
                mCrosshairX = (int)event.getX();
                mCrosshairY = (int)event.getY();
                if(action == MotionEvent.ACTION_UP){
                    if(mListener != null){
                        mListener.onCrosshairChanged(this, mCrosshairX, mCrosshairY, getWidth(), getHeight());
                    }
                }
                postInvalidate();
            }

            return true;
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            super.onDraw(canvas);
            final int w2 = mCrosshairDrawable.getIntrinsicWidth() / 2;
            final int h2 = mCrosshairDrawable.getIntrinsicHeight() / 2;
            mCrosshairDrawable.setBounds(mCrosshairX - w2, mCrosshairY - h2, mCrosshairX + w2, mCrosshairY + h2);
            mCrosshairDrawable.draw(canvas);
        }

        private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
        {
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
            if(height > reqHeight || width > reqWidth){
                final int halfHeight = height / 2;
                final int halfWidth = width / 2;
                while((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth){
                    inSampleSize *= 2;
                }
            }
            return inSampleSize;
        }


        public static interface OnCrosshairChanged
        {
            public void onCrosshairChanged(CrosshairView view, int x, int y, int w, int h);
        }
    }
}

OTHER TIPS

Maybe this?

@Override
public void surfaceCreated(SurfaceHolder holder) {
    updateCrosshair();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top