Spotlight
Spotlight copied to clipboard
How to create custom text overlay for each individual element
let's say, i have 4 buttons, A, B, C, D, everytime i click to one of them, something will pop up, how do i change the change and draw and whatever i want for each of them? i have read your comments about still havent figured out the way to do it!!!
this is my code: those buttons are filters to apply for photos in my projects: If i tried to setText()
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
new Handler().post(() -> {
List<Target> targets = new ArrayList<>();
FrameLayout firstRoot = new FrameLayout(this);
View firstLayout = LayoutInflater.from(this).inflate(R.layout.instruction_layout, firstRoot);
Rect offsetViewBounds = new Rect();
binding.ivOriginalMode.getDrawingRect(offsetViewBounds);
binding.enhanceContainer.offsetDescendantRectToMyCoords(binding.ivOriginalMode, offsetViewBounds);
float a = offsetViewBounds.centerX();
float b = offsetViewBounds.centerY();
Target originalTarget = new Target.Builder()
.setAnchor(a, b)
.setShape(new Circle(62f, 500L, new DecelerateInterpolator(2f)))
.setEffect((new RippleEffect(80f, 100f, (30), 124, new DecelerateInterpolator(2f), 90)))
.setOverlay(firstLayout)
.setOnTargetListener(new OnTargetListener() {
@Override
public void onStarted() {
Toast.makeText(EnhanceActivity.this, "first target start", Toast.LENGTH_SHORT).show();
}
@Override
public void onEnded() {
Toast.makeText(EnhanceActivity.this, "first target end", Toast.LENGTH_SHORT).show();
}
}).build();
targets.add(originalTarget);
Rect offsetViewBounds1 = new Rect();
//returns the visible bounds
binding.ivGreyScaleMode.getDrawingRect(offsetViewBounds1);
// calculates the relative coordinates to the parent
binding.enhanceContainer.offsetDescendantRectToMyCoords(binding.ivGreyScaleMode, offsetViewBounds1);
float a1 = offsetViewBounds1.centerX();
float b1 = offsetViewBounds1.centerY();
FrameLayout secondRoot = new FrameLayout(this);
View secondLayout = LayoutInflater.from(this).inflate(R.layout.instruction_layout, secondRoot);
Target grayScaleTarget = new Target.Builder()
.setAnchor(a1, b1)
.setShape(new Circle(62f, 500L, new DecelerateInterpolator(2f)))
.setEffect((new RippleEffect(80f, 100f, (30), 124, new DecelerateInterpolator(2f), 90)))
.setOverlay(secondLayout)
.setOnTargetListener(new OnTargetListener() {
@Override
public void onStarted() {
Toast.makeText(EnhanceActivity.this, "second target start", Toast.LENGTH_SHORT).show();
}
@Override
public void onEnded() {
Toast.makeText(EnhanceActivity.this, "second target end", Toast.LENGTH_SHORT).show();
}
}).build();
targets.add(grayScaleTarget);
Rect offsetViewBounds2 = new Rect();
//returns the visible bounds
binding.ivGreyScaleMode.getDrawingRect(offsetViewBounds2);
// calculates the relative coordinates to the parent
binding.enhanceContainer.offsetDescendantRectToMyCoords(binding.ivMagicColorMode, offsetViewBounds2);
float a2 = offsetViewBounds2.centerX();
float b2 = offsetViewBounds2.centerY();
FrameLayout thirdRoot = new FrameLayout(this);
View thirdLayout = LayoutInflater.from(this).inflate(R.layout.instruction_layout, thirdRoot);
Target magicColorTarget = new Target.Builder()
.setAnchor(a2, b2)
.setShape(new Circle(62f, 500L, new DecelerateInterpolator(2f)))
.setEffect((new RippleEffect(80f, 100f, (30), 124, new DecelerateInterpolator(2f), 90)))
.setOverlay(thirdLayout)
.setOnTargetListener(new OnTargetListener() {
@Override
public void onStarted() {
Toast.makeText(EnhanceActivity.this, "third target start", Toast.LENGTH_SHORT).show();
}
@Override
public void onEnded() {
Toast.makeText(EnhanceActivity.this, "third target end", Toast.LENGTH_SHORT).show();
}
}).build();
targets.add(magicColorTarget);
Rect offsetViewBounds3 = new Rect();
//returns the visible bounds
binding.ivGreyScaleMode.getDrawingRect(offsetViewBounds3);
// calculates the relative coordinates to the parent
binding.enhanceContainer.offsetDescendantRectToMyCoords(binding.ivBlackAndWhiteMode, offsetViewBounds3);
float a3 = offsetViewBounds3.centerX();
float b3 = offsetViewBounds3.centerY();
FrameLayout fouthRoot = new FrameLayout(this);
View fouthView = LayoutInflater.from(this).inflate(R.layout.instruction_layout, fouthRoot);
Target blackAndWhiteTarget = new Target.Builder()
.setAnchor(a3, b3)
.setShape(new Circle(62f, 500L, new DecelerateInterpolator(2f)))
.setEffect((new RippleEffect(80f, 100f, (30), 124, new DecelerateInterpolator(2f), 90)))
.setOverlay(fouthView)
.setOnTargetListener(new OnTargetListener() {
@Override
public void onStarted() {
Toast.makeText(EnhanceActivity.this, "third target start", Toast.LENGTH_SHORT).show();
}
@Override
public void onEnded() {
originalText.setVisibility(View.GONE);
Toast.makeText(EnhanceActivity.this, "third target end", Toast.LENGTH_SHORT).show();
}
}).build();
targets.add(blackAndWhiteTarget);
// create spotlights
spotlight = new Spotlight.Builder(this)
.setTargets(targets)
.setBackgroundColor(R.color.spotlightBackground)
.setDuration(1000L)
.setAnimation(new DecelerateInterpolator(2f))
.setContainer(findViewById(R.id.enhance_container))
.setOnSpotlightListener(new OnSpotlightListener() {
@Override
public void onStarted() {
Toast.makeText(EnhanceActivity.this, "spotLight started", Toast.LENGTH_SHORT).show();
}
@Override
public void onEnded() {
Toast.makeText(EnhanceActivity.this, "spotLight started", Toast.LENGTH_SHORT).show();
}
}).build();
spotlight.start();
firstLayout.findViewById(R.id.close_target).setOnClickListener(view -> {
originalText.setVisibility(View.GONE);
spotlight.next();
}
);
secondLayout.findViewById(R.id.close_target).setOnClickListener(view -> {
tvGrayScale.setVisibility(View.VISIBLE);
spotlight.next();
});
thirdLayout.findViewById(R.id.close_target).setOnClickListener(view -> spotlight.finish());
});
}
I want to do like the one you did here: for each button, i want to have its own text and description
I read some comments and you said setOverLay() for each target, does it mean for 4 buttons, i need to duplicate the same overlay with different text for 4 times, 1 button needs 1 layout ? If i misunderstood your lines, please correct my understanding!
this part, i tried to make some view gone , the other appeared on the same layout but it didnt work that way, then it crashed
I do not understand what you are trying to do and what is the problem.
Could you clarify a bit more about these?
- What you want to do.
- The problem you have.
- The expected behavior when
2
happens.
@theherrsherofthunder You need to feed diferent layouts for the inflater, not this one R.layout.instruction_layout
Or you could modify it after it has been inflated, like:
View firstLayout = LayoutInflater.from(this).inflate(R.layout.instruction_layout, firstRoot);
firstLayout.findViewById<View>(R.id.your_title_field).let {
it.text = "Your text for the first slide"
}
secondLayout.findViewById<View>(R.id.your_title_field).let {
it.text = "Your text for the second slide"
}