Bài 2 : Xây dựng các giao diện cơ bản với main.xml

Thảo luận trong 'Lập trình cho Di động' bắt đầu bởi virutmath, 14/8/10. Trả lời: 37, Xem: 22825.

  1. virutmath

    virutmath Thành viên

    Ở trong bài trước ta đã làm quen với Android qua các ví dụ về HelloWorld và HelloImage, bước đầu đã nắm được cách sử dụng main.xml để thiết kế giao diện, trình bày tranh ảnh.
    Thông thường thì, với 1 ứng dụng có 2 phần công việc cần làm là : Thiết kế giao diện và xử lý dữ liệu. Với thiết kế giao diện bạn cần code trong file main.xml, với xử lý dữ liệu bạn cần code trong file .java. Điều này tận dụng được các thế mạnh của mỗi ngôn ngữ.
    Bài này chúng ta sẽ đi tìm hiểu về các thành phần hay sử dụng trong thiết kế giao diện và lập trình chủ yếu trên file main.xml
    Đầu tiên bạn mở 1 project mới, hoặc trong project HelloWorld cũ, bạn mở file main.xml, sẽ thấy có các thành phần : LinearLayout, TextView.
    Ngoài 2 thành phần này thì còn có rất nhiều thành phần khác nữa. Vậy có những thành phần nào và chúng để làm j?

    Có thể hiểu layout là trang giấy trong đó có các view được đặt lên. View tương tác với người sử dụng.
    Vì layout giống trang giấy, nên bạn cần phải căn chỉnh nó cho phù hợp với màn hình, hoặc phù hợp với nhu cầu lập trình. Cũng giống như trong Word vậy, bạn phải căn lề, chia văn bản dạng cột, chọn định dạng giấy khổ A4 hay A5, giấy nằm ngang hay xoay dọc. Layout trong xml cũng có các thuộc tính như thế
    Có nhiều loại layout để bạn lựa chọn sử dụng :
    - FrameLayout : cái này sẽ định vị trí cho các view nằm ở góc trên bên trái màn hình
    - LinearLayout : cái này có 2 thuộc tính ngang dọc, dùng để sắp xếp các view theo chiều ngang hay chiều dọc. Đây là layout hay được sử dụng nhất
    - RelativeLayout : Thêm các view theo các mối quan hệ của nó với các view khác trong layout
    - TableLayout : Đặt các view ở dưới dạng bảng
    - AbsoluteLayout : Đặt các view theo dạng tọa độ
    Lưu ý : layout cũng là 1 view nhé
    Bài này chúng ta sẽ chỉ sử dụng LinearLayout (đặt các view theo chiều ngang hoặc dọc)
    Trong 1 thẻ layout có thể có nhiều layout khác hoặc nhiều view.
    Để khai báo 1 layout, trong main.xml ta khai báo thẻ <LinearLayout></LinearLayout>

    Các bạn xem hình sau
    [​IMG]

    Như trong hình, mình đã chèn thêm 3 layout nữa. Tuy nhiên vì không có thông số nên khi run các bạn sẽ chỉ thấy 1 layout vì các layout con đã nằm đè lên các layout cha. Vì thế ta cần cài đặt các thuộc tính cho layout
    Từ giờ ta qui ước LinearLayout là LL cho dễ viết nhé. hi

    Nhìn vào hình trên bạn sẽ thấy LL ngoài cùng có 3 thuộc tính
    - orentation : Dùng để set LL sẽ trải theo chiều ngang hay dọc. Ấn ctrl + space để xem nó có mấy giá trị nhé.
    - layout_height và layout_width. Cái này không nói chắc các bạn cũng biết. Cũng ấn ctrl space để xem
    Ngoài ra còn các thuộc tính khác :
    - Gravity
    - layout_weight

    Tham khảo http://developer.android.com/resources/tutorials/views/hello-linearlayout.html
    :
    thongnh, humorcake, legend92no113 người khác thích nội dung này.
  2. virutmath

    virutmath Thành viên

    hục, lọ mọ mãi cũng tự làm đc cái giao diện đơn của giản. Mình học chậm quá, lại lười nên giờ mới đến thiết kế giao diện. Hôm trc có mấy bro hỏi học đến đâu rồi, tưởng mình pro định hỏi, ai dè đang ở mức a ma tơ. hức, xấu hổ quá. Hôm nay up lên cái project cho anh em beginner.
  3. virutmath

    virutmath Thành viên

    Bài 2b - Xây dựng 1 giao diện đơn giản

    Mở rộng từ bài 2a ở trên. Các bạn đã biết qua 1 vài thuộc tính của layout và view. Muốn biết thêm chi tiết xin mời gõ android:.... và đợi sugget của android hoặc ấn ctrl+space và ngồi tìm hiểu từng loại thuộc tính.
    Sau đây, ta sẽ sử dụng các kiến thức cơ bản để tạo 1 giao diện như sau : <Đây là mình tạo, xấu đẹp j cũng ko đc chê nha, gà mà :D>

    [​IMG]

    Nào bắt tay vào làm cùng mình nào:

    Đầu tiên tạo 1 project mới tên là Sudoku, mấy cái còn lại tự đặt tên nha

    Rùi, vì là thiết kế giao diện nên ta lờ cái activity Sudoku đi, quay ra thư mục res mở file main.xml ra để chỉnh sửa

    Đầu tiên các bạn thấy có 1 cái ảnh ở trên cùng đúng ko. Mình down về từ google đấy. Các bạn lên google tìm cái ảnh nào hay hay nhét vào thư mục drawable nhé
    Xem hình và phân tích các bạn sẽ thấy :

    Ta cần 1 LL chính và 2 LL con :
    - LL chính trải theo chiều dọc -> vertical
    - LL con đầu tiên chứa ảnh, vì chỉ có 1 view là ImageView nên để thuộc tính ngang dọc j cũng đc
    - LL con tiếp theo chứa 4 cái button ạ. Và trải theo chiều dọc -> vertical
    ( thực ra trong ví dụ này ta chỉ cần 1 LL để vertical, nhưng tớ thích bày vẽ chút, cho nó riêng biệt nữa mà. LL 1 chứa ảnh, LL 2 chứa button. Hơn nữa để cho quen với việc phân tích các giao diện khác)
    Đi vào cụ thể nhé : Các bạn chèn thêm 2 LL nữa với code như sau (2 LL này giống nhau đấy):
    Code:
    <LinearLayout
    		android:orientation="vertical"
    		android:layout_width="fill_parent"
    		android:layout_height="fill_parent"
    		android:layout_weight="1"
                    >
    
    	</LinearLayout>
    
    Để ý số 1 trong layout_weight nhé :Sau khi code xong toàn bài bạn thử thay số khác vào xem có j xảy ra nhé. thay số nhỏ nhỏ thôi (2, 3, 4...). Chạy thử xem mấy số đấy có ý nghĩa j nhé


    Trong LL con 1, ta cần 1 ImageView, vì thế ta sẽ thêm 1 cái :

    Code:
    <ImageView
    			android:id="@+id/imageSudoku"
    			android:layout_width="fill_parent"
    			android:layout_height="fill_parent"
    			android:src="[MENTION=281999]dra[/MENTION]wable/sudoku1"
    			
    			/>
    Ở đây mình đặt tên file ảnh là sudoku1 nhé. Thuộc tính id là quan trọng cho việc viết code trong file java sau này. Vì thế sau này khi thiết kế 1 giao diện nào đó, với mỗi 1 view bạn nên đặt cho nó 1 cái id (như mình là imageSudoku), để sau này quản lý và sửa lỗi dễ hơn.

    Tiếp theo đến LL con thứ 2: Có 4 cái button, bạn chỉ cần viết 1 button thôi rồi copy paste và chỉnh sửa các thông số riêng biệt là đc.

    Code:
    <Button
    			android:id="@+id/new_game"
    			android:text="New Game"
    			android:layout_width="200px"
    			android:layout_height="50px"
    			android:lines="1"
    			android:padding="10px"
    			android:layout_gravity="center"
    			/>
    Giải thích chút nhỉ :
    - text : Mọi view đều có thuộc tính này. Cái này dùng để điền chữ vào trong view đấy, khi chạy thì view sẽ có chữ này.
    - layout_width="200px" và layout_height="50px" . Cái px này là pixel, là điểm ảnh. Tức là bạn dùng nó để chỉ ra kích thước của button. Hãy thử với các số px khác nhau để biết nhé. Ngoài px thì còn 1 vài chuẩn đo nữa, nhưng mà khá rắc rối : pt, dp, sp, in, mm (bạn tra thêm google nhé)

    - lines : chỉ ra rằng nội dung của text chỉ đc viết trên xx dòng (như code của mình là 1 dòng) . Dùng để căn chỉnh cho đồng đều ấy mà.
    - padding : chỉ ra rằng mỗi 1 view trong cùng 1 layout sẽ cách nhau bao nhiêu (đvị px nhé). Nếu để mặc định thì các view nó dính vào nhau, trông xấu :D
    - layout_gravity : căn chỉnh view ở bên trái, giữa, bên phải, trên or dưới... của layout. Nó có thể nhận các giá trị : ctrl+space nhé :D
    Ngoài ra còn 1 nhiều thuộc tính nữa nhằm trang điểm cho button của bạn, nhưng ở đây mình ko dùng. Chỉ xin nêu ra 1 số đại diện :
    - Những cái xử lý text trong view: textSize, textStyle, textColor...
    - Những cái căn chỉnh nội dung trong view : thường dùng gravity nhất, để set cho nội dung trong view nằm ở vị trí nào của view.
    - Những cái cài đặt cho view : hint; min (max)height, width; password....
    Các bạn tự thử thêm nhé. Nên để thêm quyển từ điển bên cạnh :D

    Rồi. Và đây là toàn bộ code giao diện của mình

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    	<LinearLayout
    		android:orientation="vertical"
    		android:layout_width="fill_parent"
    		android:layout_height="fill_parent"
    		android:layout_weight="1"
    		>
    		
    		<ImageView
    			android:id="@+id/imageSudoku"
    			android:layout_width="fill_parent"
    			android:layout_height="fill_parent"
    			android:src="[MENTION=281999]dra[/MENTION]wable/sudoku1"
    			
    			/>	
    	</LinearLayout>
    	<LinearLayout
    		android:orientation="vertical"
    		android:layout_width="fill_parent"
    		android:layout_height="fill_parent"
    		android:layout_weight="1"
    		>
    		
    		<Button
    			android:id="@+id/new_game"
    			android:text="New Game"
    			android:layout_width="200px"
    			android:layout_height="50px"
    			android:lines="1"
    			android:padding="10px"
    			android:layout_gravity="center"
    			android:
    			/>
    		<Button
    			android:id="@+id/continue_game"
    			android:text="Continue Game"
    			android:layout_width="200px"
    			android:layout_height="50px"
    			android:lines="1"
    			android:padding="10px"
    			android:layout_gravity="center"
    			/>
    		<Button
    			android:id="@+id/help_game"
    			android:text="Help Game"
    			android:layout_width="200px"
    			android:layout_height="50px"
    			android:lines="1"
    			android:padding="10px"
    			android:layout_gravity="center"
    			/>
    		<Button
    			android:id="@+id/quit_game"
    			android:text="Quit Game"
    			android:layout_width="200px"
    			android:layout_height="50px"
    			android:lines="1"
    			android:padding="10px"
    			android:layout_gravity="center"
    			/>
    			
    		</LinearLayout>
    		
    </LinearLayout>
    Save vào và enjoy. Quá đơn giản phải ko. Tuy nhiên các bạn hãy tự thiết kế cho mình các giao diện khác nữa. Lúc mình làm giao diện này đã bị lỗi tùm lum vì thử thêm nhiều thuộc tính khác. hehe. còn chép nguyên code trên đương nhiên chạy đc rùi, nên hãy tự chế biến thêm cho code nhé

    Bài 2b đến đây là hết. Bài 2c sẽ là xử lý tương tác với các view trong file java nhé
    bướngvl, thongnh, humorcake10 người khác thích nội dung này.
  4. virutmath

    virutmath Thành viên

    buồn nhỉ, chả ai vô đọc
    phuonga89 thích nội dung này.
  5. virutmath

    virutmath Thành viên

    chuẩn bị có phần mới, đang viết rồi. hehe.
  6. LIENHUONG

    LIENHUONG Ngôi Sao Tử Thần

    Có mình vô đọc còn j :) Chỉ là cứ ong ong cả đầu :D Ngày trước học tin mình ... tệ hại lắm :p Thế mà có lúc mình lại ước học CNTT - ĐTVT để phá máy cho sướng ...
    cron7 thích nội dung này.
  7. erhard

    erhard Thành viên

    èo, cái này hay quá, chỉ có điều phải đi học C trước mới kham nổi chứ gà mờ thì căng à
  8. erhard

    erhard Thành viên

    tiện thể cho em xin luôn cái file đính kèm trong bài 1 luôn nha, link die rùi, cái link hd cài eclipse á
  9. virutmath

    virutmath Thành viên

    sao die được. Mình vẫn down bình thường mà.
    View attachment 1.Gioi thieu ve Android SDK.zip
    cron7huhjun thích nội dung này.
  10. virutmath

    virutmath Thành viên

    an ủi an ủi. hic hic. post bài mới nào. lúc nãy mất điện, thế là toi công
    dominhtho thích nội dung này.
  11. virutmath

    virutmath Thành viên

    Bài 2c --------- Xây dựng giao diện cơ bản và xử lý tương tác với các thành phần trong activity.


    Ở bài trước ta đã biết cách xây dựng giao diện cho 1 chương trình. Bài này sẽ hướng dẫn các bạn xử lý tương tác với các thành phần trong activity như TextView, EditView, Button...
    Trước hết ta phải tìm hiểu qua về intent, mặc dù phần này còn được xem xét kĩ hơn ở 1 bài riêng về intent. Hiểu nôm na intent là chiếc thuyền để chở các "click" đến với các acitvity, thông báo sự kiện cho activity và báo cho device biết cách xử lý như thế nào. Như vậy, muốn xử lý được tương tác với các view, ta cần "mua thuyền" chở "hàng".
    Chúng ta sẽ xem xét kĩ hơn nhờ ví dụ sau. Từ từ rồi mình sẽ giải thích code. Nào, mục tiêu của chúng ta là tạo ra 1 chương trình dùng để gọi điện, thay cho trình gọi điện sẵn có của điện thoại. Nhờ có unicode dựng sẵn utf-8 nên chúng ta hoàn toàn có thể có 1 chương trình gọi điện bằng tiếng việt, hehe. Và sản phẩm của mình đây , xem ảnh để hình dung tý :

    [​IMG]

    [​IMG]

    [​IMG]


    Tạo 1 project và đăt tên cho nó nhé
    Trước hết các bạn hãy tự code cho mình cái main.xml nhé. Rồi so sánh với code của mình xem nào :

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    	<TextView
    		android:id="@+id/textLabel"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="Nhập số điện thoại cần gọi"
    		android:padding="10px"
    		/>
    	<EditText
    		android:id="@+id/phoneNumber"
    		android:layout_width="fill_parent"
    		android:layout_height="wrap_content"
    		android:hint="Nhập số vào đây"
    		android:numeric="integer"
    		android:padding="20px"
    		/>
    	<Button 
    		android:id="@+id/callButton"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="Gọi"
    		android:layout_gravity="center"
    		
    		/>
    	
    </LinearLayout>
    
    Có lẽ cần giải thích chút--- trong ô EditText ta có thuộc tính numeric. Thuộc tính này giúp hạn chế kiểu nhập vào trong ô EditText, tức là khi có mặt thuộc tính này thì nội dung đc input là kiểu số, (trong trường hợp này cụ thể là kiểu số nguyên). Những phần khác chắc bạn còn nhớ ở bài trước chứ.?
    thongnh, minhngocdvhg, vqt9073 người khác thích nội dung này.
  12. virutmath

    virutmath Thành viên

    Tiếp 2c

    Rồi, bạn đã xây xong cái nhà, giờ đến nội thất nhé
    Mở file .java ra, Bạn đặt tên project là gì nhỉ? Mình đặt là helloPhoneDialer nên file của mình là HelloPhoneDialer.java
    Lúc đầu nó trông như thế này :

    Code:
    import android.app.Activity;
    import android.os.Bundle;
    
    public class HelloPhoneDialer extends Activity {
        /** Called when the activity is first created. */
        [MENTION=123941]override[/MENTION]
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    Bạn cần phải chỉnh sửa lại. Đầu tiên là các gói package, bạn import đầy đủ các thư viện sau :
    Code:
    import android.app.Activity;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.os.Bundle;
    import android.content.Intent;
    import android.net.Uri;
    Trong hàm onCreate, bạn chú ý là trong file main.xml ta đã tạo 1 EditText, 1 TextView, 1 Button. Sự kiện mà ta cần quan tâm liên quan đến EditText ( nhập số vào đó và lấy dữ liệu ở đó để gọi mà) và Button (nhấn phát gọi luôn). Vì thế trong hàm onCreate chắc chắn phải có sự hiện diện của 2 thằng View này.

    Bạn khai báo như sau, vì tạo ở trong file main.xml rồi, nên ta ko cần tạo mới mà chỉ cần lấy dữ liệu theo id của view :

    Code:
     final Button callButton = (Button) findViewById(R.id.callButton);
               final EditText phoneNumber = (EditText)findViewById(R.id.phoneNumber);
    Giải thích chút nhỉ !
    Từ khóa final có lẽ quen thuộc với các bạn đã học java rồi. Mình cũng ko phân biệt được nhiều lắm, thường thì dùng public hoặc final. Lúc nào cần phân biệt thì tra google thôi, nếu bạn là newbie thì kô cần bận tâm đến từ đó, nó giống như 1 thành phần dùng để phân quyền truy cập các thành phần (class, biến, hàm...) trong các thành phần khác. Bỏ qua nó ta sẽ xem đến cấu trúc của câu lệnh, Cả 2 câu lệnh có dạng :

    Code:
    <thuộc tính> <type> <tên_view> = <type>findViewById(R.id.<tên_id_lưu_trữ_view)
    Câu này dùng để gọi và khai báo 1 view khi nó đã được tạo trong main.xml rồi. Vì mình cần dùng nó để xử lý, xào nấu nó, nên fai gọi nó ra báo danh, qua phương thức gọi id. Vậy là đồng thời các bạn cũng biết tác dụng của id rồi chứ, và vì sao mình bảo trong 1 view luôn fai có 1 id riêng. Chính là để quản lý trong code .java. Thử tưởng tượng bạn sẽ quản lý các view khó khăn tới mức nào khi bạn ko có id cho nó.

    Nói hơi lạc đề . hì. Tiếp nào

    Đây là phần chính của bài học đây, đó là set sự kiện click cho nút button. Tức là khi ta ấn "gọi" thì chương trình sẽ nhận được tín hiệu ấn gọi của ta để thực hiện cuộc gọi. Để làm đc việc đó bạn cần method sau :
    Code:
    public void onClick(View v)
    Nhưng đây là 1 khai báo ko tường minh, muốn khai báo đc nó bạn phải làm 1 thao tác khác. Đó là phải làm cho android "nghe" được sự kiện "click" rồi sau đó mới thực hiện nó. Ta cần khai báo sau :

    Code:
    callButton.setOnClickListener()
    Hàm này cần tạo mới 1 đối tượng để làm đối số cho hàm, và nó được xây dựng sẵn mỗi khi gặp sự kiện click vào đâu đó của chương trình. Toàn bộ đoạn code được override sẵn từ 1 interface . Và bạn sẽ thấy như sau :
    Code:
    callButton.setOnClickListener(new OnClickListener() {
    			
    			[MENTION=123941]override[/MENTION]
    			public void onClick(View v) {
    				[COLOR="Red"]//Làm gì đó với cái view của chúng ta ở trong này[/COLOR]
    			}
    		});
    Như mình comment đó thì sau khi override được method như trên ta sẽ xử lý sự kiên onClick theo ý của ta. Ở đây ta cần xử lý với mục đích : "Lấy dãy số ở EditView làm số điện thoại và thực hiện cuộc gọi"

    Nói chung để thực hiện 1 cuộc gọi bạn cần phải tạo mới 1 intent để truyền thông điệp "tao chuẩn bị gọi vào số này đấy" cho activity biết mà thực hiện, và code thì như sau :
    Code:
    Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel: [I][COLOR="Red"]số điện thoại ở đây nha[/COLOR][/I])";
    				callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    				startActivity(callIntent);
    Như ở trên mình đã tạo mới 1 intent có tên là callIntent, mình set nhiệm vụ cho nó là ACTION_CALL. Đây cũng là 1 trong những nhiệm vụ hay sử dụng nhất của 1 intent. Thành phần Uri.parse("tel: số điện thoại") dùng để nhặt dãy số sau chữ tel kia kìa, để thực hiện hành động calling.
    Với bài của chúng ta, chúng ta sẽ cần lấy "số điện thoại từ hàng text trong EditView, tức là phải get nó ra. Ta dùng lệnh này để lấy dữ liệu ra từ EditView nè :
    Code:
    phoneNumber.getText()
    Và hoàn thiện thì câu khai báo intent sẽ phải là:
    Code:
    Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber.getText()));
    Chưa xong, sau khi có nó rồi, bạn cần gọi ra activity để nó thực hiện cuộc gọi này chứ. Cụ thể cần có lời gọi hàm FLAG_ACTIVITY_NEW_TASK.

    Code:
    callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    				startActivity(callIntent);
    Câu lệnh cuối cùng chính là để khởi chạy activity.
    Nào, giờ hãy so sánh với code đầy đủ xem bạn có thiếu sót j kô nhé :

    [​IMG]


    Nếu đã chính xác rồi, hãy save vào và thưởng thức thôi. Ctrl + F11
    dungth25, totruongno1, ShjkUn8 người khác thích nội dung này.
  13. virutmath

    virutmath Thành viên

    Chú ý chút, mình sợ các bạn ko để ý. Trong các bức ảnh mình post lên, kích cỡ hơi bé, bạn hãy di chuyển chuột tới nó và click vào để mở 1 trang riêng, và ở đó bạn có thể phóng to để xem rõ hơn

    ---------- Post added at 11:32 PM ---------- Previous post was at 11:30 PM ----------

    Bài 2 đến đây là hết, Hẹn gặp các bạn ở bài 3 (chưa biết là gì). Có thể sẽ là học thêm về các View nâng cao : Radio Button, List View, Menu Option... Có lẽ bài 3 sẽ kết thúc phần view và xử lý sự kiện với view
    xenggl, Zerazickhoahut thích nội dung này.
  14. mai tu oanh

    mai tu oanh Thành viên

    cám ơn vì các bài viết quá hữu ích của virutmath
  15. erhard

    erhard Thành viên

    chua có bài tiếp theo ạ? nôn quá
  16. programervn

    programervn Thành viên

    Vẫn có người đọc chứ bác, hơn 99% người ta mua điện thoại di động để sử dụng chứ không phải để phát triển, vì vậy nó hẻo hơn mục khác. Em cũng mới tập tọe dev cho android. Sẽ phản hồi bác sau khi có ít vốn nhé.
  17. dewberry

    dewberry Thành viên

    :d hihi em đang phải viết code trên Android, gặp những bài này của bạn thật là mừng quá chừng
  18. AndroidVietnam

    AndroidVietnam Thành viên

    bài viết hay.Tích cực phát huy tiếp đi bạn hiền nhé !
  19. konal

    konal Thành viên

    Ông bạn cứ viết đi...bài viết rất hay đấy....
    Khi bạn cho đi 1 điều gì đó, bạn sẽ nhận được 1 điều lớn hơn...hehe.Hãy chờ nhé, bít đâu sẽ là 1 cơ hội ......Cố lên!
  20. badboy04

    badboy04 Thành viên

    Rất đơn giản và dễ hiểu cho newbie :D