TextView:在TextView控件中單擊鏈接彈出Activity

在5.2.1節和5.2.2節介紹了<a>標籤以及TextView自動識別的特殊文本(網址、電話號、Email等),這些都可以通過單擊來觸發不同的動作。雖然這些單擊動作已經可以滿足大多數需要了,但如果讀者想在單擊鏈接時執行任意自定義的動作,那麼本節的內容非看不可。

     現在讓我們使用5.2.1節介紹的方法重新查看Html.java文件的內容,隨便找一個處理Html標籤的方法,例
如,endA方法。該方法用於處理</a>標籤。我們會發現在該方法中如下的語句。

text.setSpan(new URLSpan(h.mHref), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    其中text是SpannableStringBuilder對象,該對象即可以修改文本內容,又可以將某段文本設置成一個Span,在Android中,Span表示一段文本的效果,例如,鏈接形式、圖像、帶背景色的文本等。

    上面代碼中使用setSpan方法將某個區間(由where和len指定的區間)的文本設置成URLSpan效果,也就是鏈接顯示效果。其中URLSpan表示將文本設置成鏈接效果,該類是ClickableSpan的子類,在android.text.style包中可以找到URLSpan和ClickableSpan類。實際上,所有的Span類都在android.text.style包中。

     我們再按着查看Html.java文件內容的方法查看URLSpan.java文件的內容,會看到一個onClick方法,代碼如下:
//  覆蓋ClickableSpan類中的onClick方法,onClick方法在ClickableSpan類中是抽象方法
@Override
public void onClick(View widget) {
    Uri uri = Uri.parse(getURL());
    Context context = widget.getContext();
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
    context.startActivity(intent);
}
    在onClick方法中獲得了<a>標籤的href屬性設置的URL,並調用相應的Activity來顯示網頁。

    從onClick方法的源代碼以及ClickableSpan類的名字可以得出一個結論。在5.2.1節和5.2.2節介紹的像電話、Email、網址、鏈接都是在ClickableSpan類的onClick方法中通過Action調用相應的Activity來顯示不同的內容的。那麼我們也可以採用類似的方法,也就是自己來實現onClick方法,這樣就可以達到自定義單擊動作的目的了。
說做就做,先準備兩個TextView控件。在本例中我們使用SpannableString對象來設置Span,SpannableString和SpannableStringBuilder的區別是SpannableString不允許修改文本,只允許設置Span,而SpannableStringBuilder即允許修改文本,也允許設置Span。

下面的代碼採用了隱式創建ClickableSpan對象實例的方法來設置Span,並在其中覆蓋了onClick方法。


     現在我們來看一下setSpan方法,該方法有4個參數。第一個參數需要設置一個ClicableSpan對象,第二個和第三個參數分別表示文本中要設置成Span的某段文本的起始位置和終止位置的下一個字符的位置,也就是start和end。最後一個參數是一個標誌。在本例中設爲Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,該標誌在TextView控件中意義不大,但在EditText控件中表示在當前Span效果的前後輸入字符時並不應用Span的效果。還可以設置如下幾個類似的值。
1.  Spanned.SPAN_EXCLUSIVE_INCLUSIVE:在Span前面輸入的字符不應用Span的效果,在後面輸入的字符應用Span效果。
2.  Spanned.SPAN_INCLUSIVE_EXCLUSIVE:在Span前面輸入的字符應用Span的效果,在後面輸入的字符不應用Span效果。
3.  Spanned.SPAN_INCLUSIVE_INCLUSIVE:在Span前後輸入的字符都應用Span的效果。
本例的顯示效果如圖5.5所示。單擊屏幕上的兩個鏈接後,就會分別顯示Activity1和Activity2的界面。

package mobile.android.ch05.link.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.TextView;

public class Main extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView1 = (TextView) findViewById(R.id.textview1);
        TextView textView2 = (TextView) findViewById(R.id.textview2);

        String text1 = "顯示Activity1";
        String text2 = "顯示Activity2";
        //  將文本轉換成SpannableString對象
        SpannableString spannableString1 = new SpannableString(text1);
        SpannableString spannableString2 = new SpannableString(text2);
        //  將text1中的所有文本設置成ClickableSpan對象,並實現了onClick方法
        spannableString1.setSpan(new ClickableSpan()
        {
                       //  在onClick方法中可以編寫單擊鏈接時要執行的動作
            @Override
            public void onClick(View widget)
            {
                Intent intent = new Intent(Main.this, Activity1.class);
                //  顯示Activity1
                startActivity(intent);
            }
        }, 0, text1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //  將text2中的所有文本設置成ClickableSpan對象,並實現了onClick方法
        spannableString2.setSpan(new ClickableSpan()
        {
                       //  在onClick方法中可以編寫單擊鏈接時要執行的動作
            @Override
            public void onClick(View widget)
            {
                Intent intent = new Intent(Main.this, Activity2.class);
                //  顯示Activity2
                startActivity(intent);
            }
        }, 0, text1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //  使用SpannableString對象設置兩個TextView控件的內容
        textView1.setText(spannableString1);
        textView2.setText(spannableString2);
        //  在單擊鏈接時凡是有要執行的動作,都必須設置MovementMethod對象
        textView1.setMovementMethod(LinkMovementMethod.getInstance());
        textView2.setMovementMethod(LinkMovementMethod.getInstance());
    }
}


 bb.png

圖5.5  自定義單擊鏈接的動作


發佈了27 篇原創文章 · 獲贊 22 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章