LayoutTransition height to 0 causes view to dissappear instantly without animating - android

Given a view that is always aligned parent bottom, initially with a height of 0, I want to animate it so it slide up to it's height of WRAP_CONTENT. I'm using layout transition to achieve this:
viewGroup.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
Where viewGroup is a parent of viewToAnimate and has animateLayoutChange=true
And the logic is:
val params = viewToAnimate.layoutParams
if (expand && params.height == 0) {
params.height = ViewGroup.LayoutParams.WRAP_CONTENT
viewToAnimate.layoutParams = params
} else if (collapse && params.height != 0) {
params.height = 0
viewToAnimate.layoutParams = params
}
This works great when the view is expanded; the view slides up from the bottom to its height nicely. However, when the height is set to 0, the view simply disappears and doesn't slide in. viewToAnimate is a relative layout with some TextViews, nothing complicated. Any suggestions would be appreciated.
Video showing effect (notice the text not sliding down, just disappearing): https://www.dropbox.com/s/1pq7yh0bqx8ghif/2017_10_06_23_17_11.mp4?dl=0
View to animate:
<RelativeLayout>
..some other stuff...
<RelativeLayout
android:id="#+id/viewToAnimate"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
android:layout_alignParentBottom="true"
android:background="#color/white">
<TextView
android:id="#+id/sampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample Text"
android:textSize="50sp"/>
</RelativeLayout>
</RelativeLayout>

Keep viewToAnimate layout height as "wrap_content" and the textView height as "0dp".. see example below.
<RelativeLayout
android:animateLayoutChanges="true"
android:id="#+id/viewToAnimate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_alignParentBottom="true"
android:background="#android:color/white">
<TextView
android:id="#+id/sampleText"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="Sample Text"
android:textSize="50sp"/>
</RelativeLayout>
final RelativeLayout viewToAnimate = (RelativeLayout) findViewById(R.id.viewToAnimate);
viewToAnimate.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
TextView sampleTV = (TextView)findViewById(R.id.sampleText);
ViewGroup.LayoutParams params = sampleTV.getLayoutParams();
if (params.height == 0) {
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
}else {
params.height = 0;
}
sampleTV.setLayoutParams(params);
Try and let me know.

What I do to animate a view in and out of view is if the view is meant to be off screen i set the Visibility attribute to "Invisible" and then when it is to animate into view I set it to "Visible" when animation starts and when it is to animate off screen I set it to "Invisible" when the animation ends.
So instead of changing height set visibility.
if (expand) {
viewToAnimate.setVisibility(View.VISIBLE);
} else if (collapse) {
viewToAnimate.setVisibility(View.INVISIBLE);
}
to set visibility in xml use:
android:visibility="invisible"
Hope this helps.
CLARIFICATION:
I'm using custom animations and AnimationUtils.loadAnimation to get Animation than using setAnimationListener to set the visibility on the layout/view what is to be animated.
example:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.custom_animation_in_or_out_of_view);
animation.setAnimationListener(new Animation.AnimationListener(){
#Override public void onAnimationStart(Animation animation) {
//should always be visible on animation starting
viewToAnimate.setVisibility(View.INVISIBLE);
}
#Override public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
//set your viewToAnimate to the corresponding visibility...
}
});
viewToAnimate.startAnimation(animation);
custom animation xml for sliding into view:
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="0%p"
android:toYDelta="100%p"
android:duration="1000" />
and sliding out of view, just switch the values of 'fromYDelta' and 'toYDelta'.

Try to use object animator like
TextView sampleTV = (TextView) findViewById(R.id.sampleText);
//initially translate the view to bottom
sampleTV.setTranslationY(sampleTV.getHeight());
// for sliding up
sampleTV.animate().translationY(0).setDuration(100).setInterpolator(new AccelerateDecelerateInterpolator()).start();
// for sliding down
sampleTV.animate().translationY(sampleTV.getHeight()).setDuration(100).setInterpolator(new AccelerateDecelerateInterpolator()).start();

Just add this into your XML and it will takes the work.
android:animateLayoutChanges="true"
like that
<RelativeLayout>
..some other stuff...
<RelativeLayout
android:id="#+id/viewToAnimate"
android:layout_width="match_parent"
android:layout_height="0dp"
*******android:animateLayoutChanges="true"********
android:gravity="center"
android:layout_alignParentBottom="true"
android:background="#color/white">
<TextView
android:id="#+id/sampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample Text"
android:textSize="50sp"/>
</RelativeLayout>
</RelativeLayout>

Related

Flickers while layout visible/gone

Is there any way to hide a view without flickering its above view?
I am trying to hide a View below MapView. Once I set its visibility to GONE, MapView flickers. As I have to add more markers dynamically, couldn't able to keep MapView and bottomView in FrameLayout, since the bottomView will hide those markers in small size screens.
Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<com.myapp.widgets.MapPlacePicker
android:id="#+id/lay_fr_map_inc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/options_layout" />
<LinearLayout
android:id="#+id/options_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:animateLayoutChanges="true"
android:background="#FFFFFF"
android:orientation="vertical"
android:visibility="visible">
<com.myapp.widgets.FontTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Please select a location!!"
android:textAppearance="#android:style/TextAppearance.Small" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.aigestudio.wheelpicker.WheelPicker
android:id="#+id/main_option_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="0.5"
app:wheel_atmospheric="true"
app:wheel_curved="false"
app:wheel_item_space="15dp"
app:wheel_item_text_color="#ffafafaf"
app:wheel_item_text_size="12dp"
app:wheel_selected_item_text_color="#color/colorPrimary"
app:wheel_visible_item_count="3" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Output:
I have also tried TranslationAnimation, but no luck. Its showing more gray space than before.
int fromY = (visibility == View.GONE) ? 0 : optionLayout.getHeight();
int toY = (visibility == View.GONE) ? optionLayout.getHeight() : 0;
if (visibility == View.VISIBLE) {
optionLayout.setVisibility(visibility);
}
TranslateAnimation animate = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
fromY, // fromYDelta
toY); // toYDelta
animate.setDuration(1000);
animate.setInterpolator(new AccelerateDecelerateInterpolator());
//animate.setFillAfter(false);
animate.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (visibility == View.GONE)
optionLayout.setVisibility(visibility);
optionLayout.clearAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
optionLayout.startAnimation(animate);
I don't see any flickering in that animation; if you want to avoid the vertical resizing behavior of lay_fr_map_inc then you can just remove this attribute:
android:layout_above="#+id/options_layout"
...and maybe make the height match_parent. Then, lay_fr_map_inc will stay full height, but the bottom portion will be hidden by options_layout when it appears (instead of scooting upwards).
Don't forget to change the map padding when you do this, so you don't obscure the Google logo (which is a violation of the rules): setPadding()

Android: RelativeLayout translateY animation with layout_alignParentBottom

I'm working on an Android app with an animation where a vertically central view should be animated from the center to the top of the screen. Below this view is another view containing related content, which is aligned directly below the center view. When the center view animates up, I want the lower view to be 'pinned' to the top but also to the bottom of the screen (as per layout_alignParentBottom="true"). Currently though, as the bottom view animates up a gap is left between the bottom view and the bottom of the screen:
What's the easiest way to animate the bottom view, while keeping it pinned to the bottom of the screen?
Here is my layout XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="newsoni.com.testrelativelayouttranslation.MainActivity">
<View
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#FF0000"
android:layout_centerVertical="true"
android:id="#+id/centerBar" />
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#00FF00"
android:layout_below="#+id/centerBar"
android:id="#+id/bottomPanel" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Do animation"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:id="#+id/btn" />
</RelativeLayout>
Here is my Java:
public class MainActivity extends AppCompatActivity {
private View mCenter, mBottomPanel;
private Button mBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCenter = findViewById(R.id.centerBar);
mBottomPanel = findViewById(R.id.bottomPanel);
mBtn = $(R.id.btn);
mBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int value = mCenter.getTranslationY() == 0 ? -mCenter.getTop() : 0;
mCenter.animate()
.translationY(value)
.setDuration(250)
.start();
mBottomPanel.animate()
.translationY(value)
.setDuration(250)
.start();
}
});
}
#SuppressWarnings("unchecked")
public <T extends View> T $(int id) {
return (T) findViewById(id);
}
}
Here is a link to the project which you can download:
https://drive.google.com/file/d/0B-mqMIMqm_XHamxENkhIZDJDMHM/view?usp=sharing
I ended up using a standard Animation and overriding applyTransformation to manually alter the LayoutParams of the bottom view.

Android - TextView with 'zero' height

I would to set dinamically the TextView height with an ObjectAnimator.
This is the code:
if(condition){
height = 136;
}else{
height = 0;
}
ObjectAnimator animator = ObjectAnimator.ofInt(
mText,
"height",
height
).setDuration(400);
animator.start();
This works, somwhere, but it doesn't set the TextView height to 0, but about 80px.
Why?
To hide and show textview, It is not good practice to set its heights instead do this:
textview.setVisibility(View.GONE);
OR
textview.setVisibility(View.INVISIBLE);
View.GONE This view is invisible, and it doesn't take any space for layout purposes.
View.INVISIBLE This view is invisible, but it still takes up space for layout purposes.
To make it Visible again, use
textview.setVisibility(View.VISIBLE);
EDITED
To hide view with animation,
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.0f);
anim.addListener(new AnimatorListener() {
...
#Override
public void onAnimationEnd(Animator animation) {
animDrawable.stop()
}
...
});
anim.setDuration(300).start();
This will gradually fade your view and hide it with animation.
If you want to hide the TextView with animation, use below code
ViewPropertyAnimator mTextAnimator = myTextView.animate()
.scaleY(0f)
.setListener(new Animator.AnimatorListener() {
public void onAnimationStart(Animator animation) {}
public void onAnimationRepeat(Animator animation) {}
public void onAnimationCancel(Animator animation) {}
public void onAnimationEnd(Animator animation) {
myTextView.setVisibility(View.GONE);
}
})
.setDuration(400);
mTextAnimator.start();
To show TextView with animation, use
mTextAnimator = myTextView.animate()
.scaleY(1f)
.setListener(null)
.setDuration(400);
mTextAnimator.start();
I assume you are trying to hide it by setting height to 0? If this is the case, why not use .setVisibility(View.GONE)?
If you have other views depending on its location then use setVisibility(View.INVISIBLE). Otherwise use setVisibility(View.GONE).
In my .xml file, I used android:visibility="gone". Originally I had this:
<TextView
android:id="#+id/labelReachable"
android:layout_width="wrap_content"
android:gravity="left"
android:textSize="15dp"
android:layout_marginTop="10dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="Reachability"></TextView>
<ImageView
android:background="#drawable/bar_dark"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/insertPings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
I wanted to make those elements invisible and not take any space for layout purposes. I simply used android:visibility="gone" to have this:
<TextView
android:id="#+id/labelReachable"
android:layout_width="wrap_content"
android:gravity="left"
android:textSize="15dp"
android:layout_marginTop="10dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:visibility="gone"
android:text="Reachability"></TextView>
<ImageView
android:background="#drawable/bar_dark"
android:layout_width="fill_parent"
android:visibility="gone"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/insertPings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:visibility="gone"
android:orientation="vertical" >
</LinearLayout>

How to animate the textview (very very long text )scroll automatically horizontally

I am not interested in Marquee because, in Marquee you can not control the speed of marquee.
I have tried to animate the textview but Parent view clips the text at the end even though all parent layout and view groups encompassing textviews are set with two flags clipchildren= false, clipToPadding=false.
Am I missing something or is there a better work around ?
The xml looks like
<TextView
android:id="#+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="66dp"
android:maxLines="1"
android:singleLine="true"
android:textColor="#585858"
android:textSize="32sp" >
</TextView>
and code snippet look like
TextView textView2 = (TextView)findViewById( R.id.textview1 );
textView2.startAnimation((Animation)AnimationUtils.loadAnimation(this, R.anim.translate));
I think you can use translate animation. Something like this
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXDelta="100"
android:interpolator="#android:anim/linear_interpolator"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toXDelta="-100" />
And add to your textview like this
textview.startAnimation((Animation)AnimationUtils.loadAnimation(Context,R.anim.scroll_animation));
Hope it can help you.
I am sure this will definitely solve the problem of the large audience out there.
Q: Auto-scroll a single line long text message(either using hard_coding or from string.xml) horizontally & infinitely at a reasonable speed but using marquee(try it once at least). No clipping
Step 1:
In activity_main.xml file:
<TextView
android:text="either hard coding or from string.xml"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView2"
android:background="#color/colorPrimary"
android:textSize="18sp"
android:marqueeRepeatLimit="marquee_forever"
android:textColor="#android:color/background_light" />
Step 2: In main_activity java file
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView2);
textView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
textView.setSelected(true);
textView.setSingleLine(true);
textView.setText("Oxfam says 8 men as rich as half the world. | Govt may set threshold for probe into deposits. | At least 32 dead after Turkish plane hits village.");}}
//one can remove the last line line if he has already feed the long input
Just add this to your textview
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textSize="30dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="Your_Text" />
Here was my SOLUTION
To make the long text inside textview not be cut by parent view or by screen, I have done two things.
First, let textview inside a scroolview like below code
<ScrollView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_centerHorizontal="true">
<TextView
android:id="#+id/marquee_text"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:maxLines="1"
android:textColor="#android:color/black"
android:textSize="30sp"/>
</ScrollView>
Then, I measure my text size then refine the textview param by doing this.
marqueeText.setText("my long text");
Paint textPaint = marqueeText.getPaint();
String text = marqueeText.getText().toString();//get text
int width = Math.round(textPaint.measureText(text));//measure the text size
ViewGroup.LayoutParams params = marqueeText.getLayoutParams();
params.width = width;
marqueeText.setLayoutParams(params); //refine
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
//this is optional. do not scroll if text is shorter than screen width
//remove this won't effect the scroll
if (width <= screenWidth) {
//All text can fit in screen.
return;
}
//set the animation
TranslateAnimation slide = new TranslateAnimation(0, -width, 0, 0);
slide.setDuration(20000);
slide.setRepeatCount(Animation.INFINITE);
slide.setRepeatMode(Animation.RESTART);
slide.setInterpolator(new LinearInterpolator());
marqueeText.startAnimation(slide);
I hope this solution which took me half a day to research can help others who might meet the same problem like me.
Can try out this. This is a solution using TranslateAnimation for creating an auto scrolling text (horizontal scroll, from Right to Left) (Tested on Android 8)
Class: AnimationAutoTextScroller.java
/**
* A Class for automatically scrolling text horizontally from Right to Left
* using TranslateAnimation so that the scrolling speed can be controlled -Suresh Kodoor
*/
public class AnimationAutoTextScroller {
Animation animator;
TextView scrollingTextView;
int duration = 50000; // default value
public AnimationAutoTextScroller(TextView tv, float screenwidth) {
this.scrollingTextView = tv;
this.animator = new TranslateAnimation(
Animation.ABSOLUTE, screenwidth,
Animation.RELATIVE_TO_SELF, -1f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f
);
this.animator.setInterpolator(new LinearInterpolator());
this.animator.setDuration(this.duration);
this.animator.setFillAfter(true);
this.animator.setRepeatMode(Animation.RESTART);
this.animator.setRepeatCount(Animation.INFINITE);
// setAnimationListener();
}
public void setDuration(int duration) {
this.duration = duration;
}
public void setScrollingText(String text) {
this.scrollingTextView.setText(text);
}
public void start() {
this.scrollingTextView.setSelected(true);
this.scrollingTextView.startAnimation(this.animator);
}
public void setAnimationListener() {
animator.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
// This callback function can be used to perform any task at the end of the Animation
}
public void onAnimationRepeat(Animation animation) {
}
});
}
}
Layout XML: (keep the TextView under a HorizontalScrollView)
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
app:layout_constraintBottom_toTopOf="#+id/hguide3"
app:layout_constraintEnd_toStartOf="#+id/vguide2"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="#+id/vguide1"
app:layout_constraintTop_toBottomOf="#+id/hguide2">
<TextView
android:id="#+id/translateanimatortextviewscroller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_marginEnd="0dp"
android:layout_marginLeft="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:text=""
android:singleLine="true"
android:focusable="true"
android:scrollHorizontally="true"
android:background="#000000ff"
android:textColor="#ff0000"
android:textSize="55dp"
android:textStyle="bold"
android:typeface="sans" />
</HorizontalScrollView>
Activity:
TextView scrollertextview = findViewById(R.id.translateanimatortextviewscroller);
textscroller = new AnimationAutoTextScroller(scrollertextview, screenwidth);
textscroller.setScrollingText(scrollertext);
textscroller.setDuration(60000);
textscroller.start();
Add this Animation file:
<translate
android:duration="7000"
android:fromYDelta="0%p"
android:interpolator="#android:anim/accelerate_interpolator"
android:repeatCount="10"
android:repeatMode="restart"
android:toYDelta="-100%p" />
/*Put your text view inside scroll*/
<ScrollView
android:layout_width="#dimen/dp_size_220"
android:layout_height="#dimen/dp_size_16"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/iv_myra_notification"
app:layout_constraintRight_toLeftOf="#+id/iv_one_way"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/marquee_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="left"
android:text="#{itemData.notification.message}"
android:textColor="#android:color/black"
android:textSize="12sp"
tools:text="bfnfkjnvlen jknjkgnojeng"/>
</ScrollView>
try this code it will help you out Shri n HERO
<?xml version="1.0" encoding="utf-8"?>
<translate>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXDelta="1500"
android:interpolator="#android:anim/linear_interpolator"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toXDelta="-1250" />
</translate>
This is what worked for me.
Place your textview inside a scroll view and then perform TranslateAnimation on the scrollview's child, my case its the LinearLayout.
I am actually adding multiple views dynamically inside this linear layout.
<ScrollView android:id="#+id/textScrollView"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/textLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
</ScrollView>
TranslateAnimation slide = new TranslateAnimation(0, 0, height, -textLayout.getHeight());
slide.setDuration(movementSpeed);
slide.setRepeatCount(-1);
slide.setRepeatMode(Animation.RESTART);
slide.setInterpolator(new LinearInterpolator());
textLayout.startAnimation(slide);
height --> The point start scrolling up (in my case device height (device bottom))
movementSpeed --> scrolling speed
Use this simple way with ellipsize and marquee options using #rajath answer
<TextView
android:text="Single-line text view that scrolls automatically if the text is too long to fit in the widget"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Its really frustrating,...
But the answer is simple,
Use Edittext instead of TextView, and wrap it in horizontalscrollview
At the same time, setfocusable: false
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:scrollbars="none">
<EditText
android:id="#+id/post_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:focusable="false"
android:outlineAmbientShadowColor="#color/colorPrimaryDark"
android:shadowColor="#000000"
android:shadowDx="1.5"
android:shadowDy="1.3"
android:shadowRadius="1.6"
android:singleLine="true"
android:textAlignment="center"
android:textColor="#color/colorPrimary"
android:textSize="20dp" />
</HorizontalScrollView>
Thanks to Hein, add the animation code
final EditText textView = view.findViewById(R.id.post_message);
textView.startAnimation((Animation) AnimationUtils.loadAnimation(context,R.anim.horizontal_animation));
String message="LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLong Text.";
textView.setText(message);
<translate>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXDelta="1500"
android:interpolator="#android:anim/linear_interpolator"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toXDelta="-1250" />

Android animation starts only after scrolling it's parent view

I'm trying to create an expandable menu item in android, which will look like a button and on button click, button will expand to down with animation. I set an expand animation for the layout which i want to expand when clicked to my view and I have problem with animation. It doesn't start immediately when I clicked the view, and it starts when I scroll-down or scroll-up the container of the view. And if the container is not scrollable, my animation never starts. What am I doing wrong?
Here is my expand method, onClick method and the layout xml file for my custom view which will do this things:
expand:
public void expand(final View v) {
try {
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class, int.class);
m.setAccessible(true);
m.invoke(v,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(((View)v.getParent()).getMeasuredWidth(), MeasureSpec.AT_MOST)
);
} catch (Exception e) {
Log.e(TAG , "Caught an exception!", e);
}
final int initialHeight = v.getMeasuredHeight();
Log.d("test", "initialHeight="+initialHeight);
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
final int newHeight = (int) (initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(1000);
a.setInterpolator(AnimationUtils.loadInterpolator(context,
android.R.anim.accelerate_decelerate_interpolator));
v.startAnimation(a);
isExpanded = !isExpanded;
}
onClick:
public void onClick(View v) {
if (!isExpanded) {
expand(subButtonsLayout);
} else {
collapse(subButtonsLayout);
}
}
Layout xml for custom menu item view:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mtx="http://schemas.android.com/apk/res/com.matriksdata.trademaster"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
android:id="#+id/xExpandableMenuButtonTop"
android:background="#drawable/opened_menu_bg_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
<LinearLayout
android:background="#drawable/opened_menu_bg_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical">
<LinearLayout
android:id="#+id/xExpandableMenuButtonTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="#+id/xExpandableMenuButtonText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:textAppearance="#style/expandable_menu_button_textstyle"
android:text="Button Text">
</TextView>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="6"
android:src="#drawable/menu_button_down_arrow">
</ImageView>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/xExpandableMenuButtonSubButtonsLayout"
android:background="#drawable/opened_menu_bg_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical"
android:visibility="gone">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<com.myproject.control.XSubMenuButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mtx:XSubMenuButtonText="SubMenu1">
</ccom.myproject.control.XSubMenuButton>
<com.myproject.control.XSubMenuButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mtx:XSubMenuButtonText="SubMenu2">
</com.myproject.control.XSubMenuButton>
<com.myproject.control.XSubMenuButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mtx:XSubMenuButtonText="SubMenu3">
</com.myproject.control.XSubMenuButton>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/xExpandableMenuButtonBottom"
android:background="#drawable/opened_menu_bg_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
</LinearLayout>
If you haven't solved your problem or if anyone else comes across this problem, here is a quick solution. Invalidate your parent view on each click (in the onClick method). This should work regardless of if the parent is scrollable or not.
That is, your code will be something like:
public void onClick(View v) {
if (!isExpanded) {
expand(subButtonsLayout);
} else {
collapse(subButtonsLayout);
}
rootView.invalidate();
}
To anyone who might face this again.
If your view, the one that you are animating is in the gone state, then in that case, before starting the animation, set Visiblity to invisible. And it will work in the first go.
Source from here.
I had a view that I declared at the end of my layout to keep its Z index above its siblings. I had to touch the page to make the animation work.
So I set the Z index again through Java and it worked.
view.bringToFront();
Well, I fixed the problem using only 2 lines.
scroll.setFocusableInTouchMode(true);
scroll.requestFocus();
animation.Start();//Start anim
Good luck
"If the container is not scrollable, the animation never starts" --> Have a look at my similar problem, Scrollview doesn't swipe when it's too short to scroll. I figured out in my case it's a touch bug in Android 2.1 and under.

Categories

Resources