简体   繁体   中英

Android Spotlight Always on Corner point

same the sample but in my project , spotlight always show in corner what should i do ? or any offer for this same library?

here is my code

    View one = findViewById(R.id.img_drawer);
        int[] oneLocation = new int[2];
        one.getLocationInWindow(oneLocation);
        float oneX = oneLocation[0] + one.getWidth() / 2f;
        float oneY = oneLocation[1] + one.getHeight() / 2f;
        // make an target
        SimpleTarget firstTarget = new SimpleTarget.Builder(TripActivity.this).setPoint(oneX, oneY)
                .setRadius(100f)
                .setTitle("first title")
                .setDescription("first description")
                .build();
Spotlight.with(TripActivity.this)
                .setDuration(1000L)
                .setAnimation(new DecelerateInterpolator(2f))
                .setTargets(firstTarget)
                .setOnSpotlightStartedListener(new OnSpotlightStartedListener() {
                    @Override
                    public void onStarted() {
                        Toast.makeText(TripActivity.this, "spotlight is started", Toast.LENGTH_SHORT)
                                .show();
                    }
                })
                .setOnSpotlightEndedListener(new OnSpotlightEndedListener() {
                    @Override
                    public void onEnded() {
                        Toast.makeText(TripActivity.this, "spotlight is ended", Toast.LENGTH_SHORT).show();
                    }
                })
                .start();

and pictures图一

图二

Actually your spotlight target is getting created before the target view is actually inflated and created. To overcome this issue, you must create your spotlight target only once the view is inflated.

View one = findViewById(R.id.img_drawer);
int[] oneLocation = new int[2];
one.getLocationInWindow(oneLocation);
float oneX = oneLocation[0] + one.getWidth() / 2f;
float oneY = oneLocation[1] + one.getHeight() / 2f;

so in above code sample, oneX and oneY is coming as 0 and so your spotlight target is moving to top-left corner and only a quarter is visible.

Make use of post method, which can be called from any view. Post method takes a runnable thread and makes sure that everything in this post runnable is executed once the view is properly inflated.

// create globally
SimpleTarget firstTarget = null;

// do this in onCreate of Activity or in onCreateView of Fragment
View one = findViewById(R.id.img_drawer);

one.post(new Runnable(){
    @Override
    public void run(){
        int[] oneLocation = new int[2];
        one.getLocationInWindow(oneLocation);
        float oneX = oneLocation[0] + one.getWidth() / 2f;
        float oneY = oneLocation[1] + one.getHeight() / 2f;

        // make a target
        firstTarget = new SimpleTarget.Builder(TripActivity.this)
            .setPoint(oneX, oneY)
            .setRadius(100f)
            .setTitle("first title")
            .setDescription("first description")
            .build();
    }
});

// Do this in onStart of Activity or in onViewCreated of Fragment
if (firstTarget != null)
    Spotlight.with(TripActivity.this)
        .setDuration(1000L)
        .setAnimation(new DecelerateInterpolator(2f))
        .setTargets(firstTarget)
        .setOnSpotlightStartedListener(new OnSpotlightStartedListener() {
            @Override
            public void onStarted() {
                Toast.makeText(TripActivity.this, "spotlight is started", Toast.LENGTH_SHORT).show();
            }
        })
        .setOnSpotlightEndedListener(new OnSpotlightEndedListener() {
            @Override
            public void onEnded() {
                Toast.makeText(TripActivity.this, "spotlight is ended", Toast.LENGTH_SHORT).show();
            }
        })
        .start();

Your view was not ready yet, You have to call it in doOnPreDraw (I'm using core-ktx lib)

 binding.root.doOnPreDraw {
        showSpotlight() // call it here
 }

The reason behind this is the view (element which you want to highlight) is not yet drawn into your root layout and you are trying to add spotlight on that.

The solution is below which solved my problem.

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override public void onGlobalLayout() {
        view.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        SimpleTarget target = new SimpleTarget.Builder(activity)
                .setPoint(view)
                .setRadius(radius)
                .setTitle(title)
                .setDescription(description)
                .build();

        Spotlight.with(activity)
                .setDuration(500L)
                .setDuration(500L)
                .setAnimation(new DecelerateInterpolator(1f))
                .setTargets(target)
                .setOnSpotlightStartedListener(new OnSpotlightStartedListener() {
                    @Override
                    public void onStarted() {

                    }
                })
                .setOnSpotlightEndedListener(new OnSpotlightEndedListener() {
                    @Override
                    public void onEnded() {
                        App.getLocalStorage().write(sharedPrefKey, true);
                    }
                })
                .start();

    }
});

Find your root layout from your xml file then

rootlayout.post { //write your code for creating targets and spotlight }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM