[DEV]เล่นกับ TextView ตัวอักษรเลื่อน

0

           หากใครได้อ่านตรง Profile ก็จะเห็นได้ว่านอกจากนักอ่านแล้วผมยังเป็นนักเขียนโปรแกรม ( Programmer ) อีกด้วย ที่จริงผมอยากจะทำบทความเกี่ยวกับสอนเขียนโปรแกรม Android มานานแล้ว แต่ติดที่ว่าขี้เกียจและความรู้ไม่คั่อยแน่น เลยพลัดมาเรื่อยๆ จนวันนี้เกิดอยากแบ่งปันขึ้นมาเลยมาเขียน

          ผมก็หัดเขียน Android ได้ไม่นาน รู้แค่พื้นฐาน ก็ถือซะว่าเรามาเรียนรู้ไปด้วยกันเลยแล้วกันนะครับ

           วันนี้เริ่มกันด้วย TextView แบบวิ่งกันดีกว่า ลองนึกถาพตัวอักษรวิ่งๆที่อยู่ด้านล่างของพวกรายการข่าวในทีวีก็คงจะนึกออก ซึ่งก็มีคนทำเอาไว้แล้ว ชื่อว่า MarqueeView โดยวิธีใช้ก็ไม่ได้อยากอะไร เดี๋ยวเรามาลองทำกันดู

          Source https://github.com/ened/Android-MarqueeView

           เริ่มแรกก็สร้าง Project ขึ้นมาก่อน ของผมเลือกเป็น Blank Activity with Fragment
20-02-15 10-31-30 PM

           จากนั้นเข้าไปที่ build.gradle ของ Project ตามรูปด้วยล่าง ดูว่าเราใช้ respositories ของ mavenCentral() หรือไม่ ถ้ายังไม่มีก็เติมซะนะ
20-02-15 10-34-27 PM

           จากนั้นก็เข้าไปที่ build.gradle(Module:app) เพิ่ม Code ด้านล่างใน dependencies

build.gradle(Module:app)

dependencies {
    ...
    compile 'asia.ivity.android:marqueeview:1.1.5'
}

          ลองกด Syn Now ดู ถ้าผ่านก็ OK ไปกันต่อได้

           ต่อไปเราจะมาทำส่วนของ Layout กัน โดย Layout หลักของผมคือ activity_main.xml แต่ข้างในเป็น Fragment เลยทำให้ Layout จริงของผมคือ fragment_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:marquee="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <TextView
            android:text="First MarqueeView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            />

        <asia.ivity.android.marqueeview.MarqueeView
            android:id="@+id/marqueeView"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do."
                android:singleLine="true"
                android:ellipsize="end"
                tools:ignore="HardcodedText"/>

        </asia.ivity.android.marqueeview.MarqueeView>

    </LinearLayout>

</RelativeLayout>

           อย่าลืมใส่บรรทัดที่ 3 xmlns:marquee=http://schemas.android.com/apk/res-auto ตามรูปนะครับเดี๋ยวจะ Error

           มาอธิบายให้เข้าใจกันอีกนิดดีกว่า จะเห็นว่าจะมี android:id=”@+id/marqueeView” ซึ่งเอาไว้กำหนดขนาดของกรอบที่ตัวอักษรจะแสดง เช่นตัวอย่างกำหนดความกว้างเป็น layout_width=”100dp” คือจะแสดงตัวอักษรแค่ความกว้าง 100dp เท่านั้น(กำหนดเป็น match_parent ก็ได้นะ) ถ้าประโยคของเราเกินจากนี้จะไม่แสดงต้องรอมันเลื่อนเอง

           ส่วน textview android:id=”@+id/textView1” เอาไว้กำหนดตัวอักษรที่จะแสดง ตามปกติทั่วไป

           จากนั้นเรามาทำส่วนของ Code กันบ้างไปกันที่ MainActivity.java ของผมเป็น Fragment เลยขอข้ามไปดูที่ตรงกำหนดค่าใน Fragment เลยแล้วกันนะครับ ใน onCreateView ให้เพิ่ม Code ด้านล่างนี้ลงไป

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

import asia.ivity.android.marqueeview.MarqueeView;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            final MarqueeView mv = (MarqueeView) rootView.findViewById(R.id.marqueeView);
            mv.setPauseBetweenAnimations(500);  //Set stop time when finish
            mv.setSpeed(10);    //Set speed 
            getActivity().getWindow().getDecorView().post(new Runnable() {
                @Override
                public void run() {
                    mv.startMarquee();
                }
            });

            return rootView;
        }
    }
}

           การเรียก MarqueeView ก็เหมือนกับการประกาศ Textview ธรรมดา แค่เปลี่ยนเป็น MarqueeView
           ส่วนการกำหนดเวลาตอนที่ตัวอักษรวิ่งจนหมดคำแล้วหยุดให้กำหนดโดยคำสั่ง

mv.setPauseBetweenAnimations(500);

           ส่วนการกำหนดความเร็วในการเลื่อนตัวอักษาให้กำหนดโดยคำสั่ง

mv.setSpeed(10);

           จากนั้นเรียก Runnable เพื่อสั่งให้ตัวอักษรเริ่มทำการเลื่อนด้วย

getActivity().getWindow().getDecorView().post(new Runnable() {
                @Override
                public void run() {
                    mv.startMarquee();
                }
            });

           จากนั้นลองกด Run ดู ผลออกมาตัวอักษรของเราจะทำการเลื่อนแล้ว

ภาพหน้าจอ อยากถ่ายวีดีโอให้ดูนะ แต่มือถือไม่อำนวย

ภาพหน้าจอ อยากถ่ายวีดีโอให้ดูนะ แต่มือถือไม่อำนวย

          เรามาทำเพิ่มกันอีกนิด โดยมีปุ่มกด 2 ปุ่มให้ เริ่มเลื่อนตัวอักษร และ หยุดเลื่อน กันดีกว่า กลับมาที่ fragment_main.xml อีกครั้ง แล้วก็เพิ่มปุ่ม 2 ปุ่ม เพื่อ เริ่มเลื่อนและหยุดเลื่อน

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:marquee="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <TextView
            android:text="First MarqueeView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            />

        <asia.ivity.android.marqueeview.MarqueeView
            android:id="@+id/marqueeView"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do."
                android:singleLine="true"
                android:ellipsize="end"
                tools:ignore="HardcodedText"/>

        </asia.ivity.android.marqueeview.MarqueeView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <Button
                android:id="@+id/btnStop"
                android:text="Stop"
                android:layout_width="0dp"
                android:layout_weight="50"
                android:layout_height="wrap_content"/>

            <Button
                android:id="@+id/btnStart"
                android:text="Start"
                android:layout_width="0dp"
                android:layout_weight="50"
                android:layout_height="wrap_content"/>
        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

           เราเพิ่ม Button 2 อัน กำหนด id ว่า btnStart และ btnStop

           จากนั้นมาที่ MainActivity.java เพื่อกำหนดให้กับการกดปุ่ม ที่ btnStart เราจะกำหนดให้เมื่อกดปุ่ม ตัวอักษรจะเริ่มเลื่อน และ btnStop เราจะกำหนดให้เมื่อกดปุ่ม ตัวอักษรจะหยุดเลื่อน โดยเพิ่ม Code ด้านล่างเพิ่มจากของเดิม

@Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            final MarqueeView mv = (MarqueeView) rootView.findViewById(R.id.marqueeView);
            mv.setPauseBetweenAnimations(500);  //Set stop time when finish
            mv.setSpeed(10);    //Set speed
            getActivity().getWindow().getDecorView().post(new Runnable() {
                @Override
                public void run() {
                    mv.startMarquee();
                }
            });
            
            rootView.findViewById(R.id.btnStart).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mv.startMarquee();
                }
            });

            rootView.findViewById(R.id.btnStop).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mv.reset();
                }
            });

            return rootView;
        }

          ลอง Run ดูครับ เมื่อเรากด Start ตัวTextจะเริ่มเลื่อนใหม่ตั้งแต่แรก เมื่อกด Stop ตัวTextจะหยุดเลื่อน

           เป็นอย่างไรกันบ้างครับกับ Library ตัวอักษรเลื่อนนี้ คงไม่ยากใช่มั้ยครับ วันหลังผมจะหา Library ตัวอื่นๆมาฝากอีกนะครับ โชคดี

Source Codeโหลดได้จาก Github หรือ Zip

package com.kamonway.blog_movingtext;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

import asia.ivity.android.marqueeview.MarqueeView;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            final MarqueeView mv = (MarqueeView) rootView.findViewById(R.id.marqueeView);
            mv.setPauseBetweenAnimations(500);  //Set stop time when finish
            mv.setSpeed(10);    //Set speed
            getActivity().getWindow().getDecorView().post(new Runnable() {
                @Override
                public void run() {
                    mv.startMarquee();
                }
            });

            rootView.findViewById(R.id.btnStart).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mv.startMarquee();
                }
            });

            rootView.findViewById(R.id.btnStop).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mv.reset();
                }
            });

            return rootView;
        }
    }
}
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:marquee="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <TextView
            android:text="First MarqueeView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            />

        <asia.ivity.android.marqueeview.MarqueeView
            android:id="@+id/marqueeView"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do."
                android:singleLine="true"
                android:ellipsize="end"
                tools:ignore="HardcodedText"/>

        </asia.ivity.android.marqueeview.MarqueeView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <Button
                android:id="@+id/btnStop"
                android:text="Stop"
                android:layout_width="0dp"
                android:layout_weight="50"
                android:layout_height="wrap_content"/>

            <Button
                android:id="@+id/btnStart"
                android:text="Start"
                android:layout_width="0dp"
                android:layout_weight="50"
                android:layout_height="wrap_content"/>
        </LinearLayout>

    </LinearLayout>

</RelativeLayout>
Facebook Comments
Share.

About Author

Comments are closed.