I am trying to make an animation with two textviews. Both are in a relative layout. The functionality of the animation is left textview will go little bit left and at the same time right textview will also go little bit left. I have tried:
http://nineoldandroids.com/ and default way.
But for both case I am getting a gap during the process. I already put one question but i am not getting any positive reply:
Android slider animation is not synchronized
Nineoldandroids code:
xml file:
<RelativeLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#+id/target"
android:layout_marginTop="50dp">
<TextView
android:id="#+id/TextView01"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:background="#f00"
android:gravity="center"
android:text="RED"
android:textColor="#000" />
<Button
android:id="#+id/TextView02"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/TextView01"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/TextView01"
android:background="#0F0"
android:text="TXT"
android:visibility="invisible" />
</RelativeLayout>
MainActivity.java:
public class MainActivity extends Activity {
double counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.toggles);
final View target = findViewById(R.id.target);
final int duration = 5*1000;
final int duration1 = 300;
final View textView1 = findViewById(R.id.TextView01);
final View textView2 = findViewById(R.id.TextView02);
textView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (counter == 0) {
textView2.setVisibility(View.VISIBLE);
ObjectAnimator.ofFloat(textView1, "translationX", 0, -50).setDuration(duration1).start();
ObjectAnimator.ofFloat(textView2, "translationX", 100, 0).setDuration(duration1).start();
counter++;
}
else {
ObjectAnimator.ofFloat(textView1, "translationX", -50,0).setDuration(duration1).start();
ObjectAnimator.ofFloat(textView2, "translationX", 0,100).setDuration(duration1).start();
counter--;
}
}
});
}
}
How can I fix it?
otherwise I am trying to put both textview inside a layout where second textview will be outside the screen and using the animation I will move the whole layout. how can I make the xml like this?
Sorry for misunderstanding your question.
Anyway, your issue is not about time exactly. Both animations have the same duration but the problem is the sizes of the animated regions are different. Logically, moving a longer distance in the same duration will look slower than moving a smaller distance.
For example, to solve your problem, I used the following code in the OnClickListener:
public void onClick(View v) {
int width =textView2.getWidth();
if (counter == 0) {
textView2.setVisibility(View.VISIBLE);
ObjectAnimator.ofFloat(textView1, "translationX", 0, -1*width).setDuration(duration1).start();
ObjectAnimator.ofFloat(textView2, "translationX", 1*width, 0).setDuration(duration1).start();
counter++;
}
else {
ObjectAnimator.ofFloat(textView1, "translationX", -1*width, 0).setDuration(duration1).start();
ObjectAnimator.ofFloat(textView2, "translationX", 0, 1*width).setDuration(duration1).start();
counter--;
}
}
Try this
<!-- YOUR CONTAINER -->
<LinearLayout
android:id="#+id/target"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/target"
android:layout_marginTop="50dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/TextView01"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:background="#f00"
android:gravity="center"
android:text="RED"
android:textColor="#000" />
<Button
android:id="#+id/TextView02"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/TextView01"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/TextView01"
android:background="#0F0"
android:text="TXT"
android:visibility="invisible" />
</LinearLayout>
Then use a ViewPropertyAnimator like this (if you can use it)
//Translate your view -50 to the left.
yourLinearLayout.animate().translationX(-50).setDuration(1000);
With the ObjectAnimator I achieved the same results by using this code
Button textView02 = (Button) findViewById(R.id.textView02);
LinearLayout target = (LinearLayout) findViewById(R.id.target);
int width = textView02.getWidth();
ObjectAnimator.ofFloat(target, "translationX", 0, -width).setDuration(1000).start();
Hope this helps you
Related
I have made a app in which on button click i have slided a linear layout.The code to slide the linear layout is working fine but the problem is that it lags when sliding.Also the height which i have set to slide the layout doesnt look proper on all screen sizes(Specially on Nexus 5).Please do help me out
XMl
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_upload_add"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/add" />
<LinearLayout
android:id="#+id/ll_upload_options"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#drawable/choosefile_bg"
android:gravity="center"
android:orientation="vertical">
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
android:id="#+id/tv_upload_gallery"
style="#style/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:padding="5dp"
android:text="GALLERY"
android:textSize="20sp"
android:visibility="visible" />
<TextView
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="#drawable/line" />
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
android:id="#+id/tv_upload_camera"
style="#style/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:padding="5dp"
android:text="CAMERA"
android:textSize="20sp"
android:visibility="visible" />
<TextView
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="#drawable/line" />
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
android:id="#+id/tv_upload_file"
style="#style/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:padding="5dp"
android:text="FILE"
android:textSize="20sp"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/all_left_mar"
android:layout_marginRight="#dimen/all_right_mar"
android:layout_weight="2"
android:gravity="center"
android:orientation="vertical">
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.EditTextFont
style="#style/edit_text"
android:drawableBottom="#drawable/line_black"
android:hint="File Title"
android:textColor="#000"
android:textColorHint="#000" />
<AutoCompleteTextView
style="#style/edit_text"
android:layout_marginTop="10dp"
android:completionThreshold="1"
android:drawableBottom="#drawable/line_black"
android:hint="Type"
android:textColor="#000"
android:textColorHint="#000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<Switch
android:id="#+id/switch1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="false"
android:textOff="No"
android:textOn="Yes" />
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
style="#style/text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="#string/Protect"
android:textColor="#000" />
</LinearLayout>
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.EditTextFont
style="#style/edit_text"
android:layout_marginTop="10dp"
android:drawableBottom="#drawable/line_black"
android:hint="Password"
android:inputType="numberPassword"
android:textColor="#000"
android:textColorHint="#000" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="#dimen/all_left_mar"
android:layout_marginRight="#dimen/all_right_mar"
android:layout_weight="1">
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.ButtonFont
style="#style/button"
android:text="UPLOAD" />
</LinearLayout>
</LinearLayout>
Code
if (llUploadOptions.getMeasuredHeight() != 0) {
// tvGallery.setVisibility(View.GONE);
// tvCamera.setVisibility(View.GONE);
// tvFile.setVisibility(View.GONE);
ValueAnimator anim = ValueAnimator.ofInt(llUploadOptions.getMeasuredHeight(),200);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = llUploadOptions.getLayoutParams();
layoutParams.height = val;
llUploadOptions.setLayoutParams(layoutParams);
}
});
anim.setDuration(700);
anim.start();
} else {
ValueAnimator anim = ValueAnimator.ofInt(llUploadOptions.getMeasuredHeight(),250);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = llUploadOptions.getLayoutParams();
layoutParams.height = val;
llUploadOptions.setLayoutParams(layoutParams);
}
});
anim.setDuration(700);
anim.start();
}
The problem is, that you are trying to animate the height of your Layout. That means, that with every animation step you call setLayoutParams() which forces your whole layout (incl. children) to be relayouted by going through the complete view hierarchy and this leads to laggy animation. Layouting things is an expensive operation!
There are some "workarounds" (I'm not sure what you want to do):
Since Android 4.0 you simply can use animate layout changes in your xml if you simply want to show / hide a element with animations in your layout
For more complex things you may consider to use Transitions framework introduced in Kitkat (Api 19) https://www.youtube.com/watch?v=S3H7nJ4QaD8. Backports: https://github.com/guerwan/TransitionsBackport or https://github.com/andkulikov/transitions-everywhere
"Fake" the animation by animating views by hand with translation, alpha etc. and set the LayoutParameters only once after the animation has been finished
I can't remember how the api is called, but you can subclass from ViewGroup and use it as your root layout. You have to intercept layout changes while animating the height somehow to get a smooth animation (this is how animateLayoutChanges = true works). However thats an advanced topic an I would recommend to go one of the other ways
you are using Animators (not Animations), which might be laggy, especially with moving widgets. try TranslateAnimation
TranslateAnimation animation = new TranslateAnimation(0.0f, 200.0f,
0.0f, 0.0f);
// these are delta's, check doc for this constructor
// TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(700);
llUploadOptions.startAnimation(animation);
if you want to leave your animated view with final coordinates use
animation.setFillAfter(true);
but it might not be clickable or other issues might occur. for these you might use
animation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation anim)
{
};
public void onAnimationRepeat(Animation anim)
{
};
public void onAnimationEnd(Animation anim)
{
//set fixed position in here, using LayoutParams or setTop/setRight etc. methods of View (API 11)
};
});
edit:
so instead of ValueAnimator you might do smth like this
int desiredHeightInPx = getResources().getDimensionPixelSize(R.dimen.expandedHeight);
//note those are pixels, not dp. you might set this as =200 or =250 like you have
ScaleAnimation animation = new ScaleAnimation(0, 0, 0, desiredHeightInPx/llUploadOptions.getMeasuredHeight(), Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
animation.setDuration(1000); //ms
llUploadOptions.startAnimation(animation);
next steps as above, fillAfter or set AnimationListener and inside onAnimationEnd set final LayoutParams.
be aware that ScaleAnimation is scaling, it might be more appropiate to use RelativeLayout instead of Linear (which rescales its childers)
i have a Button i want to have - 4 images around its boundaries .
all images exactly the same size .
and they have to be located like in the shown picture.
i don't want to use image button because it can attach only one image,
please dont offer to create one image on a image button - because i have a dynamic order .
Just tell me how to set the location of images progmatically according to button location .
You can use relative layout to implement this!
Also you can make relative layout clickable and set onClickListener on it and make click animation on it! It will work as big button with custom layout on it!
<RelativeLayout
android:layout_height="200dp"
android:layout_width="200dp"
android:id="#+id/real_button"
android:clickable="true">
<Button android:id="#+id/fake_empty_button"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:visibility="invisible"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_above="#+id/fake_empty_button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_launcher"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toLeftOf="#+id/fake_empty_button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_launcher"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toRightOf="#+id/fake_empty_button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_launcher"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_below="#+id/fake_empty_button"
android:src="#drawable/ic_launcher"/>
</RelativeLayout>
Instead of 200dp make 3 * picture height and istead of 100dp make 1 * picture height!
In the activity:
int mX = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.real_button).setOnClickListener(listener);
}
private OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
if (mX % 2 == 0) {
findViewById(R.id.real_button).setBackgroundColor(Color.RED);
} else {
findViewById(R.id.real_button).setBackgroundColor(Color.WHITE);
}
mX += 1;
}
};
I'm using Slide Up/Down Animation for my four TextView. Following is my XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/shadow"
android:orientation="vertical"
android:weightSum="2.0" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0" >
<TextView
android:id="#+id/textViewblue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_marginLeft="25dp"
android:background="#drawable/blue"
android:gravity="center"
android:text="blue" />
<TextView
android:id="#+id/textVieworange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_marginRight="25dp"
android:background="#drawable/orange"
android:gravity="center"
android:text="orange" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0">
<TextView
android:id="#+id/textViewpink"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="25dp"
android:background="#drawable/pink"
android:gravity="center"
android:text="pink" />
<TextView
android:id="#+id/textViewgreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_alignParentTop="true"
android:layout_marginRight="25dp"
android:background="#drawable/green"
android:gravity="center"
android:text="green" />
</RelativeLayout>
</LinearLayout>
and Following is my Class
public class HomeScreenActivity extends Activity implements OnClickListener {
TextView textViewblue, textVieworange, textViewpink,
textViewgreen;
Animation mAnimation_up, mAnimation_down;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
mAnimation_up = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_SELF, 0f,
TranslateAnimation.RELATIVE_TO_SELF, 0f,
TranslateAnimation.RELATIVE_TO_SELF, 1.6f,
TranslateAnimation.RELATIVE_TO_SELF, 0f);
mAnimation_up.setDuration(1000);
mAnimation_up.setRepeatCount(-1);
mAnimation_up.setRepeatMode(Animation.REVERSE);
mAnimation_up.setInterpolator(new LinearInterpolator());
mAnimation_down = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_SELF, 0f,
TranslateAnimation.RELATIVE_TO_SELF, 0f,
TranslateAnimation.RELATIVE_TO_SELF, 0f,
TranslateAnimation.RELATIVE_TO_SELF, 1.6f);
mAnimation_down.setDuration(1000);
mAnimation_down.setRepeatCount(-1);
mAnimation_down.setRepeatMode(Animation.REVERSE);
mAnimation_down.setInterpolator(new LinearInterpolator());
initialize();
}
private void initialize() {
textViewblue = (TextView) findViewById(R.id.textViewblue);
textVieworange = (TextView) findViewById(R.id.textVieworange);
textViewpink = (TextView) findViewById(R.id.textViewpink);
textViewgreen = (TextView) findViewById(R.id.textViewgreen);
textViewblue .setOnClickListener(this);
textVieworange .setOnClickListener(this);
textViewpink .setOnClickListener(this);
textViewgreen .setOnClickListener(this);
textViewblue .setAnimation(mAnimation_down);
textViewpink .setAnimation(mAnimation_down);
textVieworange .setAnimation(mAnimation_up);
textViewgreen .setAnimation(mAnimation_up);
}
#Override
public void onClick(View v) {
Intent intentmenu;
switch (v.getId()) {
case R.id.textViewblue:
Toast.makeText(this, "blue", Toast.LENGTH_LONG).show();
break;
case R.id.textVieworange:
Toast.makeText(this, "orange", Toast.LENGTH_LONG).show();
break;
case R.id.textViewpink:
Toast.makeText(this, "pink", Toast.LENGTH_LONG).show();
break;
case R.id.textViewgreen:
Toast.makeText(this, "reeng", Toast.LENGTH_LONG).show();
break;
}
}
}
The problem is that when any TextViewslide for int position means when animation starts the onClickListener works only at its XML position not for its updated position.
Please suggest me the solution for that, how can I detect the updated position for to detect onClickListener on TextView.
Thanks.
Maybe that's a bit complicated to make it. As you're using View animation system, the behavior is under expectation. Although the Views are translated to other places, they're just being
drawn there. From the system's perspective, they're in fact always at the original place where you define in xml file. If you want the click event at the new place, you should use the new property animation system.
The onClickListener is not working because views are shifted from their original place due to animation. To solve this create a same layout below your animation and initially make its Gravity as GONE and when your animation finishes up make its Gravity as Visible and your animation layout visibility as Gone.
also be careful that all the id's of animation and original layout would not be same.
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" />
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.