ViewPropertyAnimator messing with view layout position - android

I created a button, set the position using top and left margin and added to the layout. If i just do this the buttons sits there in the right location.
Now I need to add a translation animation, and I am using viewPropertyAnimator.
Unfortunately this voids the initial button position, making the animation start from (0, 0).
Following is the code I wrote.
final Button bonus_button = new Button(this);
int bonus_y_start, bonus_x_start, bonus_y_end, bonus_x_end;
bonus_x_start = random.nextInt(2) == 1 ? layout_width + button_size : -1 * button_size;
bonus_y_start = random.nextInt(layout_height + 2 * button_size) - button_size;
if (bonus_x_start < 0)
bonus_x_end = layout_width + button_size;
else
bonus_x_end = -1 * button_size;
bonus_y_end = random.nextInt(layout_height + button_size) - button_size;
RelativeLayout.LayoutParams bonus_l = new RelativeLayout.LayoutParams(button_size, button_size);
bonus_l.leftMargin = bonus_x_start;
bonus_l.topMargin = bonus_y_start;
bonus_button.setLayoutParams(bonus_l);
bonus_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mHandler.sendEmptyMessage(MSG_PAUSE_TIMER);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mHandler.sendEmptyMessage(MSG_RESUME_TIMER);
}
}, 2000);
}
});
bonus_button.bringToFront();
ViewPropertyAnimator animator = bonus_button.animate().x(bonus_x_end).y(bonus_y_end);
animator.setDuration(2000);
animator.withEndAction(new Runnable() {
#Override
public void run() {
layout.removeView(bonus_button);
}
});
layout.addView(bonus_button);
Anybody has any idea on where I'm doing wrong?

Use bonus_l.setX(bonus_x_start) and bonus_l.setY(bonus_x_start) instead of margins

Related

How to make a Button blink in Android?

If the user (in my quizgame) chooses the false answer, the button with the correct answer should blink green.
So far i did it like this:
if(answerTrue)
for (int i = 0; i < 2000; i = i + 250) {
handler.postDelayed(rbl_blinkNormal, i);
i = i + 250;
handler.postDelayed(rbl_blinkGreen, i);
}
And the runnables:
Green:
rbl_blinkGreen= new Runnable() {
#Override
public void run() {
btn_richtig.setBackgroundResource(R.drawable.color_green_btn);
}
};
Normal:
rbl_blinkNormal= new Runnable() {
#Override
public void run() {
btn_richtig.setBackgroundResource(R.drawable.color_black_btn);
}
};
It works fine but like this Im calling the postDelayed() every 250ms. May this impact my application performance and is there any better way to do this?
You can animate your button once you set its color to say GREEN. I mean,
if(answerTrue){
// Set the color of the button to GREEN once.
// Next, animate its visibility with the set color - which is GREEN as follows:
Animation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(50); //You can manage the blinking time with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
button.startAnimation(anim);
}
Similarly, you can animate the other button and stop animation when you feel like.
Source: Blinking Text in android view
If you want to blink the image only, here is an example.
Button bt_notes = (Button) findViewById(R.id.bt_notes);
int bt_notes_blink = 0;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
int DrawableImage[] = {R.drawable.picto_keys, R.drawable.picto_blank};
Resources res = getApplicationContext().getResources();
bt_notes.setCompoundDrawablesWithIntrinsicBounds(null, null, null, res.getDrawable(DrawableImage[bt_notes_blink]));
bt_notes_blink++;
if (bt_notes_blink == 2) { bt_notes_blink = 0; }
handler.postDelayed(this, 500);
}
});
}
}, 0);

Android Rebound translate up animation

I have popupWindow with some image views, which are created and added progammatically to popup window. Their position is set to bottom line with setY(). But when I use setEndValue to animate with spring, image goes from 0 to setEndValue, not from it's initial position.
How that can be fixed?
public SharePostPopupWindow(View parentView) {
super(MATCH_PARENT, MATCH_PARENT);
this.context = parentView.getContext();
this.parentView = parentView;
AndroidBlaBlaApplication.component(context).inject(this);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
FrameLayout container = new FrameLayout(context);
socialViews = new ArrayList<>();
socials = new ArrayList<>();
shadow = new View(context);
shadow.setId(R.id.share_view_shadow);
shadow.setBackgroundColor(Color.BLACK);
shadow.setClickable(true);
shadow.setAlpha(0.5f);
shadow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bus.post(new ShadowClickedEvent());
spring.setEndValue(initialPosition / 2 - Utils.convertDpToPixel(imageSize, context));
dismiss();
}
});
}
public void show() {
Utils.hideKeyboard(context, getContentView());
createButtons();
SpringSystem springSystem = SpringSystem.create();
spring = springSystem.createSpring();
SpringConfig slowConfig = new SpringConfig(TENSION, DAMPER);
spring.setSpringConfig(slowConfig);
spring.addListener(new SimpleSpringListener() {
#Override
public void onSpringUpdate(Spring spring) {
float value = (float) spring.getCurrentValue();
for (int i = 0; i < socialViews.size(); i++) {
if (i % 2 != 0) {
socialViews.get(i).setY(value);
}
}
}
});
showAtLocation(parentView, Gravity.CENTER_VERTICAL, 0, 0);
getContentView().setAlpha(1f);
}
If you want to force spring animation from certain position, you need to use
spring.setCurrentValue method first.

How can I add additional transitions to my animation on Android?

I have a transition animation that works very nicely. How can I add an additional translation after I pause for 1000 milliseconds?
view.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int button1_position[] = new int[2];
ibContact1.getLocationInWindow(button1_position);
Log.e(">>>>", "button1_position[0] "+button1_position[0] + " button1_position[1] " + button1_position[1]);
mSlidingImage = (ImageView) view.findViewById(R.id.slidingImage);
Animation translation = new TranslateAnimation(button1_position[0]-200, button1_position[0]-25, 0, button1_position[1] - 110);
translation.setStartOffset(1000);
translation.setDuration(2000);
translation.setRepeatCount(1);
//translation.setRepeatCount(Animation.INFINITE);
//translation.setRepeatMode(Animation.REVERSE);
mSlidingImage.startAnimation(translation);
//mSlidingImage.setVisibility(View.INVISIBLE);
}
});
return view;
}

Error while trying to create circular reveal: IllegalStateException: cannot start this animation on a detached view

So, I'm experimenting trying to create a circular reveal on API level 21 on a TextView but I keep getting this error. At first I thought it had something to do with the lifecycle of the fragment I was attempting it but then I just tried the same thing in an activity and it still wouldn't work.
Here's the code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window w = getWindow();
w.setFlags(
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
w.setStatusBarColor(Color.parseColor("#0277bd"));
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.text);
int a = (tv.getLeft() + tv.getRight()) / 2;
int b = (tv.getTop() + tv.getBottom()) / 2;
int radius = tv.getWidth();
Animator anim = ViewAnimationUtils.createCircularReveal(tv, a, b, 0, radius);
anim.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
}
It's still early days so I can't really find any answers about this. Any ideas?
You're getting the error because the view you passed in hasn't been measured and laid out on the screen yet. ViewAnimationUtils.createCircularReveal needs the target view to be measured to calculate the animation. You'll also find that your variables a and b are always 0.
If you want to experiment, create the animation and start it within a button click listener. Here's an example using your code:
Button button = (Button) findViewById(R.id.your_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView tv = (TextView) findViewById(R.id.text);
int a = (tv.getLeft() + tv.getRight()) / 2;
int b = (tv.getTop() + tv.getBottom()) / 2;
int radius = tv.getWidth();
Animator anim = ViewAnimationUtils.createCircularReveal(tv, a, b, 0, radius);
anim.start();
}
});
You can use Runnable to do the animation. The Runnable will run after the view's creation. No need to post delay.
view.post(new Runnable()
{
#Override
public void run(){
//create your anim here
}
});
Or you can do this.
tv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
Animator anim = ViewAnimationUtils.createCircularReveal(tv, a, b, 0, radius);
anim.start();
}
});
Adding GlobalLayoutListener to wait for the view to be inflated worked for me.
Or you can do this.
tv.postDelayed(new Runnable() {
#Override
public void run() {
//start your animation here
}
}, 1000);

Reduce speed of smooth scroll in scroll view [duplicate]

This question already has answers here:
Android: HorizontalScrollView smoothScroll animation time
(7 answers)
Closed 1 year ago.
I have a scroll View. I performed smooth-scroll.using smoothScrollBy().It all works fine, but I want to change the duration of the smooth-scroll. Smooth-scroll happens very fast and user is not understanding what happened.Please help me reduce smooth-scroll speed?
The simple answer is just to replace
scrollView.smoothScrollTo(0, scrollTo);
with
ObjectAnimator.ofInt(scrollView, "scrollY", scrollTo).setDuration(duration).start();
where duration is the time in milliseconds you want it to take.
Try the following code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
ValueAnimator realSmoothScrollAnimation =
ValueAnimator.ofInt(parentScrollView.getScrollY(), targetScrollY);
realSmoothScrollAnimation.setDuration(500);
realSmoothScrollAnimation.addUpdateListener(new AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation)
{
int scrollTo = (Integer) animation.getAnimatedValue();
parentScrollView.scrollTo(0, scrollTo);
}
});
realSmoothScrollAnimation.start();
}
else
{
parentScrollView.smoothScrollTo(0, targetScrollY);
}
This is how I achieved a smooth vertical scroll (like movie credits). This also allows the user to move the scroll up and down and allow it to continue scrolling when they let go. In my XML, I encapsulated my TextView inside of a ScrollView called "scrollView1". Enjoy!
final TextView tv=(TextView)findViewById(R.id.lyrics);
final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView1);
Button start = (Button) findViewById(R.id.button_start);
Button stop = (Button) findViewById(R.id.button_stop);
final Handler timerHandler = new Handler();
final Runnable timerRunnable = new Runnable() {
#Override
public void run() {
scrollView.smoothScrollBy(0,5); // 5 is how many pixels you want it to scroll vertically by
timerHandler.postDelayed(this, 10); // 10 is how many milliseconds you want this thread to run
}
};
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timerHandler.postDelayed(timerRunnable, 0);
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timerHandler.removeCallbacks(timerRunnable);
}
});
whichScreen = Math.max(0, Math.min(whichScreen, getBase().getDocumentModel().getPageCount()-1));
mNextScreen = whichScreen;
final int newX = whichScreen * getWidth();
final int delta = newX - getScrollX();
//scroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);
scroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta));
invalidate();

Categories

Resources