android scale child parent height not changed - android

I have an ImageView with RelativeLayout parent and this the xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageViwe
android:layout_width="30dp"
android:layout_height="30dp"
android:id="#+id/love"
android:src="#drawable/love_large"
android:layout_alignParentRight="true" />
</RelativeLayout >
now in jave i scale the ImageView
private ImageView love;
love = (ImageView)findViewById(R.id.love);
/*** animation scale with e value ***/
love.setScaleX(e);
love.setScaleY(e);
/*** animation scale ***/
now the ImageView size changed but its parent still same size

use this layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/love"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/ic_love" />
</RelativeLayout>
and
public class MainActivity extends AppCompatActivity {
ImageView love;
RelativeLayout root;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
love = (ImageView)findViewById(R.id.love);
root = (RelativeLayout)findViewById(R.id.root);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f,5.0f);
valueAnimator.setDuration(5000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value =(Float) animation.getAnimatedValue();
love.setScaleX(value);
love.setScaleY(value);
}
});
valueAnimator.start();
}
}

Related

Android animate view does not resize other view

I have an issue on Android and can't understand why. I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/Container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_primary">
<RelativeLayout
android:id="#+id/RecyclerViewContainer"
android:layout_below="#+id/UpdatesBanner"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:scrollbars="none"
android:clipToPadding="false"
android:splitMotionEvents="false"
android:requiresFadingEdge="none"
android:overScrollMode="never" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_red_dark" />
</RelativeLayout>
<Droid.UIElements.UIBanner
android:id="#+id/UpdatesBanner"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_alignParentTop="true"
android:background="#android:color/holo_green_dark" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
UIBanner is a custom view that content 2 buttons. One of them is binded on a Hide function which will animate the view.
public void Hide()
{
ObjectAnimator animation = ObjectAnimator.OfFloat(this, "TranslationY", TranslationY, TranslationY - Height);
animation.Start();
}
This works but the view under the banner keep the same size and does not expand. If i only make a visibility gone on the banner then it works but no animation performed.
Following the states before and after animation:
Found a solution, don't know if it is the best way to achieve this bu well i have to animate the second view too. Following the code:
ObjectAnimator bannerAnimation = ObjectAnimator.OfFloat(banner, "TranslationY", banner.TranslationY, banner.TranslationY - banner.Height);
ObjectAnimator viewAnimation = ObjectAnimator.OfFloat(recycler, "ScaleY", recycler.ScaleY, recycler.ScaleY - banner.Height);
AnimatorSet set = new AnimatorSet();
set.PlayTogether(bannerAnimation, viewAnimation);
set.Start();
Best solution is ValueAinmator
ValueAnimator viewAnim = ValueAnimator.OfInt(view.MeasuredHeight, viewHeight);
viewAnim.AddUpdateListener(new UpdateListener(view));
AnimatorSet set = new AnimatorSet();
set.AnimationEnd += (sender, e) => EndAnim();
set.Play(viewAnim);
set.Start();
And the listener
class UpdateListener : Java.Lang.Object, IAnimatorUpdateListener
{
Android.Views.View view;
public UpdateListener(Android.Views.View pView)
{
view = pView;
}
public void OnAnimationUpdate(ValueAnimator animation)
{
int value = (int)animation.AnimatedValue;
ViewGroup.LayoutParams layoutParams = view.LayoutParameters;
layoutParams.Height = value;
view.LayoutParameters = layoutParams;
}
}

Android -TranslateAnimation not working

I am trying to start a shining affect animation on an Image view.
the problem is that the animation does not show on screen.
It is work only when I start it inside a button listener.
this is my shine_effect.xml file:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:centerColor="#beffffff"
android:endColor="#00ffffff"
android:startColor="#00ffffff" />
</shape>
this is my layout xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/gradient"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="170dp"
android:layout_height="170dp"
android:layout_centerInParent="true">
<ImageView
android:id="#+id/img"
android:layout_width="170dp"
android:layout_height="170dp"
android:contentDescription="#string/desc"
android:src="#drawable/logo" />
<ImageView
android:id="#+id/shine"
android:layout_width="50dp"
android:layout_height="170dp"
android:layout_marginStart="-50dp"
android:contentDescription="#string/desc"
android:src="#drawable/shine_effect" />
</RelativeLayout>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/relativeLayout"
android:layout_centerHorizontal="true"
android:layout_marginTop="43dp"
android:text="#string/pending"
android:textColor="#android:color/white" />
</RelativeLayout>
and my activity onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_pending);
img=(ImageView)findViewById(R.id.img) ;
shine=(ImageView)findViewById(R.id.shine) ;
shine_anim=new TranslateAnimation(0, img.getWidth()+ shine.getWidth(),0,
0);
shine_anim.setDuration(550);
shine_anim.setFillAfter(true);
shine_anim.setRepeatMode(Animation.RESTART);
shine_anim.setInterpolator(new AccelerateDecelerateInterpolator());
shine_anim.setRepeatMode(Animation.INFINITE);
shine.startAnimation(shine_anim);
}
It is because the ImageView has not layouted yet so the width is 0. You can give it a layout cycle and start the animation then.
img.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
img.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Create and start animation
}
});
Alternatively if your image width is always static, you can convert e.g. that 170dp to px and use that value when creating the TranslateAnimation instead of using getWidth() methods of views.
Call your animation in onWindowFocusChanged method
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus) {
shine_anim = new TranslateAnimation(0, img.getWidth() + shine.getWidth(), 0,
0);
shine_anim.setDuration(550);
shine_anim.setFillAfter(true);
shine_anim.setRepeatMode(Animation.RESTART);
shine_anim.setInterpolator(new AccelerateDecelerateInterpolator());
shine_anim.setRepeatMode(Animation.INFINITE);
shine.startAnimation(shine_anim);
}
}

Animate a view from 0dp width to MATCH_PARENT

I'm trying to animate my RecyclerView item when its clicked by making a rectangle grow from zero width to 100% (MATCH_PARENT) and become the background of the item.
However I can't see the animation working. I mean, the initial background is white, but the rectangle is gray, so the clicked item would become gray. But this is not happening.
Here's the item xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="0dp"
android:focusable="true"
android:clickable="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="72dp"
android:orientation="horizontal">
<View
android:id="#+id/colored_bar"
android:layout_width="3dp"
android:layout_height="match_parent"
android:background="#drawable/colored_bar_bg1"></View>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/option_background_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#e0e0e0"></View>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<ImageView
android:id="#+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="13dp"
app:srcCompat="#drawable/ic_lock" />
<TextView
android:id="#+id/card_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/icon"
android:layout_toRightOf="#+id/icon"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp"
tools:text="#string/option_title_label" />
<TextView
android:id="#+id/card_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/card_title"
android:layout_toEndOf="#+id/icon"
android:layout_toRightOf="#+id/icon"
android:paddingLeft="8dp"
android:textSize="14sp"
tools:text="#string/option_description_label" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
And the code to make the animation:
public class OptionListItemHolder extends RecyclerView.ViewHolder {
private TextView cardTitle;
private TextView cardSubtitle;
private ImageView icon;
private View coloredBar;
private View optionBackground;
public OptionListItemHolder(View v) {
super(v);
cardTitle = (TextView)v.findViewById(R.id.card_title);
cardSubtitle = (TextView)v.findViewById(R.id.card_subtitle);
icon = (ImageView)v.findViewById(R.id.icon);
coloredBar = v.findViewById(R.id.colored_bar);
optionBackground = v.findViewById(R.id.option_background_container);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ObjectAnimator animation = ObjectAnimator.ofInt(optionBackground, "width", 0, view.getWidth());
animation.setDuration(600);
animation.setInterpolator(new DecelerateInterpolator());
animation.start();
}
});
}
}
Why it is not working?
I've found that using a ValueAnimator instead works
ValueAnimator widthAnimator = ValueAnimator.ofInt(view.getWidth(), newWidth);
widthAnimator.setDuration(500);
widthAnimator.setInterpolator(new DecelerateInterpolator());
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
view.getLayoutParams().width = (int) animation.getAnimatedValue();
view.requestLayout();
}
});
widthAnimator.start();
If the view's width needs to match the parent, you can get the width of the parent by
int parentWidth = ((View)view.getParent()).getMeasuredWidth();

Scale parentLayout without scaling its childView

I am scaling and translating my parent layout, but the problem is my child view is also scaling and but not translating according to its parent(I want my child view to be at the center of the screen, no matter where my parent layout is translating).
Below is my code
public class Splash extends AppCompatActivity {
Animation zoomIn,zoomOut;
ImageView icon;
LinearLayout relativeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
zoomIn = AnimationUtils.loadAnimation(this,R.anim.zoom_in);
zoomOut = AnimationUtils.loadAnimation(this,R.anim.zoom_out);
relativeLayout = (LinearLayout) findViewById(R.id.activity_splash);
relativeLayout.setBackgroundResource(R.drawable.utt);
icon = (ImageView) findViewById(R.id.icon);
relativeLayout.setAnimation(zoomIn);
relativeLayout.setAnimation(zoomOut);
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.height= 75;
layoutParams.width = 75;
layoutParams.gravity= Gravity.CENTER;
icon.setLayoutParams(layoutParams);
zoomIn.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
relativeLayout.startAnimation(zoomOut);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
zoomOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
icon.setAlpha(1.0f);
icon.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(),R.anim.translate_top_center));
}
#Override
public void onAnimationEnd(Animation animation) {
relativeLayout.startAnimation(zoomIn);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
It's Activity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context="store.shopnix.com.kenburns.Splash">
<ImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:alpha="0.0"
android:src="#drawable/icon"/>
anim.xml
zoom_in
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="20000"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.5"
android:toYScale="1.5"
android:repeatMode = "reverse"
android:translationX="100dp"
android:translationY = "100dp">
</scale>
zoom_out
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="20000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="70%"
android:pivotY="20%"
android:toXScale="1.5"
android:toYScale="1.5"
android:repeatCount="1"
android:repeatMode = "reverse"
android:translationX="20dp"
android:translationY = "20dp">
</scale>
Create two separate layouts, one that scales and other that doesn't.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/layout_to_scale">
<!--put stuff that scales here-->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/layout_to_stay">
<!--put static stuff here-->
</LinearLayout>
</FrameLayout>
Now in your activity animate only layout with id = R.id.layout_to_scale
Instead of LinearLayout you can use RelativeLayout and place the childView inside it .
now you add property android:layout_centerInParent="true" for childView
now you can scale the RelativeLayout without scaling the childView it will definitely stay in centre of parentView(RelativeLayout).
Hope this solves your problem.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="store.shopnix.com.kenburns.Splash">
<ImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerInParent="true"
android:alpha="0.0"
android:src="#drawable/icon" />

Slide up/down layout on click

I am looking to slide/up down a nested layout on its parent layout click.
Ie the parent layout will have a hidden child. On click I would like the parents height to animate down (slide down) to fit the child layout. On click again I would like the child to animate up (slide up). Basically just animating the parents height to show/hide the child.
I have found this which looks to work but seems like a lot of code:
http://gmariotti.blogspot.com/2013/09/expand-and-collapse-animation.html
I have seen a lot of things using 'animateLayoutChanges' to animate things however I cannot get that to work.
I have tried this:
<LinearLayout android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout android:id="#+id/child"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:animateLayoutChanges="true">
<TextView android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some text to show/hide"/>
</LinearLayout>
</LinearLayout>
Then in code:
LinearLayout parent = (LinearLayout)findViewById(R.id.parent);
parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LinearLayout child = (LinearLayout)findViewById(R.id.child);
child.setVisibility(child.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
}
});
That sets the visibility of the child view correctly but there is absolutely no animation.
Well, first of all android:animateLayoutChanges effects the child elements. So, obviously, if you are changing the properties of the element itself, it will not be animated.
I think you can accomplish what you are trying to in API 16 by enabling the LayoutTransition.CHANGING animation.
<LinearLayout android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true">
<TextView android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"/>
<TextView android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="Some text to show/hide"/>
</LinearLayout>
LinearLayout parent = (LinearLayout)findViewById(R.id.parent);
parent.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
View text = findViewById(R.id.text);
text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View message = findViewById(R.id.message);
ViewGroup.LayoutParams params = message.getLayoutParams();
params.height = params.height == 0 ? ViewGroup.LayoutParams.WRAP_CONTENT : 0;
message.setLayoutParams(params);
}
});
Try to use SlidingDrawer
use this code
xml layout sideupdown.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/bopen"
android:layout_width="90sp"
android:layout_height="wrap_content"
android:text="open" />
<Button
android:id="#+id/btogg"
android:layout_width="90sp"
android:layout_height="wrap_content"
android:text="change" />
<Button
android:id="#+id/bclose"
android:layout_width="90sp"
android:layout_height="wrap_content"
android:text="close" />
</LinearLayout>
<SlidingDrawer
android:id="#+id/slidingDrawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:content="#+id/content"
android:handle="#+id/handle" >
<Button
android:id="#+id/handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Handle" />
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<CheckBox
android:id="#+id/chkbok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="On/Off" />
</LinearLayout>
</SlidingDrawer>
</FrameLayout>
java class SlideUpDown.java
public class SlideUpDown extends Activity implements OnClickListener,
OnCheckedChangeListener, OnDrawerOpenListener, OnDrawerCloseListener {
Button opn, cloz, chng, hndl;
CheckBox chkbox;
SlidingDrawer sd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sideupdown);
refference();
opn.setOnClickListener(this);
cloz.setOnClickListener(this);
chng.setOnClickListener(this);
chkbox.setOnCheckedChangeListener(this);
sd.setOnDrawerOpenListener(this);
sd.setOnDrawerCloseListener(this);
}
private void refference() {
opn = (Button) findViewById(R.id.bopen);
cloz = (Button) findViewById(R.id.bclose);
chng = (Button) findViewById(R.id.btogg);
chkbox = (CheckBox) findViewById(R.id.chkbok);
sd = (SlidingDrawer) findViewById(R.id.slidingDrawer);
hndl = (Button) findViewById(R.id.handle);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bopen:
sd.open();
break;
case R.id.bclose:
sd.close();
break;
case R.id.btogg:
sd.toggle();
break;
}
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (chkbox.isChecked()) {
sd.lock();
hndl.setEnabled(false);
} else {
sd.unlock();
hndl.setEnabled(true);
}
}
#Override
public void onDrawerOpened() {
}
#Override
public void onDrawerClosed() {
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
In one of our applications we hide and show a header and footer. We do this by changing the height and visibility of the view.
It looks something like this
ValueAnimator va;
if (show)
va = ValueAnimator.ofInt(0, px);
else
va = ValueAnimator.ofInt(px, 0);
va.setDuration(400);
va.setInterpolator(new DecelerateInterpolator(2));
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
topicNavBar.getLayoutParams().height = value;
topicNavBar.requestLayout();
if (value == 0) {
if (show)
topicNavBar.setVisibility(View.VISIBLE);
else
topicNavBar.setVisibility(View.GONE);
}
if (show && value == px) {
animationInProgress = false;
}
if (!show && value == 0) {
animationInProgress = false;
}
}
});
va.start();
Hope this helps

Categories

Resources