How to setOnClickListener on a customView inside a Wallpaper Service?

0

I have a class that extends the WallpaperService and inside it i have a CustomView that is being drawn on Canvas. What i want to do is setOnClickListener on this view. Currently i am doing it like customView.SetOnClickListener({}). But its not working.

Below is my Service Class:

public class ClockWallpaperService extends WallpaperService {

@Override
public Engine onCreateEngine() {
    return new ClockWallpaperEngine();
}

private class ClockWallpaperEngine extends Engine implements
        OnSharedPreferenceChangeListener {
    private final Handler handler = new Handler();
    private final Runnable drawRunner = new Runnable() {
        @Override
        public void run() {
            draw();
        }

    };

    private Paint paint;
    /** hands colors for hour, min, sec */
    private int[] colors = { 0xFFFF0000, 0xFF0000FF, 0xFFA2BC13 };
    private int bgColor;
    private int width;
    private int height;
    private boolean visible = true;
    private boolean displayHandSec;
    private AnalogClock clock;
    private SharedPreferences prefs;

    public ClockWallpaperEngine() {
        prefs = PreferenceManager
                .getDefaultSharedPreferences(ClockWallpaperService.this);
        prefs.registerOnSharedPreferenceChangeListener(this);
        displayHandSec = prefs.getBoolean(
                SettingsActivity.DISPLAY_HAND_SEC_KEY, true);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        bgColor = Color.parseColor("#FFFFFF");
        clock = new AnalogClock(getApplicationContext());


        clock.setClickable(true);
        clock.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("CLICED","CLICK");
                Toast.makeText(getApplicationContext(),"CLicked",Toast.LENGTH_SHORT).show();
            }
        });
        handler.post(drawRunner);
    }

    @Override
    public void onVisibilityChanged(boolean visible) {
        this.visible = visible;
        if (visible) {
            handler.post(drawRunner);
        } else {
            handler.removeCallbacks(drawRunner);
        }
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        super.onSurfaceDestroyed(holder);
        this.visible = false;
        handler.removeCallbacks(drawRunner);
        prefs.unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format,
            int width, int height) {
        this.width = width;
        this.height = height;
        super.onSurfaceChanged(holder, format, width, height);
    }

    private void draw() {
        SurfaceHolder holder = getSurfaceHolder();
        Canvas canvas = null;
        try {
            canvas = holder.lockCanvas();
            if (canvas != null) {
                draw(canvas);
            }
        } finally {
            if (canvas != null)
                holder.unlockCanvasAndPost(canvas);
        }

        handler.removeCallbacks(drawRunner);

        if (visible) {
            handler.postDelayed(drawRunner, 200);
        }
    }

    private void draw(Canvas canvas) {
        canvas.drawColor(bgColor);
        clock.config(width / 2, height / 2, (int) (width * 0.6f),
                new Date(), paint, colors, displayHandSec);
        clock.draw(canvas);
    @Override
    public void onSharedPreferenceChanged(
            SharedPreferences sharedPreferences, String key) {
        if (SettingsActivity.DISPLAY_HAND_SEC_KEY.equals(key)) {
            displayHandSec = sharedPreferences.getBoolean(
                    SettingsActivity.DISPLAY_HAND_SEC_KEY, true);
        }
    }

}

And My CustomViewClass:

public class AnalogClock extends View {

/** center X. */
private float x;
/** center Y. */
private float y;

private int radius;
private Calendar cal;
private Paint paint;
private Bitmap clockDial = BitmapFactory.decodeResource(getResources(),
        R.drawable.clocktest);
private int sizeScaled = -1;
private Bitmap clockDialScaled;
/** Hands colors. */
private int[] colors;
private boolean displayHandSec;

public AnalogClock(Context context) {
    super(context);
    cal = Calendar.getInstance();
}

@Override
public boolean performClick() {
    return super.performClick();
}

public void config(float x, float y, int size, Date date, Paint paint, int[] colors, boolean displayHandSec) {
    this.x = x;
    this.y = y;
    this.paint = paint;
    this.colors = colors;
    this.displayHandSec = displayHandSec;

    cal.setTime(date);

    // scale bitmap if needed
    if (size != sizeScaled) {
        clockDialScaled = Bitmap.createScaledBitmap(clockDial, size, size, false);
        radius = size / 2;
    }
}

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

    if (paint != null) {
        // draw clock img
        canvas.drawBitmap(clockDialScaled, x - radius, y - radius, null);

        float sec = cal.get(Calendar.SECOND);
        float min = cal.get(Calendar.MINUTE);
        float hour = cal.get(Calendar.HOUR_OF_DAY);
        //draw hands
        paint.setColor(colors[0]);
        canvas.drawLine(x, y, (float) (x + (radius * 0.5f) * Math.cos(Math.toRadians((hour / 12.0f * 360.0f) - 90f))),
                (float) (y + (radius * 0.5f) * Math.sin(Math.toRadians((hour / 12.0f * 360.0f) - 90f))), paint);
        canvas.save();
        paint.setColor(colors[1]);
        canvas.drawLine(x, y, (float) (x + (radius * 0.6f) * Math.cos(Math.toRadians((min / 60.0f * 360.0f) - 90f))),
                (float) (y + (radius * 0.6f) * Math.sin(Math.toRadians((min / 60.0f * 360.0f) - 90f))), paint);
        canvas.save();

        if (displayHandSec) {
            paint.setColor(colors[2]);
            canvas.drawLine(x, y, (float) (x + (radius * 0.7f) * Math.cos(Math.toRadians((sec / 60.0f * 360.0f) - 90f))),
                (float) (y + (radius * 0.7f) * Math.sin(Math.toRadians((sec / 60.0f * 360.0f) - 90f))), paint);
        }
    }
}

}

java
android
android-studio
live-wallpaper
asked on Stack Overflow Apr 2, 2020 by hamza khan

1 Answer

0

You can create an interface for this e.g. in your CustomView.

interface OnClickInterface {
    void handleMyClick();
}

Now implement this method in your ServiceClass.

public class ClockWallpaperService extends WallpaperService implements AnalogClock.OnClickInterface
...
    @Override
    void handleMyClick() {
        //do your handling
    }

Furthermore, pass an instance of your Service to the customView.

//in ClockWallPaperService
clock = new AnalogClock(getApplicationContext(), this);

Save this instance in your view and than call it at onClick:

//in AnalogClock
public AnalogClock(Context context, OnclickInterface mycallback) {
    super(context);
    cal = Calendar.getInstance();
    this.mycallback = mycallback;
}

Finally, call this interface function in the onClick function this.callback.handleMyClick();

answered on Stack Overflow Apr 2, 2020 by FrontMobe • edited Apr 3, 2020 by FrontMobe

User contributions licensed under CC BY-SA 3.0