I have a ScrollView that contains a LinearLayout, in the LinearLayout I have a view that I expand or collapse depending on a button being pushed. This piece works just fine.
What I would like to do is re-position the ScrollView so that when the view is expanded it automatically re-positions the scroll view so that the expanded view is visible. I would like to the view to reposition it self automatically so the user does not have to scroll.
Currently when the view is expanded everything get's pushed down and you have to scroll up to view the newly expanded content. I tried repositioning after the animation has ended but that section of code never fires. Below is my code.
public void animateExpandCollapse(View v) {
View captionLayout = null;
View parentLayout = null;
if(v.getId() == R.id.squareCal) {
captionLayout = (LinearLayout) findViewById(R.id.layout3);
parentLayout = (LinearLayout) findViewById(R.id.squareLayout);
} else if(v.getId() == R.id.circleCal) {
captionLayout = (LinearLayout) findViewById(R.id.layout2);
parentLayout = (LinearLayout) findViewById(R.id.circleLayout01);
}
if (!more) {
dda = new DropDownAnim(captionLayout, 350, false);
more=true;
} else {
dda = new DropDownAnim(captionLayout, 350, true);
more=false;
}
dda.setDuration(350);
parentLayout.startAnimation(dda);
// Here, I want to position ScrollView to the bottom
// After the animation has finished but this never fires.
if(dda.hasEnded() ) {
ScrollView sv = (ScrollView)findViewById(R.id.calScroller);
sv.scrollTo(0, sv.getBottom());
}
return;
}
After searching online I found the following solution. I hope this helps someone.
dda.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
ScrollView sv = (ScrollView)findViewById(R.id.calScroller);
sv.scrollTo(0, sv.getBottom());
}
});
Related
The animation does not work after I set visibility to Invisible, I tried clear animation but not work. I have a button when I click the button it opens a linear layout with animation when I press back button I set the linear layout visibility to invisible again I click the button linear layout appear but no animation please help me.
l1 = (LinearLayout) findViewById(R.id.lnrlgn);
l2 = (LinearLayout) findViewById(R.id.lnrlgn1);
l2.setVisibility(View.INVISIBLE);
Animation uptodown = AnimationUtils.loadAnimation(this,R.anim.uptodown);
viewcrrd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
l2.setAnimation(downtoup);
l2.clearanimation(); // is it right ?
l2.setVisibility(View.VISIBLE);
}
});
public void onBackPressed() {
// super.onBackPressed();
if (back_pressed + TIME_DELAY > System.currentTimeMillis()) {
// super.onBackPressed();
Exitdlg alert = new Exitdlg();
alert.showDialog(LoginActivity.this, "Are You Sure ");
l2.clearAnimation();
} else {
l2.clearAnimation();
l2.setVisibility(View.INVISIBLE);
}
back_pressed = System.currentTimeMillis();
}
Use startAnimation instead of setAnimation
viewcrrd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
l2.setVisibility(View.VISIBLE);
l2.clearanimation();
l2.startAnimation(downtoup);
}
});
ivSwapImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
frameFromX = llFrom.getX();
frameFromY = llFrom.getY();
frameToX = llTo.getX();
frameToY = llTo.getY();
if (isSwap) {
llFrom.setX(frameToX);
llFrom.setY(frameToY);
llTo.setX(frameFromX);
llTo.setY(frameFromY);
isSwap = false;
} else {
llFrom.setX(frameToX);
llFrom.setY(frameToY);
llTo.setX(frameFromX);
llTo.setY(frameFromY);
isSwap = true;
}
}
});`
Above write to change Two Linear layout swap to each other position.but need to add animation on that layouts
try this. how add an animation to llFrom and llTo LinearLayout?
I have added childView with ObjectAnimator in RelativeLayout. Now when I remove all the child from RelativeLayout I still gets onAnimationEnd triggered.
How would I stop all the animation of childViews once I removed all the childs from RelativeLayout.
RelativeLayout container = (RelativeLayout) findViewById(R.id.container);
RelativeLayout.LayoutParams layoutParams = getCircleLayoutParam(R.dimen.game_circle_width, R.dimen.game_circle_ht);
container.addView(view, layoutParams);
ObjectAnimator scale = ObjectAnimator.ofPropertyValuesHolder(view,
PropertyValuesHolder.ofFloat("alpha", 0f),
PropertyValuesHolder.ofFloat("scaleY", 1f),
PropertyValuesHolder.ofFloat("y", 0, mWindowHeight));
scale.setDuration(SPEED_TIME);
scale.start();
scale.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
//Getting triggered even after calling container.removeAllViews()
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (scale != null){
scale.removeAllListeners();
scale.cancel();
scale.end();
}
container.removeAllViews();
container.invalidate();
}
});
On calling container.removeAllViews() and container.invalidate() on button click. I still gets onAnimationEnd() triggered.
Any response is highly appreciated.
When adding a View to the container, pass the Animator as tag:
view.setTag(scale);
The OnClickListener:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < container.getChildCount(); i++)
{
View v = container.getChildAt(i);
Object o = v.getTag();
if (o != null && o instanceof ObjectAnimator)
{
((ObjectAnimator)o).cancel();
// or ...end(), see below
}
}
container.removeAllViews();
container.invalidate();
}
});
Use ValueAnimator.cancel() or ValueAnimator.end() depending on which result you want to achieve, see documentation
If the tag is already in use for some other purpose, one could keep a list with the ObjectAnimators and in the for loop run through that list.
Use removeAllListeners() or removeListener(Animator.AnimatorListener listener) before your calls.
I have a RelativeLayout in my View whose visibility is set as GONE. I need to provide a slide down translation and also set the visibility as VISIBLE for the RelativeLayout over the ListView on button press and Slide up animation on button press by.
replyMessage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
//slideToBottom(replyLayout);
Toast.makeText(getActivity(), "Reply pressed",
Toast.LENGTH_SHORT).show();
TranslateAnimation animate = new TranslateAnimation(0,0,0,replyLayout.getHeight());
animate.setDuration(1000);
animate.setFillAfter(true);
replyLayout.startAnimation(animate);
replyLayout.setVisibility(View.VISIBLE);
if(replyFlag){
replyMessage.setImageResource(R.drawable.reply_active);
replyFlag = true;
}else{
replyMessage.setImageResource(R.drawable.reply_img);
replyFlag = false;
}
}
I have a class where I include another layout on a button click. This included layout has some buttons and a code which executes on clicking these buttons. I have used a counter which indicates the number of times the button is clicked. First time clicking on the button includes the layout and the second time clicking removes the views and so on. Here's the code
public class Home extends Fragment implements OnClickListener {
int c = 0;
Button bmain, bnew, bolder;
RelativeLayout r1;
View rootView;
Animation slidedown, slideup;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.home, container, false);
bmain = (Button) rootView.findViewById(R.id.btn2);
bmain.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View arg0) {
ViewGroup con = null;
LayoutInflater layoutInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
FrameLayout flContainer = (FrameLayout)rootView.findViewById(R.id.flContainer);
//Loading animation
slidedown = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_down);
slideup = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_up);
//The counter indicates the number of clicks.
//Needs to be replaced for a better solution.
//If it's even add view
if(c%2==0)
{
//Adding layout here
flContainer.addView(layoutInflater.inflate(R.layout.test1,con,false ));
//Starting Animation
flContainer.startAnimation(slidedown);
//After adding layout we can find the Id of the included layout and proceed from there
bnew = (Button) rootView.findViewById(R.id.btntest);
bnew.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0) {
Toast.makeText(getActivity(), "You Clicked New", Toast.LENGTH_LONG).show();
}
});
bolder = (Button) rootView.findViewById(R.id.btntest1);
bolder.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0) {
Intent form = new Intent(getActivity(),FeedbackForm.class);
startActivity(form);
}
});
c++;
} //If ends here
//If it's odd remove view
else
{
flContainer.removeAllViews();
flContainer.startAnimation(slideup);
//flContainer.removeView(flContainer);
//flContainer.removeView(layoutInflater.inflate(R.layout.test1, con, false));
c++;
}
}
}
The code at the end
flContainer.removeAllViews();
flContainer.startAnimation(slideup);
removes the view but fails to process the animation. I have tried using removeView but in that case the buttonclicks in the if statement fail to execute the second time. What am I missing here? How can I achieve it?
The answer is pretty simple. You have to remove the view after the animation is finished. This can be achieved pretty simple, first you have to set an animation listener for your animation and in the onAnimationEnd callback - which is called when the animation is finished - you remove the views.
EDIT:
Replace this:
flContainer.removeAllViews();
flContainer.startAnimation(slideup);
With this:
slideup.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
flContainer.removeAllViews();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
flContainer.startAnimation(slideup);
If there are any further problems let me know.