Wednesday, October 4, 2017

Đọc thơ Nhật cổ

Ta sẽ làm một ứng dụng thực tế, đó là ứng dụng đọc thơ Nhật.
Copy các bài thơ tùy chọn của bạn vào notepad lưu thành file txt có Encoding là UTF-8.
File xml của MainActivity gồm có một textView và một ListView.

Trong MainActivity khai báo một mảng String gồm tên các bài thơ, ở đây tôi để là bài một đến bài tám.
Khai báo một textView, listView cùng adapter, tham chiếu địa chỉ cho chúng.
Dòng tiêu đề “Thơ ca Nhật Bản” ta để phông chữ riêng của mình.

Trong thư mục Layout tạo một file xml có tên li để dùng cho listView.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="42sp"
    android:background="#ffffff"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/im"
        android:layout_width="40sp"
        android:layout_height="45sp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="5sp"
        android:contentDescription="@null"
        android:src="@drawable/hoa" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="5sp"
        android:layout_toEndOf="@+id/im"
        android:layout_toRightOf="@+id/im"
        android:textColor="#0000aa"
        android:textSize="18sp" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="10dp"
        android:contentDescription="@null"
        android:src="@drawable/muiten" />

</RelativeLayout>
Set adpater cho ListView.
adapter=new ArrayAdapter<String>(this,R.layout.li,R.id.text, ten);
Trong lệnh onItemClick của ListView, khi người dùng chạm vào dòng tên bài thơ ta lấy số dòng chạm, chuyển tên bài thơ cùng số dòng sang class mới để đọc bài thơ này.
int sodong = arg2;                  
Intent in = new Intent(MainActivity.this, five.class);                                
Bundle bun = new Bundle();           
bun.putInt("gi", sodong);                 
bun.putString("gi2",ten[sodong]);              
in.putExtras(bun);
startActivity(in);

Chạy thử để thấy hình ảnh ban đầu của ta như sau.
Tiếp theo tạo class mới có tên five, khai báo class trong file AndroidManifest.
<activity
 android:name="com.bai.baidau.five"           
 android:screenOrientation="portrait">
 </activity>
Dùng đúng tên gói package của bạn, để màn hình dọc không cho quay ngang.
File xml giao diện của class này như sau.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ImageSwitcher
        android:id="@+id/ImageSwitcher01"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_centerInParent="true"
        android:background="@drawable/nen" >
    </ImageSwitcher>
    <TextView
        android:id="@+id/tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="70dp"
        android:gravity="center_horizontal"
        android:textColor="#0000cd"
        android:textSize="18sp" />
    <ScrollView
        android:id="@+id/tz"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv"
        android:layout_marginTop="10dp" >
    <TextView
        android:id="@+id/tv2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:lineSpacingExtra="2dp"
        android:textColor="#0f0f0f"
        android:textSize="18sp"
        android:textStyle="italic" />
    </ScrollView>
    <TextView
        android:id="@+id/tv3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tz"
        android:layout_marginTop="10dp"
        android:gravity="center_horizontal"
        android:textColor="#800000"
        android:textSize="18sp" />

</RelativeLayout>
Ta dùng Relativelayout, sắp xếp 3 textView từ trên xuống dưới. TextView thứ hai ta cho nó vào trong ScrollView để nếu có bài thơ dài ta sẽ cuộn trong textView này được, không ảnh hưởng đến tên bài thơ và tên tác giả bên dưới.
Chú ý cái <ImageSwitcher trên cùng, đây là cách ta cho một cái ảnh làm nền vừa khít với màn hình mà không bị co kéo lệch ảnh.
Nếu bạn dùng LinearLayout rồi set background là ảnh, tuy vẫn được nhưng ảnh khi đó bị xô lệch không đúng như ảnh ban đầu. Bạn có thể làm thử để so sánh.
Tiếp theo vào class mới, chỉnh thành extends Activity nếu chưa có, khai báo 3 textView tv, tv2, tv3, tham chiếu địa chỉ.
Dùng lệnh để bỏ tên ứng dụng trên đầu và giữ cho màn hình luôn bật sáng.

Khai báo một mảng chuỗi là tên các tác giả cho từng bài thơ.
String[] tacgia = { "Teika","Jakuren", "Narihita", "Komachi", "Saigyo", "Teika", "Shikibu", "Teika" };
Khai báo một Object như sau.
Object[]mang={R.raw.t1,R.raw.t2,R.raw.t3,R.raw.t4,R.raw.t5,R.raw.t6,R.raw.t7,R.raw.t8};
Object giống như mảng, nhưng ta có thể cho vào đó bất cứ cái gì, ở đây là địa chỉ các file txt của các bài thơ cần đọc trong thư mục raw dưới thư mục layout.
Bên class gốc ta chuyển sang tên các bài thơ và số dòng thì bên này ta nhận lại y như vậy.
Ta set tên các bài thơ ra textView trên cùng, dùng số dòng để set tên tác giả xuống textView thứ 3. Vì số dòng tương ứng với thứ tự tên tác giả trong mảng, nên ta dùng luôn biến vitri đó để truy xuất lấy tên tác giả.
Intent in = getIntent();
Bundle bun = in.getExtras();     
int vitri = bun.getInt("gi");
String tenbai = bun.getString("gi2");
tv.setText(tenbai);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
tv3.setText(tacgia[vitri]);
Ta đọc file txt bằng cách dùng InputStream như đã biết, lấy nội dung set vào textView thứ 2 là xong.
InputStream inp = this.getResources().openRawResource((Integer) mang[vitri]);
     try
    {
    byte[] buffer = new byte[inp.available()];
        while (inp.read(buffer) != -1);
        String jsontext = new String(buffer);

        tv2.setText(jsontext);      
     
    }
    catch (IOException e)
    {
        //return null;
    }
Chú ý chỗ openRawResource((Integer) mang[vitri]);
Nếu ta biết chắc đó là file nào thì ta cho luôn vào trong ngoặc ví dụ như R.raw.t5. Nhưng do chỉ biết vị trí theo thứ tự nên ta xếp thứ tự các file cần đọc trong Object đúng như vậy và lấy ra theo vị trí của nó.
Nếu bạn làm đúng, code trông như sau.
Ứng dụng chạy sẽ trông phần đọc thơ giống như sau

Đây là ứng dụng đơn giản mà dù bạn mới học cũng làm được, dù bạn không hiểu thì cứ copy từng đoạn vào nó vẫn chạy như thường. Nhiều ứng dụng đọc sách trên Play Store cũng tương tự thế này mà thôi.
Nếu thích thơ ai đó, bạn có thể tự copy về làm thành ứng dụng để đọc.
Thậm chí với tình trạng nhà nhà làm thơ hiện nay thì bạn có thể tự làm thơ rồi cho vào ứng dụng post lên Play Store. Sau đó nhắn tin cho bạn bè, người thân hót rằng ái ôi tôi có tập thơ vừa đẩy lên Google Play xong, mới quý vị tải xuống đọc thử. Hơn chán so với việc đi mua giấy phép, tự bỏ tiền ra in, rồi mang đi biếu từng người mà cả năm sau gặp lại họ vẫn nói là tôi bận quá chưa đọc được !

Bạn nào đang tán tỉnh ai đó cũng có thể dùng cách này. Copy thơ tình hay ho vào nếu không tự sáng tác được. Rồi nhắn tin cho đối tượng rằng anh vừa có một ứng dụng rất hot chỉ dành riêng cho em thôi. Mau tải về xem ngay không nó nguội mất hí hí…

No comments:

Post a Comment