Android Open Source - Spotlight View Actor






From Project

Back to project page Spotlight.

License

The source code is released under:

Apache License

If you think the Android project Spotlight listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 Copyright 2013 Andrew Mahone//  w w w .j a  v a 2s.  co m

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

package us.looking_glass.spotlight.actor;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.util.Log;
import android.view.View;

import java.sql.BatchUpdateException;

import us.looking_glass.spotlight.Stage;

public class ViewActor implements Actor {
    private final static String TAG = ViewActor.class.getSimpleName();
    final static boolean debug = true;
    private final Context context;
    private Point center = new Point();
    private float radius = 0;
    private Stage host;
    private final View view;
    private final int spotlightPlacement;
    private final float spotlightSize;
    private final float innerPadding;
    private boolean dirty = true;
    public static final int AROUND = 1;
    public static final int INSIDE = 2;
    public static final int FIXED = 3;
    Object listener = null;

    public ViewActor(Context context, View view, int placement, float size, float innerPadding) {
        this.context = context;
        this.view = view;
        spotlightPlacement = placement;
        spotlightSize = size;
        this.innerPadding = innerPadding;
    }

    private void update() {
        if (!dirty)
            return;
        int[] hostOffset = new int[2];
        int[] targetOffset = new int[2];
        host.getLocationOnScreen(hostOffset);
        view.getLocationOnScreen(targetOffset);
        int targetWidth = view.getMeasuredWidth();
        int targetHeight = view.getMeasuredHeight();
        int x = targetOffset[0] - hostOffset[0] + targetWidth / 2;
        int y = targetOffset[1] - hostOffset[1] + targetHeight / 2;
        float size = 1;
        switch (spotlightPlacement) {
            case AROUND:
                size = (float) Math.sqrt(targetHeight * targetHeight + targetWidth * targetWidth) / 2;
                size = size * spotlightSize + innerPadding;
                break;
            case INSIDE:
                size = Math.min(targetWidth, targetHeight) / 2 - host.getSpotlight().getBorder();
                size = size * spotlightSize - innerPadding;
                break;
            case FIXED:
                size = spotlightSize;
                break;
        }
        center.x = x;
        center.y = y;
        radius = size;
        Logv("Target size: %dx%d radius: %f", targetWidth, targetHeight, radius);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            dirty = false;
    }

    @Override
    public Point getPosition() {
        if (view == null || view.getVisibility() == View.GONE)
            return null;
        update();
        return center;
    }

    @Override
    public float getRadius() {
        return radius;
    }

    @Override
    public void show(Stage host) {
        this.host = host;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            addListener();
    }

    @Override
    public void hide() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            removeListener();
        if (host != null)
            host = null;
    }

    public static class Builder {
        private final Context context;
        private View view = null;
        private int spotlightPlacement = AROUND;
        private float spotlightSize = 1;
        private final float defaultInnerPadding;
        private float innerPadding;

        public Builder(Context context) {
            this.context = context;
            defaultInnerPadding = context.getResources().getDisplayMetrics().density * 2;
            innerPadding = defaultInnerPadding;
        }

        public Builder setView(View view) {
            this.view = view;
            return this;
        }

        public Builder setView(int id) {
            this.view = ((Activity) context).findViewById(id);
            return this;
        }

        public Builder setPlacement(int spotlightPlacement) {
            this.spotlightPlacement = spotlightPlacement;
            return this;
        }

        public Builder setSize(float spotlightSize) {
            this.spotlightSize = spotlightSize;
            return this;
        }

        public void clear() {
            view = null;
            spotlightPlacement = AROUND;
            spotlightSize = 1;
            innerPadding = defaultInnerPadding;
        }

        public Actor build() {
            return new ViewActor(context, view, spotlightPlacement, spotlightSize, innerPadding);
        }
    }

    private static final void Logd(String text, Object... args) {
        if (debug) {
            if (args != null && args.length > 0)
                text = String.format(text, args);
            Log.d(TAG, text);
        }
    }

    private static final void Logv(String text, Object... args) {
        if (debug) {
            if (args != null && args.length > 0)
                text = String.format(text, args);
            Log.v(TAG, text);
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void addListener() {
        if (host == null || view == null)
            return;
        listener = new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                Logv("layout changed");
                dirty = true;
                if (host != null)
                    host.forceLayout();
            }
        };
        view.addOnLayoutChangeListener((View.OnLayoutChangeListener) listener);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void removeListener() {
        if (host == null || view == null || listener == null)
            return;
        view.removeOnLayoutChangeListener((View.OnLayoutChangeListener) listener);
        listener = null;
    }
}




Java Source Code List

us.looking_glass.spotlight.Script.java
us.looking_glass.spotlight.Stage.java
us.looking_glass.spotlight.actor.Actor.java
us.looking_glass.spotlight.actor.ViewActor.java
us.looking_glass.spotlight.demo.DemoActivity.java
us.looking_glass.spotlight.draw.RingSpotlight.java
us.looking_glass.spotlight.draw.Spotlight.java