Thứ Tư, 7 tháng 8, 2013

Anh nghĩ là anh nhất định quên em được, anh bảo với mình là anh không cần em nữa. Không có em anh không còn phải đoán già đoán non xem em có yêu anh không, không còn phải rón rén e dè sợ mất em. Anh không đi tìm em, không liên lạc với em, không muốn nghe bất cứ thứ gì dính dáng đến em tận đến lúc bắt gặp em. Em đã bao giờ thử mở lòng đi yêu một người mà kết quả chẳng được gì chưa?



P/S anh sắp quên em rồi

Thứ Sáu, 14 tháng 6, 2013

Thế là hết mấy ngày ríu rít. Chuyển về nhà mới tất cả đồ đạc trong nhà đều nhờ em mua sắm.Từ cái móc áo, thau chậu... tới gối nệm đều là e chọn.
Cám ơn em nhiều.

Thứ Tư, 15 tháng 5, 2013

24 down vote accepted
Here is how you can pass an ArrayList as I tried it.
MyListClass.java - Custom class
public class MyListClass implements Parcelable{

    private int test;

    public MyListClass()
    {}

    public MyListClass(Parcel read){
        test = read.readInt();
    }

    public int getTest() {
        return test;
    }

    public void setTest(int test) {
        this.test = test;
    }

    public static final Parcelable.Creator<MyListClass> CREATOR = 
        new Parcelable.Creator<MyListClass>() {

            @Override
            public MyListClass createFromParcel(Parcel source) {
                return new MyListClass(source);
            }

            @Override
            public MyListClass[] newArray(int size) {
                return new MyListClass[size];
            }
        };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel arg0, int arg1) {
        arg0.writeInt(test);
    }
}
MyParcelable.java
public class MyParcelable implements Parcelable {

    private List<MyListClass> arrList = new ArrayList<MyListClass>();
    private int myInt = 0;
    private String str = null;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    public List<MyListClass> getArrList() {
        return arrList;
    }

    public void setArrList(List<MyListClass> arrList) {
        this.arrList = arrList;
    }

    public int getMyInt() {
        return myInt;
    }

    public void setMyInt(int myInt) {
        this.myInt = myInt;
    }

    MyParcelable() {
        // initialization
        arrList = new ArrayList<MyListClass>();
    }

    public MyParcelable(Parcel in) {
        myInt = in.readInt();
        str = in.readString();
        in.readTypedList(arrList, MyListClass.CREATOR);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel outParcel, int flags) {
        outParcel.writeInt(myInt);
        outParcel.writeString(str);
        outParcel.writeTypedList(arrList);
    }

    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {

        @Override
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        @Override
        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };
}
MainAcitivty.java
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        arrList.add(new MyListClass());
        arrList.get(0).setTest(200);

        MyParcelable object = new MyParcelable();
        object.setMyInt(100);
        object.setArrList(arrList);

        Intent intent = new Intent(MainActivity.this,ReceiverParcel.class);
        intent.putExtra("parcel", object);
        startActivity(intent);
    }
ReceiverParcel.java
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle b = getIntent().getExtras();
        MyParcelable object = b.getParcelable("parcel");

        System.out.println(object.getArrList().get(0).getTest());
        System.out.println(object.getMyInt());
}

Thứ Năm, 9 tháng 5, 2013

có nên tiếp tục cái dang dở kia ko?

đi cùng trời cuối đất, qua bao nhiêu người, cuối cùng ta lại về bên nhau. Bên nhau rồi thì có ở đc lâu ko?

Thứ Tư, 10 tháng 4, 2013

Android Notifications - Tutorial <!-- Jennifers Analytics

Android Notifications - Tutorial

Lars Vogel

Version 2.2
23.01.2013








Using the Notification Manager in Android
This article describes how to use the Notification Manager in Android. It is based on Eclipse 4.2, Java 1.6 and Android 4.2.

1. Prerequisites for this tutorial

The following assumes that you have already basic knowledge in Android development. Please check the Android development tutorial to learn the basics.

2. Notification Manager

2.1. Notification Manager

Android allows to put notification into the titlebar of your application. The user can expand the notification bar and by selecting the notification the user can trigger another activity.

2.2. Setting up Notifications

Notifications in Android are represented by the Notification class. To create notifications you use the NotificationManager class which can be received from the Context, e.g. an activity or a service, via the getSystemService() method.
NotificationManager notificationManager = (NotificationManager) 
  getSystemService(NOTIFICATION_SERVICE); 
The Notification.Builder provides an builder interface to create an Notification object. You use a PendingIntent to specify the action which should be performed once the user select the notification. Notification.Builder allows to add up two three buttons with definable actions to the notification.
// Prepare intent which is triggered if the
// notification is selected

Intent intent = new Intent(this, NotificationReceiver.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

// Build notification
// Actions are just fake
Notification noti = new Notification.Builder(this)
        .setContentTitle("New mail from " + "test@gmail.com")
        .setContentText("Subject")
        .setSmallIcon(R.drawable.icon)
        .setContentIntent(pIntent)
        .addAction(R.drawable.icon, "Call", pIntent)
        .addAction(R.drawable.icon, "More", pIntent)
        .addAction(R.drawable.icon, "And more", pIntent).build();
    
  
NotificationManager notificationManager = 
  (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

// Hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;

notificationManager.notify(0, noti); 
Showing the Notification bar with the created notification
Android 4.1 supports expandable notifications. In addition to normal notification view it is possible to define a big view which gets shown when notification is expanded. There are three styles to be used with the big view: big picture style, big text style, Inbox style. The following code demonstrates the usage of the BigTextStyle() which allows to use up to 256 dp.
String longText = "...";

Notification noti = new Notification.Builder(this).
.....
.setStyle(new Notification.BigTextStyle().bigText(longText)) 
Showing the Notification bar with the created notification

2.3. Canceling Notifications

The user can dismiss all notification or if you set your notification to auto-cancel it is also removed once the user selects it.
You can also call the cancel() for a specific notification ID on the NotificationManager. The cancelAll() method call removes all of the notifications you previously issued.

3. Pending Intent

A PendingIntent is a token that you give to another application (e.g. Notification Manager, Alarm Manager or other 3rd party applications), which allows this other application to use the permissions of your application to execute a predefined piece of code.
To perform a broadcast via a pending intent so get a PendingIntent via the getBroadcast() method of the PendingIntent class. To perform an activity via an pending intent you receive the activity via PendingIntent.getActivity().

4. Example: NotificationManager

Create a new project called de.vogella.android.notificationmanager with the activity class called CreateNotificationActivity. This activity should use the main.xml layout file.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:onClick="createNotification"
        android:text="Create Notification" >
    </Button>

</LinearLayout> 
Create the following result.xml layout file.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is the result activity opened from the notification" >
    </TextView>

</LinearLayout> 
Create a new activity called NotificationReceiverActivity with the following coding. Don't forget to register the activity in the AndroidManfest.mf.
package de.vogella.android.notificationmanager;

import android.app.Activity;
import android.os.Bundle;

public class NotificationReceiverActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.result);
  }
} 
Change the CreateNotificationActivity class to the following coding.
package de.vogella.android.notificationmanager;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class CreateNotificationActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }

  public void createNotification(View view) {
    // Prepare intent which is triggered if the
    // notification is selected
    Intent intent = new Intent(this, NotificationReceiverActivity.class);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

    // Build notification
    // Actions are just fake
    Notification noti = new Notification.Builder(this)
        .setContentTitle("New mail from " + "test@gmail.com")
        .setContentText("Subject").setSmallIcon(R.drawable.icon)
        .setContentIntent(pIntent)
        .addAction(R.drawable.icon, "Call", pIntent)
        .addAction(R.drawable.icon, "More", pIntent)
        .addAction(R.drawable.icon, "And more", pIntent).build();
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    // Hide the notification after its selected
    noti.flags |= Notification.FLAG_AUTO_CANCEL;

    notificationManager.notify(0, noti);

  }
} 
Run your application and press the button. A new notification is created. If you select it your second activity will be displayed.

5. Thank you

Please help me to support this article:
Flattr this

6. Questions and Discussion

Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.

7. Links and Literature

7.1. Source Code

Source Code of Examples

7.3. vogella Resources

vogella Training Android and Eclipse Training from the vogella team
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system
-->

Thứ Tư, 27 tháng 3, 2013

Android Page Curl Animation by Harism shows inconsistency in the reverse index count in the getBitmap() method of CurlActiviy()? - Stack Overflow

I have used Harism's Page Curl animation for my application, but I have been facing a small problem, I am using the index Value in the getBitmap() method of the CurlActivity, I need to show page numbers to the user on every flip of the page(say using a call to Toast.maketext().show), this works fine while going from page 0 to pageCount.length, but when I move page right to left(the pages, i.e. while going the other way from pageCount.lenth to 0) the index values are not consistently reduced.

Can anyone please help me with this.

Thanks in Advance.

P.S.:That would be my first question on stackoverflow

            public Bitmap getBitmap(int width, int height, int index) {
        Bitmap b = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        b.eraseColor(0xFFFFFFFF);
        Canvas c = new Canvas(b);

        //this is where index seems to go wrong on reverse counting, I believe

        Log.e("PAGE--", ""+index);
        Toast.makeText(CurlActivity.this, ""+index, Toast.LENGTH_SHORT).show();

        Drawable d = getResources().getDrawable(mBitmapIds[index]);

        int margin = 7;
        int border = 3;
share|improve this question

2 Answers

up vote 0 down vote accepted

Problem is that you really can't rely on requested page index on purpose you try to implement. Reason for the behavior you're facing is that once you flip through pages forward, only 'next page' is requested, in which case index seems to be what you're expecting. But changing pages backwards works the exact opposite, only 'previous page' is requested, and there's a gap within index between these separate operations.

There's a method CurlView.getCurrentIndex() though which is constantly set to index of the page being shown on right side. It should give you means for having actual page numbers shown.

share|improve this answer
Let me first Thank you for the wonderful piece of work you have provided us all with page curl in android. I tried your Suggested way of displaying the mCurrentIndex from the getCurrentIndex method of the CurlView class from inside the getBitmap() Method, but it seems that the getCurrentIndex Method increases the count of the Right Page by one (+1) on the Reverse flip(i.e. moving page left to right), Moreover flipping back to the first page would also not bring back the initial value(from where it had started.) Where am i going wrong here? – Some one Some where Jan 12 '12 at 22:38
Yep, got the answer to my question in the Curl view class only as you had suggested, I was being wrong trying to fetch the page Index from the getBitmap method Cheers !!! – Some one Some where Jan 13 '12 at 12:14

Firstly, Harism, thank you for sharing this beautiful framework! :)

Now, only to complement the response of Harism:

When working with magazines, books, etc, we deal with an undetermined amount of pages.

In the example presented in class CurlActivity, of project Harism-Android-Page-Curl, uses a "Switch" to control the pages. To be able to meet my needs, I had to change the method "updatePage" and then control my magazines more appropriately, regardless of the amount of pages.

My need was to present the outline below, according to the Index (of the method signature itself) and current Orientation device:

Landscape Orientation ("Side Back" with next page)

Index | Page Left | Page Right

0 | 0 | 1

1 | 2 | 3

2 | 4 | 4

3 | 6 | 7

4 | 8 | 9


Portrait Orientation ("Side Back" with same page mirrored)

Index | Page

0 | 0

1 | 1

2 | 2

3 | 3

4 | 4

....

To implement this scheme, first have to change the method getPageCount thus:

public int getPageCount() {
        //return 5;

        int pagesCount = 0;

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int wwidth = displaymetrics.widthPixels;
        int hheight = displaymetrics.heightPixels;

        if(wwidth > hheight){
            if((mBitmapIds.length % 2) > 0)
                pagesCount = (mBitmapIds.length / 2) + 1;
            else
                pagesCount = mBitmapIds.length / 2;
        }else{
            pagesCount = mBitmapIds.length;
        }
        return pagesCount;
    }

This will allow the page counter will return the actual number of pages.


Then change the method updatePage, conforms the code below:

public void updatePage(CurlPage page, int width, int height, int index) {

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int wwidth = displaymetrics.widthPixels;
        int hheight = displaymetrics.heightPixels;

        if(wwidth > hheight){

            System.out.println("case landscape orientation...");
            Bitmap front = loadBitmap(width, height, (index * 2));
            Bitmap back = loadBitmap(width, height, (index * 2) + 1);

            Matrix matrix = new Matrix(); 
            matrix.preScale(-1.0f, 1.0f); 
            Bitmap mirroredBitmap = Bitmap.createBitmap(back, 0, 0, back.getWidth(), back.getHeight(), matrix, false);

            page.setTexture(front, CurlPage.SIDE_FRONT);
            page.setTexture(mirroredBitmap, CurlPage.SIDE_BACK);

        }else{

            System.out.println("case portrait orientation...");
            Bitmap front = loadBitmap(width, height, index);
            Bitmap back = loadBitmap(width, height, index);

            page.setTexture(front, CurlPage.SIDE_FRONT);
            page.setTexture(back, CurlPage.SIDE_BACK);

        }}}

I hope I helped!

And once again, thanks for the framework Harism!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.

Thứ Hai, 21 tháng 1, 2013


Tut: Android: Cách chia text thành các trang sử dụng StaticLayout


        Chào các bạn, hnay m sẽ giới thiệu cho các bạn cách chia 1 đoạn text dài (1 chương sách hay cả cuốn sách) thành dạng trang phù hợp với màn hình điện thoại mà bạn đang sử dụng. Sau khi hoàn thành phần hướng dẫn này, các bạn sẽ đạt đc kết quả như sau:
 

I. Giới thiệu về StaticLayout:
+ kế thừa từ class android.text.Layout
+ Constructor:
StaticLayout(CharSequence source, TextPaint paint, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad)
StaticLayout có tác dụng là sắp xếp đoạn text của bạn theo layout đã xác lập. Nó sử dụng các tham số:
-          CharSequence  source: đoạn text của bạn
-          TextPaint paint: quy định màu chữ, font, cỡ chữ, style… Và dùng để vẽ text lên canvas (xem thêm về Canvas và các phương thức draw).
-          int width: chiều rộng của trang sách (phần hiển thị chữ, không kể căn lề) mà bạn muốn.
-          Layout.Alignment align:
-          float spacingmult, float spacingadd: khoảng cách dòng,…
-          boolean includepad:
+ StaticLayout “viết” chữ của bạn ntn?
StaticLayout sử dụng phương thức draw(Canvas canvas) để vẽ text lên 1 canvas. Như vậy chúng ta có thể thu được 1 đối tượng Bitmap như sau:

bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// Tạo canvas để vẽ lên
Canvas c = new Canvas(bitmap);
// Vẽ lên canvas
staticlayout.draw(c);

II. Thực hiện:

1. Chuẩn bị:
- Như bạn đã thấy, StaticLayout sẽ vẽ text lên canvas và chúng ta thu đc 1 bitmap. Để đơn giản, m sẽ sử dụng ImageView để view bitmap này.       
- Việc đầu tiên là tạo ra 1 project mới, ở đây m lấy tên là BitmapTest.
- Các bạn sửa layout của main.xml như sau:

<?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"
    >
    <ImageView
            android:id="@+id/imgview"
            android:layout_width="fill_parent"
android:layout_height="fill_parent"
            android:src="#ffFDF8A6"
    ></ImageView>        
</LinearLayout>

▲Ở đây, ImageView với id là image sẽ đảm nhận nhiệm vụ hiển thị bitmap thu đc.

▲Chạy chương trình vào lúc này sẽ cho bạn 1 màn hình màu vàng (ffFDF8A6).
-Tinh chỉnh 1 chút cho chương trình đẹp hơn:
+ Các bạn sửa method onCreate() như sau để chương trình thành full screen:

public void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);            
                        requestWindowFeature(Window.FEATURE_NO_TITLE); 
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
                                WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
}

-Tiếp theo, chúng ta cần có 1 đoạn text. Bạn có thể chọn đoạn text bất kỳ nhưng fải đảm bảo đủ dài.

String story = “<nội dung>”

-Khai báo thêm vài thông số cần thiết:

// width, height: chiều dài, rộng màn hình
            int width, height;       
            // Các thông số khác
            int textSize = 20; // cỡ chữ
            int textColor = 0xffA7573E; // màu chữ
            int pageColor = 0xffFDF8A6; // màu nền
            int topPadding = 30, leftPadding = 10; // căn trên, căn dưới
            // Paint vẽ text
      TextPaint myTextPaint;

-Thêm dòng sau vào phương thức onCreate của activity để tìm width, height của màn hình:
Display display = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
            width = display.getWidth();
            height = display.getHeight();

-Khai báo textPaint:
+Bạn có thể thêm phông chữ cho sinh động hơn:

// Xác lập font chữ
Typeface tf = Typeface.createFromAsset(this.getAssets(),"fonts/UVNDaLat_R.TTF");
// Xác lập các thông số về font chữ
myTextPaint = new TextPaint();
            myTextPaint.setColor(textColor);
            myTextPaint.setTextSize(textSize);
            myTextPaint.bgColor = pageColor;
            myTextPaint.setAntiAlias(true);
            myTextPaint.setTypeface(tf);

2.Tiến hành
-Sau đây m sẽ dùng SL để vẽ đoạn text lên màn hình:
//
            public Bitmap getPageBitmap() {                 
                        Bitmap pageContentBitmap;             
                        // Bitmap chứa text
                        pageContentBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
                        // Tạo canvas để vẽ lên
                        Canvas c = new Canvas(pageContentBitmap);
                        // Tạo StaticLayout cho nội dung text
                        StaticLayout layout = new StaticLayout(story, myTextPaint, width            - (leftPadding << 1), Layout.Alignment.ALIGN_NORMAL, 0.5f, 10f, false);
                        // Vẽ lên canvas
                        layout.draw(c);
                        return pageContentBitmap;
      }

▲Ở đây, tham số width được truyền vào là width    - (leftPadding << 1) với mục đích căn trái cho đoạn text(chừa lề khi viết, kok viết hết toàn bộ chiều rộng màn hình).

-Hiển thị bitmap lên màn hình:
khai báo và set ảnh cho ImageView:
image = (ImageView) findViewById(R.id.imgview);          
image.setImageBitmap(getPageBitmap());    

▲Bạn chạy chương trình sẽ thấy đoạn text đã đc vẽ lên. Nhg đc vẽ ở vị trí (0,0) của màn hình. Chúng ta cần chỉnh lại 1 chút method getPageBitmap():
//
            public Bitmap getPageBitmap() {                 
                        Bitmap pageBitmap, pageContentBitmap;
                        // Bitmap nền
                        pageBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
                        // Bitmap chứa text
                        pageContentBitmap = Bitmap.createBitmap(width-(leftPadding<<1), height-topPadding, Bitmap.Config.ARGB_8888);
                        // Tạo canvas để vẽ lên
                        Canvas c = new Canvas(pageContentBitmap);
                        // Tạo StaticLayout cho nội dung text
                        StaticLayout layout = new StaticLayout(story, myTextPaint, width
                                                - (leftPadding << 1), Layout.Alignment.ALIGN_NORMAL, 0.5f, 10f, false);
                        // Vẽ lên canvas
                        layout.draw(c);
                        // Canvas của nền cho vẽ ảnh nội dung lên
                        Canvas c2 = new Canvas(pageBitmap);
                        // Tô màu nền
                        c2.drawColor(pageColor);
                        // vẽ ảnh nội dung
                        c2.drawBitmap(pageContentBitmap, leftPadding<<1, topPadding, myTextPaint);
                        return pageBitmap;
      }

▲Ở đây, chúng ta sẽ dùng 1 bitmap làm nền, sau đó vẽ bitmap chứa text lên vị trí (leftPadding<<1, topPadding). Sau đó trả về bitmap nền này để show lên màn hình.

-Bi h, chạy chương trình sẽ cho kết quả đoạn text được căn chỉnh lại. Tuy nhiên, vẫn có những dòng thừa ở cuối màn hình. Điều này là do SL chỉ có tác dụng WRAP-TEXT nên bạn sẽ thu đc kết quả tương tự như hiển thị text dài trên 1 TextView.

Vậy cách giải quyết vấn đề này ntn?

Nếu bạn muốn cắt bỏ đoạn text thừa ở cuối dòng, thì đoạn text của bạn fải chia nhỏ ra sao cho khớp với kích thước trang. Hay nói cách khác, bạn fải biết đc vị trí cần cắt text. Vị trí đó nằm ổ cuối dòng-dòng cuối cùng của trang (gold position).
Thật may mắn, SL cho chúng ta 2 method:
-          public int getLineForVertical (int vertical): Trả về dòng nằm ở tọa độ (0, vertical)
-          public int getOffsetForHorizontal(int line, float horiz): Trả về index của đoạn text nằm ở dòng line và có tọa độ (horiz,0);
-Và đây là cách mà m đã làm:
//
            public void splitTextIntoPages() {                
                        // các chỉ mục dùng để cắt text
                        int offsetI = 0, offsetII = 0;
                        // Tạo Static Layout cho toàn bộ text
                        StaticLayout layout = new StaticLayout(story, myTextPaint, width
                                                - (leftPadding << 1), Layout.Alignment.ALIGN_NORMAL, 0.5f, 10f, false);
                        // Tổng số dòng
                        int totalLines = layout.getLineCount();
                        // Số dòng từng trang
                        int linePerPage = layout.getLineForVertical(height - (topPadding << 1));
                       
                        // loop to the end
                        int i = 0;
                       
                        do{
                                    //
                                    Log.i("Thong bao", "Dang chia...");
                                    //
                                    int line = Math.min(linePerPage * (i+1), totalLines-1);
                                    // vi tri của ký tự cuối trang
                                    offsetII = layout.getOffsetForHorizontal(line, width - (leftPadding << 1));           
                                    // Lấy subString                                  
                                    String sub = story.substring(offsetI, offsetII);
                                    //
                                    offsetI = offsetII;
                                    // Thêm vào danh sách
                                    listOfPages.add(sub);                        
                                    //
                                    i++;                             
                        }while (offsetII<story.length());                               
            }
▲Ở mỗi vòng lặp, chúng ta sẽ lấy “gold position” và cắt text dựa vào nó. Các đoạn text được cắt (sẽ khớp với kích thước trang) được lưu theo thứ tự vào Vector<String> listOfPages.

-Thử hiển thị trang đầu tiên:
+ method onCreate(): thêm splitTextIntoPages() vào trước dòng set ảnh cho ImageView.
+ method getPageBitmap(): bạn sửa đoạn khai báo SL:
StaticLayout layout = new StaticLayout(listOfPages.elementAt(0), myTextPaint, width- (leftPadding << 1), Layout.Alignment.ALIGN_NORMAL, 0.5f, 10f, false);

▲Chạy thử chương trình sẽ thấy các dòng thừa đã mất.

-Để hiển thị tiếp các trang sau bạn có thể làm như sau:
+ Thêm biến chỉ mục trang: int index=0;
+ method onCreate:
image.setOnClickListener(new OnClickListener() {

                                    @Override
                                    public void onClick(View v) {
                                                //
                                                if (index > listOfPages.size()-1) {
                                                            index = 0;
                                                }                                             
                                                // Xác lập ảnh
                                                image.setImageBitmap(getPageBitmap());                                        
                                                //
                                                index++;
                                                //
                                               
                                    }
                  });
+ method getPageBitmap(): sửa khai báo SL:
StaticLayout layout = new StaticLayout(listOfPages.elementAt(index), myTextPaint, width
                                          - (leftPadding << 1), Layout.Alignment.ALIGN_NORMAL, 0.5f, 10f, false);

Vậy là mỗi khi bạn click chuột vào ảnh, trang mới sẽ đc hiển thị.
Tut đến đây là kết thúc. Hy vọng những thông tin này sẽ giúp ích cho bạn.      
Download source code: http://www.mediafire.com/?bt9p65ud4nf59wm   
sưu tầm từ blog hnimblog