How to fade in textview letter by letter in Android - android

I am trying to do a fade in animation on a textview letter by letter but when i do it with view animation it fade in the entire textview.
I tried to combine view animation with a handler for when letter appear but i don't get the result i wanted. this is the code i tried.
the xml file
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="#android:anim/linear_interpolator"
android:duration="3000"
android:fillBefore="true"
android:zAdjustment="bottom"/>
the java code
public class TextViewAnimator {
private TextView textView;
private CharSequence text;
private long delay;
private int index;
private Handler timerHandler = new Handler();
private Runnable animationTask = new Runnable() {
#Override
public void run() {
textView.setText(text.subSequence(0, index++));
if (index <= text.length()) {
timerHandler.postDelayed(animationTask, delay);
}
}
};
public static TextViewAnimator newInstance(TextView textView,
CharSequence text, long delay) {
TextViewAnimator instance = new TextViewAnimator();
instance.textView = textView;
instance.text = text;
instance.delay = delay;
return instance;
}
public void start() {
textView.setText("");
timerHandler.postDelayed(animationTask, delay);
}
}
is there another way to get fade in letter by letter?

I guess this is too late but still may help someone.
I too needed something like this but found a satisfactory solution nowhere, decided to make a custom View of my own, then transformed it into a library. Try [Fade-In TextView][1]. It sets text letter by letter with a nice fade-in animation.
Usage
In the XML layout
<believe.cht.fadeintextview.TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="#android:color/black"
app:letterDuration="250"/>
And in the Activity/Fragment
believe.cht.fadeintextview.TextView textView = (believe.cht.fadeintextview.TextView) findViewById(R.id.textView);
textView.setLetterDuration(250); // sets letter duration programmatically
textView.isAnimating(); // returns current animation state (boolean)
textView.setText(); // sets the text with animation

Related

How can I link some text of a TextView to an Activity?

I would like to link some text on a TextView to an Activity. This is the TextView that I have:
<TextView
android:id="#+id/termsLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/terms"
android:layout_weight="4"/>
where #string/terms is:
<string name="terms">Accept terms & conditions..</string>
If I had a link to a webpage I would do it like this:
TextView link = (TextView) findViewById(R.id.termsLink);
link.setMovementMethod(LinkMovementMethod.getInstance());
but I do not know how to start an Activity when I press the link as when it is a real link (that it links a webpage).
EDIT: Please note that I do not have to handle the onClick event in the full text because the link is only on the part "terms & conditions".
EDIT 2: I have tried using two TextView as suggested on the comments and one of the answers below to make the same effect. But sometimes (depending on the screen) the "terms & conditions" part occupy two lines because it does not fill properly on the available space so the second line it is shown on the second TextView and not on the begining of the second line.
The effect is similar to this:
Accept terms &
conditions.
and I would like that it would be like this:
Accept terms &
conditions.
Thanks in advance!
Create a helper class with inner onClick listener
public class ClickSpan extends ClickableSpan {
private String url;
private OnClickListener listener;
public ClickSpan(String url, OnClickListener listener) {
this.url = url;
this.listener = listener;
}
#Override
public void onClick(View widget) {
if (listener != null) listener.onClick(url);
}
public interface OnClickListener {
void onClick(String url);
}
}
Then convert existing span into clickable one
public static Spannable createClickableSpans(Spanned original, ClickSpan.OnClickListener listener) {
SpannableString result = new SpannableString(original);
URLSpan[] spans = result.getSpans(0, result.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = result.getSpanStart(span);
int end = result.getSpanEnd(span);
int flags = result.getSpanFlags(span);
result.removeSpan(span);
result.setSpan(new ClickSpan(span.getURL(), listener), start, end, flags);
}
return result;
}
So, final usage would be like
TextView link = (TextView) findViewById(R.id.termsLink);
link.setMovementMethod(LinkMovementMethod.getInstance());
link.setText(createClickableSpans((Spanned)link.getText(), new ClickSpan.OnClickListener(){
#Override
public void onClick(String url){
//Handle URL on text view click
}
}));
To make only part of a TextView clickable, you can use a spannable inside the TextView and set an onClick event listener. From here, you launch the activity with an intent as usual. You can limit the clickable section of the text by specifying the character positions (start to end)
Checkout this answer by #becomputer06
How to set the part of the text view is clickable
You should probably separate the text into 2 text views one with the terms and condition and one with just the accept.It would make things cleaner and easier. The following TextView is assuming its just for accept.
In the layouts corresponding java class(example: activity_main -> MainActivity):
public void start_activity(View view){
Intent newActivityIntent = new Intent(this,NewActivity.class);
startActivity(newActivityIntent);
}
NewActivity.class is just the name of the activity you want to start.
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
....
}
public void start_activity(View view){
.....
}
}

android - animation doesn't work the second time

I have a button which need to fade in. But it works only the first time. It doesn't work the second time.
Here is my code.
final TextView doctorInfoView = (TextView) rowView.findViewById(R.id.doctorInfo);
final TextView specialtyView = (TextView) rowView.findViewById(R.id.specialty);
final ImageButton deleteDoctor = (ImageButton)rowView.findViewById(R.id.deleteDoctor);
final Animation fadeInAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_in_animate);
final ImageButton editDoctor = (ImageButton)rowView.findViewById(R.id.editDoctor);
final RelativeLayout mainRowLayout = (RelativeLayout)rowView.findViewById(R.id.doctorListInfoView);
final LinearLayout rowLayout = (LinearLayout)rowView.findViewById(R.id.doctorInfoLayout);
final LinearLayout editButtonLayout = (LinearLayout)rowView.findViewById(R.id.editButtonLayout);
final LinearLayout deleteButtonLayout = (LinearLayout)rowView.findViewById(R.id.deleteButtonLayout);
rowLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (isClicked) {
editDoctor.setAnimation(fadeInAnimation);
editDoctor.setVisibility(View.VISIBLE);
deleteDoctor.setAnimation(fadeInAnimation);
deleteDoctor.setVisibility(View.VISIBLE);
mainRowLayout.setBackgroundColor(Color.parseColor("#ffffff"));
doctorInfoView.setTextColor(Color.parseColor("#eeeeee"));
specialtyView.setTextColor(Color.parseColor("#eeeeee"));
editButtonLayout.setBackgroundColor(Color.parseColor("#16aea3"));
deleteButtonLayout.setBackgroundColor(Color.parseColor("#16aea3"));
isClicked = false;
} else {
editDoctor.setVisibility(View.GONE);
deleteDoctor.setVisibility(View.GONE);
mainRowLayout.setBackgroundColor(Color.parseColor("#f2f2f4"));
doctorInfoView.setTextColor(Color.parseColor("#000000"));
specialtyView.setTextColor(Color.parseColor("#0d9e9f"));
editButtonLayout.setBackgroundColor(Color.parseColor("#f2f2f4"));
deleteButtonLayout.setBackgroundColor(Color.parseColor("#f2f2f4"));
isClicked = true;
}
}
});
Here is fade_in_animate.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="500"/>
</set>
I'd appreciated about any feedback.
One approach to solve this would be to set the animation to null
editDoctor.setVisibility(View.GONE);
editDoctor.setAnimation(null);
EDIT: You forgot to set it to infinite
animation.setRepeatCount(Animation.INFINITE);
Here is the xml
android:repeatCount="-1"
android:repeatMode="repeat"
Here is the full documentation
EDIT 2: I didn't see that you are setting the alpha. My bad. This should work! You don't need to repeat it. This will work with the method of setting the animation to null.
editDoctor.setVisibility(View.GONE);
editDoctor.setAnimation(null);
editDoctor.setAlpha(.0f);

Transition Drawable with more than 2 layers

Can there be more than 2 items in transition drawable? I need to change background so second frames fades in than on top of it third does and so on to fourth...
for now I have this:
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/voting_button_not1"/>
<item android:drawable="#drawable/voting_button_not2"/>
<item android:drawable="#drawable/voting_button_not3"/>
<item android:drawable="#drawable/voting_button_not4"/>
<item android:drawable="#drawable/voting_button_not5"/>
<item android:drawable="#drawable/voting_button_not1"/>
</transition>
And I got the button:
<ImageButton android:id="#+id/skipButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/coldf1f2"
android:scaleType="fitCenter"
android:adjustViewBounds="true"/>
P.S. never mind that its an ImageButton, that doesn't make any difference.
And in my code I got smth like this:
TransitionDrawable vote_not = (TransitionDrawable)skip.getBackground();
vote_not.startTransition(1000);
It plays transition from first item to second. But I need the full list be played.
It seems like TransitionDrawable is meant to operate only with two layers. Taken from the Android documentation for the class:
An extension of LayerDrawables that is intended to cross-fade between
the first and second layer.
I think you can specify more than two layers, because this is extension of layered drawable, but in the case of the TransitionDrawable actually only the first two are used.
you can try this option using a handler
mAnimateImage is a imageView
and DrawableImage is an array with drawables
int DrawableImage[] = {R.drawable.back_red , R.drawable.back_green, R.drawable.back_purple};
final Handler handler = new Handler();
final int[] i = {0};
final int[] j = {1};
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
Resources res = getApplicationContext().getResources();
TransitionDrawable out = new TransitionDrawable(new Drawable[]{res.getDrawable(DrawableImage[i[0]]), res.getDrawable(DrawableImage[j[0]])});
out.setCrossFadeEnabled(true);
mAnimateImage.setImageDrawable(out);
out.startTransition(4000);
i[0]++;
j[0]++;
if (j[0] == DrawableImage.length) {
j[0] = 0;
}
if (i[0] == DrawableImage.length) {
i[0] = 0;
}
handler.postDelayed(this, 8000);
}
});
}
}, 0);
You can do this with a combination of using a Handler and re-applying the TransitionDrawable for the elements of the array.
See my answer at https://stackoverflow.com/a/54584103/114549
Sounds like you might want AnimationDrawable:
http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

Highlight words in a textview when pressed

I have a TextView to display a paragraph of text and I want my application to speak individual words when they are pressed, using TTS. It would look better if words can be highlighted when pressed. I have implemented it using a ClickableSpan for each word. It works almost fine except that I do not see how to reset the highlighted state back to normal once playback is done. Each time I click a new word the previous word loses the highlight and the new one gets highlighted, but I do not know how to remove the highlight once TTS calls back:
My TextView:
<TextView
android:id="#+id/sentence"
...
android:textColorHighlight="#color/i_blue"
/>
To fill in the TextView, I use:
SpannableStringBuilder strBuilder = new SpannableStringBuilder();
Iterator<Word> iterator = e.getWordList().iterator();
int wordStart, wordEnd;
while (iterator.hasNext()) {
Word w = iterator.next();
wordStart = strBuilder.length() + w.getPrefix().length();
wordEnd = wordStart + w.getWord().length();
strBuilder.append(w.getPrefix() + w.getWord() + w.getSuffix());
final String currentWord = w.getWord();
ClickableSpan readWord = new ClickableSpan() {
private String clickedWord = currentWord;
public void onClick(View view) {
Message msg = m_HandlerReadWord.obtainMessage();
msg.obj = clickedWord;
m_HandlerReadWord.sendMessage(msg);
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
strBuilder.setSpan(readWord, wordStart, wordEnd, 0);
}
m_SentenceView.setText(strBuilder);
m_SentenceView.setMovementMethod(LinkMovementMethod.getInstance());
And I also have this method which is called once TTS calls back when it is done playing the word:
public void resetHighlight() {
//What can I do there to reset any highlighted word?
}
Is there a way I can do it? Or is there a better approach than ClickableSpan?
I finally found a trick that works for me. When the text color in the TextView changes, all highlights are reset. So if I trigger a text color change in the callback of the TTS, then the highlight gets removed. The dirty part is that the triggered color change must be a different color. So I have to change the colors both when TTS calls back and in the onClick handler of the ClickableSpan. And I set these two colors to two almost identical colors.
My ClickableSpan:
final int AlmostBlack = m_Resources.getColor(R.color.i_black_almost);
ClickableSpan readWord = new ClickableSpan() {
private int almostBlack = AlmostBlack;
public void onClick(View view) {
TextView v = (TextView) view;
v.setTextColor(almostBlack);
...
And in the handler when TTS calls back:
m_SentenceView.setTextColor(m_Resources.getColor(R.color.i_black));
If you want to do something similar but without waiting for TTS or anything to call back, you can use a Color State List to trigger color changes when the view is pressed or released:
The Color State List, res/color/clickable_words.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:color="#color/i_black_almost" android:state_pressed="true"/>
<item android:color="#color/i_black" />
</selector>
The TextView:
<TextView
android:id="#+id/sentence"
...
android:textColor="#color/clickable_words"
android:textColorLink="#color/clickable_words"
android:textColorHighlight="#color/i_blue" />

Spinning wheel in Android

How can I spin a image wheel in an activity on android with the help of touch event? I need some guideline or link of any tutorial.
This is typically done with a couple pieces. This is how I do it in one of my apps. *Note: This is not a smooth wheel, so much as it starts and stops at the top (which was intentional). You can lookup more about Animation on the dev site.
Main XML that has an image:
<ImageView
android:id="#+id/anim_example"
android:src="#drawable/loading_circle"
android:layout_width="30sp"
android:layout_height="30sp"
android:onClick="RunAnimation" />
Here are the parts in code that run the animation
public void RunAnimation(View v)
{
//The onClick method has to be present and must take the above parameter.
StartLoading();
//This will delay the stop for 5 seconds
//Normally you would want to actually have this run based on some other input/data.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
StopLoading();
}
}, 5000);
}
public void StartLoading() {
ImageView refreshImage = (ImageView) this.findViewById(R.id.anim_example);
refreshImage.setImageDrawable(getResources().getDrawable(R.drawable.loading_circle));
Animation rotateLoading = AnimationUtils.loadAnimation(this, R.anim.rotate);
refreshImage.clearAnimation();
refreshImage.setAnimation(rotateLoading);
}
public void StopLoading() {
ImageView refreshImage = (ImageView) this.findViewById(R.id.anim_example);
if (refreshImage.getAnimation() != null)
{
refreshImage.clearAnimation();
refreshImage.setImageDrawable(getResources().getDrawable(R.drawable.loading_circle));
}
}
anim.rotate:
<?xml version="1.0" encoding="utf-8"?>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="359"
android:duration="2000"
android:repeatMode="restart"
android:repeatCount="-1"
android:pivotX="50%"
android:pivotY="50%">
</rotate>

Categories

Resources