Friday, March 29

[Android Code] ทำตัวเลขวิ่งๆด้วย ValueAnimator

Google+ Pinterest LinkedIn Tumblr +

          สวัสดีครับกลับมาเจอกันอีกครั้งหลังจากห่างหายการเขียนบทความ Android ไปเสียนาน ก่อนหน้านี้เมื่อหลายเดือนก่อนผมอยากจะทำให้ตัวเลขใน TextView ให้มันวิ่งๆมาถึงค่าที่เราต้องการ แต่หาจนแล้วจนรอดก็ไม่เจอกันที ผ่านไปหลายเดือนในที่สุดผมก็เจอวิธีทำ นั่นก็คือ ValueAnimator นั่นเองงงง!!

          ValueAnimator เป็นญาติพี่น้องกับ Property Animation ตัวอื่นๆของ Android แต่มันไม่ได้ทำ Animation ตรงๆ การทำงานของมันคือการเพิ่มค่าจากจุดๆนึงไปยังอีกจุดนึง เช่น เพิ่มจาก 0 เป็น 1000 ซึ่งเหมาะมากกับการเอาไปทำตัวเลขวิ่งๆ เพื่อความสวยงาม เรามาลองกันเลยดีกว่า

ก่อนอื่นก็สร้าง Layout xml ขึ้นมาก่อน ผมใส่เป็น TextView 1 อันแล้วประกาศ Id ให่มันด้วยนะครับ อย่าลืม ใส่ Id ของ 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:id="@+id/layoutBg"
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="com.kamonway.valueanimator.MainActivity">

<TextView
android:id="@+id/textCount"
android:layout_centerInParent="true"
android:textSize="40sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
[/xml]

วิธีใช้งาน ValueAnimator ก็เหมือน Class ทั่วไปคือประกาศตัวแปรขึ้นมาก่อนแบบนี้
[java] ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1000);
[/java] ตรง ValueAnimator.ofInt(start, end) การกำหนดให้มันเริ่มทำงานที่ค่าเท่าไหร่แล้วบวกเพิ่มไปจนถึงค่าเท่าไหร่ สามารถใส้ได้ทั้ง Int, Float, ARGB(ค่าสีต่างๆ) ผมให้มันเริ่มที่ 0 แล้วเพิ่มไปจนถึง 1000

จากนั้นก็เป็นส่วนของการกำหนดเวลา แบบนี้
[java] valueAnimator.setDuration(5000);
[/java] ตรงนี้จะใส่เวลาเป็น millisecond โดย 1000 เท่ากับ 1 วินาที

นอกจากนี้เรายังสามารถกำหนดรูปแบบของการเพิ่มขึ้นของค่าด้วย Interpolator ได้อีกด้วย
[java] valueAnimator.setInterpolator(new LinearInterpolator());
[/java]

แล้วก็มาถึงขั้นตอนสำคัญ การเพิ่ม Listener เพื่อให้รู้ว่าค่าเปลี่ยนไป เราจะได้นำค่าไปใส่ใน TextView ได้
[java] valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer) animation.getAnimatedValue();
textView.setText("X is " + value);
}
});
[/java] จะเห็นว่าเราแปลง AnimatedValue ออกมาเป็น int แล้วค่อยเอาไปใส่ใน Textview เหมือนปกติ (ง่ายเนอะ)

ข้อสำคัญ!!! อย่าลืม Start มันด้วย เดี๋ยวจะไม่ทำงาน
[java] valueAnimator.start();
[/java]

เราจะได้ Code ออกมารูปร่างหน้าตาประมาณนี้
[java] ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1000);
valueAnimator.setDuration(5000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer) animation.getAnimatedValue();

textView.setText("X is " + value);
}
});
valueAnimator.start();
[/java]

ลอง Run ดูเลยครับ เราจะเห็น Textview เขียนว่า X is 0 แล้ววิ่งไปจนถึง X is 1000

ตัวเลขกำลังวิ่งเลยตอนนี้

ตัวเลขกำลังวิ่งเลยตอนนี้

          ป่ะ เรามาเล่นกันต่อ อย่างที่บอกว่ามันรับ Parameter เป็นค่าสีได้ ดังนั้นมันจึงเปลี่ยนสีของ View ได้เหมือนกัน เรามาเปลี่ยนสีของ Background กัน ก่อนอื่นก็สร้างตัวแปร colorFrom กับ colorTo ก่อนเพื่อบอกสีตั้งต้นและสีที่อยากจะเปลี่ยนไป
[java] Integer colorFrom = Color.TRANSPARENT;
Drawable background = layoutBg.getBackground();
if (background instanceof ColorDrawable){
colorFrom = ((ColorDrawable) background).getColor();
}
Integer colorTo = Color.RED;
[/java] จากนั้นก็ประกาศตัวแปร ValueAnimator สำหรับรับค่าสี
[java] ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
[/java] การกำหนดเวลาทำเหมือนเดิม แต่ตรงส่วน Listener อาจจะแตกต่างไปนิดหน่อย แบบนี้
[java] colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
layoutBg.setBackgroundColor((Integer) animator.getAnimatedValue());
}

});
colorAnimation.start();
[/java] เมื่อเรารับค่า Integer มาก็นำไปใส่เป็น BackgroundColor ของ View แล้วอย่าลืม Start

สี Background จะค่อยๆเปลี่ยนไปเป็นสีแดง

สี Background จะค่อยๆเปลี่ยนไปเป็นสีแดง

          เป็นไงครับ ValueAnimator ใช้ง่ายมากๆ เพื่อนลองเอาไปเล่นกันดูได้ ทำเสร็จแล้วอย่าลิมเอามาอวดกันบ้างนะครับ อยากเห็น Animation สวยๆ ด้านล่างเป็น Code ทั้งหมดครับ มีแถบส่วนเปลี่ยนสีของ TextView ด้วย
[java] public class MainActivity extends AppCompatActivity {
TextView textView;
RelativeLayout layoutBg;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

textView = (TextView) findViewById(R.id.textCount);
layoutBg = (RelativeLayout) findViewById(R.id.layoutBg);

animateNumber(0, 1000);
animateColorBg(Color.RED);
//animateColorText(Color.WHITE);
}

private void animateNumber(int start, int end){
ValueAnimator valueAnimator = ValueAnimator.ofInt(start, end);
valueAnimator.setDuration(5000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer) animation.getAnimatedValue();

textView.setText("X is " + value);
}
});
valueAnimator.start();
}

private void animateColorBg(Integer colorTo){
Integer colorFrom = Color.TRANSPARENT;
Drawable background = layoutBg.getBackground();
if (background instanceof ColorDrawable){
colorFrom = ((ColorDrawable) background).getColor();
}

ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(5000);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
layoutBg.setBackgroundColor((Integer) animator.getAnimatedValue());
}

});
colorAnimation.start();
}

private void animateColorText(Integer colorTo){
Integer colorFrom = Color.TRANSPARENT;
colorFrom = textView.getCurrentTextColor();

ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(5000);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
textView.setTextColor((Integer) animator.getAnimatedValue());
}

});
colorAnimation.start();
}
}
[/java]

เปลี่ยนทั้งพื้นหลัง สีตัวอักษร และตัวเลข

เปลี่ยนทั้งพื้นหลัง สีตัวอักษร และตัวเลข

ขอขอบคุณตัวอย่างต่างๆและข้อมูลอ้างอิงจากเว็บเหล่านี้
http://stackoverflow.com/questions/11935216/animation-of-height-of-linearlayout-container-with-valueanimator
http://www.programcreek.com/java-api-examples/index.php?api=android.animation.ValueAnimator
https://developer.android.com/reference/android/view/animation/Interpolator.html

Facebook Comments
Share.

About Author

สวัสดีครับ ผมไอซ์ กมลวัฒน์ ผู้ก่อตั้งช่อง Youtube Kamonway และเว็บไซต์ kamonway.com เพื่อช่วยแนะนำความรู้จากเกม และเป็นช่องทางที่ช่วยให้ทุกท่านเล่นเกมอย่างสนุกสนานยิ่งขึ้น

Comments are closed.