Sunday, November 24

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

Google+ Pinterest LinkedIn Tumblr +

           หากใครได้อ่านตรง 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)
[xml]dependencies {

compile ‘asia.ivity.android:marqueeview:1.1.5’
}[/xml]

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

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

[xml title=”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>

[/xml]

           อย่าลืมใส่บรรทัดที่ 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 ด้านล่างนี้ลงไป

[java title=”MainActivity.java”] 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;
}
}
}

[/java]

           การเรียก MarqueeView ก็เหมือนกับการประกาศ Textview ธรรมดา แค่เปลี่ยนเป็น MarqueeView
           ส่วนการกำหนดเวลาตอนที่ตัวอักษรวิ่งจนหมดคำแล้วหยุดให้กำหนดโดยคำสั่ง
[java]mv.setPauseBetweenAnimations(500);[/java]            ส่วนการกำหนดความเร็วในการเลื่อนตัวอักษาให้กำหนดโดยคำสั่ง
[java]mv.setSpeed(10);[/java]            จากนั้นเรียก Runnable เพื่อสั่งให้ตัวอักษรเริ่มทำการเลื่อนด้วย
[java] getActivity().getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
mv.startMarquee();
}
});
[/java]

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

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

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

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

[xml title=”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
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>
[/xml]

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

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

[java title=”MainActivity.java”] @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;
}
[/java]

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

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

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

[java title=”MainActivity.java”] 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;
}
}
}
[/java] [xml title=”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
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>
[/xml]

Facebook Comments
Share.

About Author

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

Comments are closed.