2012年11月18日 星期日

捲動 TextView 可以捲動 (scroll) 內容


main.java:

contentTextView = (TextView) findViewById(R.id.contentTextView);
contentTextView.setMovementMethod(ScrollingMovementMethod.getInstance()); //可以Scroll textview 的內容


res/layout/main_activity_layout.xml:


<TextView
        android:id="@+id/textView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:maxLines="15"
        android:scrollbarStyle="outsideInset"
        android:scrollbars="vertical"
        android:singleLine="false"
        android:text=""
        android:textColor="#00FF00"
        android:textSize="20dp" />

2012年10月22日 星期一

iOS - Find a String and Replace


找尋字串裡是否含有某一個字或某一段文字,如果確定找到,將之取代為另一個字或另一段文字:

e.g.
I am in a bad mood.  ==>  I am in a good mood.
我今天心情很。  ==>   我今天心情很

*************************************************

- (void) viewDidLoad {

NSString *original = @"I am in a bad mood.";

NSLog (@"After replace, the result = %@", [self replaceStringWithSomeCharacters: original]);

}

- (NSString *) replaceStringWithSomeCharacters : (NSString *) aString{
    
 // 1. 定義要換掉的字串
    NSRange search = [aString rangeOfString:@"bad" options:NSCaseInsensitiveSearch];
  
//2. 建立一個新字串,值為 ""
    NSString *afterReplace = @"";

//3. 如果有找到要替換的"bad"
    if (search.location != NSNotFound) {

//4. 以"good" 替換掉 search 
        afterReplace = [aString stringByReplacingCharactersInRange:search withString:@"good"];

//5. 回傳替換後的結果
        return afterReplace;
    }
  
//4. 字串中找不到有"bad"的地方,回傳原來的字串
    return aString;
}

2012年10月6日 星期六

iOS --.xlsx 檔轉成 .csv 檔,準備之後轉成 sqlite檔使用



以 mac 的作業系統為例:
將 Excel 的 .xlsx 檔轉成 .csv 的步驟:

1. 建立一個 .xlsx 檔



 2. 另存成 .csv 檔

 3. 以 text 瀏覽器打開,在此我使用 TextWrangler 。到 Edit --> Document Options:
   
             
 4. 將它 copy 入 Xcode 的 project 裡以用建立 sqlite 檔使用。
     要確定 .csv 檔在 project 裡沒問題,可以點它,看中文有無亂碼:
     如果見到如下,就沒問題:

     學生;國文;英文
     John;89;90
     Mary;56;83
     Peter;78;54


*PS 在 .xlsx 裡輸入資料時,請不要用英文的分號 (;)。如果真的需要分號,請以中文的方式輸入(;)。這樣才能確保在程式裡轉檔成sqlite檔案時不會出問題!!!

 
 


2012年9月17日 星期一

IO -- (4) SDCARD



IO: 列出SDCARD裡的夾子與檔案 & 讀取SDCARD裡某檔案的內容 

public class IO_ListSDCardFilesActivity extends Activity {
    /** Called when the activity is first created. */

private final String SD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
private final String FILE_PATH = "/fileio";
private final String FILE_NAME = "test02.txt";
private final String ENCODING = "UTF-8";

FileInputStream fis = null; // 這裡要設定,否則無法用

TextView tv;
ListView lv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
        tv = (TextView) findViewById(R.id.textView);
     
        //列出Sdcard 裡的夾子和檔案,放上LISTVIEW
        try {
        File sdcardPATH = Environment.getExternalStorageDirectory();// 找SD的入徑
        String [] fileNamesArrayStr = sdcardPATH.list(); // 用list(),將SD裡的資料夾和檔案以字串的方式收集在array
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fileNamesArrayStr);// 以 listView 顯示在螢幕上
        lv = (ListView) findViewById(R.id.listView1);
        lv.setAdapter(adapter);
        } catch (Exception e) {
        e.printStackTrace();
        }
 
     
        readFile(); //讀出指定的檔到TEXTVIEW上
     
    }// end of onCreate
 
 
 
    public void readFile () {
   
    String result = "";
    try {
   
    File mFilePath = new File (SD_PATH + FILE_PATH);
    String mFileName = mFilePath + "/" + FILE_NAME;
    File fileText = new File (mFileName);
   
    fis = new FileInputStream(fileText);
    int length = fis.available();
    byte [] buffer = new byte [length];
    fis.read(buffer);
    result = EncodingUtils.getString(buffer, ENCODING);
    fis.close();
    tv.setText(result);
   
    } catch (Exception e) {
    e.printStackTrace();
    }
    }// end of readFile();
}

IO: (6) + TTS 給英聽練習使用


IO + TTS : 給英聽練習使用


主程式:


//設計英語英聽口說練習
public class IO_TTS_EnglishSpeakingActivity extends Activity implements OnInitListener{
    /** Called when the activity is first created. */
private final String SDCARD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
private final String FILE_PATH = "/fileio";
// private final String ENCODING = "UTF-8";
private File [] filesArray;
private File mDataPath;
private FileInputStream fis = null;
TextView tv;
ListView lv;
private String aFileName;
String [] strings;
 
private TextToSpeech mTTS;
private Button answerBtn;
private Button goBackBtn;
String result = "";
private static int NO_OF_QUESTIONS = 5;
private String [] questionsStr = new String [NO_OF_QUESTIONS];
private int flag; //判斷是否還留在原來的試卷裡
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tv= (TextView) findViewById(R.id.textView01);
//        tv.setMovementMethod(ScrollingMovementMethod.getInstance());
        
        mDataPath = new File (SDCARD_PATH + FILE_PATH);
        filesArray = mDataPath.listFiles();
        
        listFiles();//列出所有的檔案
        
        mTTS = new TextToSpeech(getApplicationContext(), this);//初始化
        answerBtn = (Button) findViewById(R.id.button2);
        answerBtn.setOnClickListener(answerListener);
        
        goBackBtn = (Button) findViewById(R.id.goBackButton);
        goBackBtn.setOnClickListener (goBackListener);
        
        flag = 1;
           
    }// end of onCreate
    
    
    //列出所有英聽的檔案,顯示在ListView上
    private void listFiles() {
    
    String fileNames = ""; // to receive every single file name
        for (int i = 0; i < filesArray.length; i++) {
        if (filesArray[i].isFile()) { //get rid of directories
        String tempStr = ""; //會多出入徑的字串
        tempStr = filesArray[i].toString();
        String strSub = ""; //to subtract the uneccessary part: /mnt/sdcard/fileio/ (19 個字元)
        strSub = tempStr.substring(19, tempStr.length()).toString();
        fileNames += strSub + "--";
        }
        }
        
        //Handle to subtraction of the final "--" in fileNames string
        String result = "";
        result = fileNames.substring(0, fileNames.length()-2);
        strings = TextUtils.split(result, "--");
        
        
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings);
        lv = (ListView) findViewById(R.id.listView1);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(listener);
    
    }// end of listFiles ();
    
    
    
// 看答案的按鈕
private OnClickListener answerListener = new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub

if (questionsStr[0] == null) {
Toast.makeText(Cq_IO01Activity.this, "請選擇試卷!",
Toast.LENGTH_SHORT).show();
tv.setMarqueeRepeatLimit(-1);
} else if (flag == 1){
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
Cq_IO01Activity.this,
android.R.layout.simple_list_item_1, questionsStr);
lv.setAdapter(adapter);
answerBtn.setText("不看題目");
answerBtn.setTextColor(Color.MAGENTA);
flag = 0;
} else if (flag == 0) {
listFiles();

answerBtn.setText("觀看題目");
answerBtn.setTextColor(Color.BLACK);
flag = 1;
}
}
};
    
    
  //按下按鈕回到原先列出全部英聽檔案的畫面
  private OnClickListener goBackListener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (mTTS != null) {
mTTS.stop();
}
listFiles();
tv.setText("請選擇下列試題卷練習英聽口說:");
tv.setTextColor(Color.RED);
tv.setMarqueeRepeatLimit(-1);
answerBtn.setText("觀看題目");
answerBtn.setTextColor(Color.BLACK);
}
};
  
  
    //選擇要唸出的檔案; 將內容的五個問題分別間隔唸出
    private OnItemClickListener listener = new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
aFileName = strings[position].toString();

tv.setText("正在播放 " + aFileName + " 練習,一共五題,每題播放兩次:");
tv.setTextColor(Color.GREEN);
tv.setMarqueeRepeatLimit(-1);
readSingleLine(aFileName); //讀出每個問題
}
};// end of listener
    
private void readSingleLine (String aFileName) {
try {
String mFileName = mDataPath + "/" + aFileName;
File fileContent = new File (mFileName);
fis = new FileInputStream(fileContent);
DataInputStream dis = new DataInputStream(fis);
for (int i = 0; i< NO_OF_QUESTIONS; i++) {
String tempStr = "";
tempStr = dis.readLine() + "\n";
questionsStr[i] = tempStr;
//讀出所選檔案的內容
mTTS.speak(tempStr, TextToSpeech.QUEUE_ADD, null); //用QUEUE_ADD可以再接其他的字串;queue_flush將無法做到                                                       //唸第一次
mTTS.playSilence(2000, TextToSpeech.QUEUE_ADD, null);   //停頓兩秒
mTTS.speak(tempStr, TextToSpeech.QUEUE_ADD, null);        //唸第二次
mTTS.playSilence(2000, TextToSpeech.QUEUE_ADD, null);   //停頓兩秒
mTTS.speak("Please answer now.", TextToSpeech.QUEUE_ADD, null); //請使用者回答
mTTS.playSilence(8000, TextToSpeech.QUEUE_ADD, null);                  //給予八秒的時間回答

}
} catch (Exception e) {
e.printStackTrace();
}
}// end of readSingleLine ()

@Override
public void onInit(int status) {
// TODO Auto-generated method stub
if (status == TextToSpeech.SUCCESS) {
mTTS.setSpeechRate(0.9f);// 正常速度是 1.0f; 小過它會變慢
mTTS.speak("I'm ready for listening and speaking practice.", TextToSpeech.QUEUE_FLUSH, null);
}else {
System.out.println("Oops!");
}
}


@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mTTS.shutdown();
}


@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (mTTS != null) {
mTTS.stop();
}
}
}


**********************************
res/layout/main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/sunset" >

    <TextView
        android:id="@+id/textView01"
        android:layout_width="350px"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:text="請選擇下列試題卷練習英聽口說:"
        android:ellipsize="marquee"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:textColor="#FF0000"
        android:textSize="22dp" />

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="75dp"
        android:layout_weight="0.70"
        
        android:divider="@drawable/list_item_divider"
        android:cacheColorHint="#00FF0000"
        android:dividerHeight="5px"    >
        
    </ListView>

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        
        <Button
        android:id="@+id/button2"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="觀看題目" />
        
        <Button
        android:id="@+id/goBackButton"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="選擇新試卷" />
        
    </LinearLayout>

    
</LinearLayout>

*******************************
res/drawable/list_item_divider:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="line" >
   <stroke 
       android:width="1dp"
       android:color="#8F8F8F"
       android:dashWidth="1dp"
       android:dashGap="1dp"/>
</shape>







2012年8月18日 星期六

俄文新聞 + ClickableSpan and WebView

閱讀有註解的俄文新聞
Using ClickableSpan and WebView

public class LangRusReaderActivity extends Activity {
    /** Called when the activity is first created. */
private TextView tv;
private static WebView wv;
private String str = "Головной ракетный крейсер четвертого поколения \"Юрий Долгорукий\" " +
"поднимет Андреевский стяг как боевая единица российского ВМФ уже в июле. И день флота " +
"его экипаж встретит в месте постоянного базирования. Будет это Вилючинск на Камчатке или " +
"Западная Лица на Кольском полуострове, пока не уточняется. Но в Минобороны, в Объединенной " +
"судостроительной корпорации и на \"Севмаше\" уже не скрывают: первенец в серии подводных " +
"ракетоносцев, созданных по проекту 955 \"Борей\" санкт-петербургского ЦКБ \"Рубин\", завершает" +
" финальный этап испытаний в Белом море.";
private String [] strings; //To every word in the str into an string array
private String result=""; //To de-array "strings[]" into a string
private CharSequence text; //For spannable use
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        initiation();
        toHtmlFormat();
        toSpannableString ();
    }
    
    
    private void initiation () {
    tv = (TextView) findViewById(R.id.textview01);
    tv.setTextSize(20);
    tv.setLinkTextColor(Color.BLUE);
    tv.setMovementMethod(LinkMovementMethod.getInstance());
    
    wv = (WebView) findViewById(R.id.webView);
    wv.setWebViewClient(new WebViewClient()); //Create
    WebSettings ws = wv.getSettings(); // Get obj
    ws.setJavaScriptEnabled(true);
    
    ws.setSupportZoom(true);
    ws.setBuiltInZoomControls(true);
    
    wv.clearCache(true);
    wv.canGoBack();
    wv.canGoForward();
    
    }
    
  //Rearrange the text into the HTML format
    private void toHtmlFormat () {
    strings = TextUtils.split(str, " ");
    //clear empty space on both sides of a word if any
    for (int i=0; i<strings.length; i++) {
    String temp = "";
    temp = strings[i].trim();
    temp = "<a style='color:yellow' href='" + temp + "'> "+ temp + "</a>"; // Turn into HTML format
    strings[i] = temp;
    }
    
    for (int i=0; i<strings.length; i++) {
    result += strings[i];
    }
    
    tv.setText(Html.fromHtml(result));
    
    }// end of toHTMLFormat
    
    
    //Make every word from result into clickable spannableString
    private void toSpannableString () {
    text = tv.getText();
    if (text instanceof Spannable) {
    Spannable sp = (Spannable) tv.getText();
    //Toast.makeText(this, sp, Toast.LENGTH_LONG).show();
    URLSpan[] urlspan = sp.getSpans(0, text.length(), URLSpan.class);
    
    SpannableStringBuilder style = new SpannableStringBuilder(text);
    style.clearSpans();
    for (URLSpan url : urlspan) {
    MyClickableURLSpan mClickUrlSpan = new MyClickableURLSpan(url.getURL());
    style.setSpan(mClickUrlSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    tv.setText(style);
    }
    }
    
    
    private static class MyClickableURLSpan extends ClickableSpan {

    private String mUrl;
    
    public MyClickableURLSpan(String url) {
// TODO Auto-generated constructor stub
    mUrl = url;
}
    
@Override
public void onClick(View widget) {
// TODO Auto-generated method stub
//Remove any punctuation sign of a word on right hand side, e.g. "," , "!", or "."
String temp = "";
if (mUrl.startsWith("(") || mUrl.startsWith("[")) {
temp = mUrl.substring(1, mUrl.length());
mUrl = temp;
}
if (mUrl.endsWith(")") || mUrl.endsWith("]") ) {
temp = mUrl.substring(0, mUrl.length()-1);
mUrl = temp;
}
if (mUrl.startsWith("\"") || mUrl.startsWith("'")) {
temp = mUrl.substring(1, mUrl.length());
mUrl = temp;
}
if (mUrl.endsWith("\"") || mUrl.endsWith("'")) {
temp = mUrl.substring(0, mUrl.length()-1);
mUrl = temp;
}
if (mUrl.endsWith(".") || mUrl.endsWith(",") || mUrl.endsWith("!")) {
temp = mUrl.substring(0, mUrl.length()-1);
mUrl = temp;
}
wv.loadUrl("http://lingvo.yandex.ru/" + mUrl + "/по-английски/");
}

@Override
public void updateDrawState(TextPaint ds) {
// TODO Auto-generated method stub
//super.updateDrawState(ds);
ds.setColor(ds.linkColor);
ds.setUnderlineText(false);
}
    
    }//end of class
}


*************************
res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
        <TextView
        
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="#00FF00"
        android:textSize="16dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="2dp"
        android:text="英文新聞"></TextView>
    
        <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal" >

       
<!-- 

android:layout_marginTop="10dp"
 -->
        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
             />
        
        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#FFF380"
            android:fadingEdge="vertical"
            android:paddingTop="10dip"
            android:scrollbars="vertical" >

            <TextView
                android:id="@+id/textview01"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="4dp"
                android:text="@string/hello" >
            </TextView>
        </ScrollView>
        
    </LinearLayout>

***********************
Manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cq.spannable.read.english.text"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/read"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".Cq_SpannableReadEngActivity"
            android:screenOrientation="landscape" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Spannable String 的變化


Spannable String 的變化

public class Cq_SpannableStringActivity extends Activity {
    /** Called when the activity is first created. */
TextView mtv = null;
SpannableString msp = null;
String source = "字體測試字體大小一半兩倍前景色背景色正常粗體斜體粗斜體下畫線刪除線x1x2電話郵件網站斷信採信地圖X軸綜合/bot";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mtv = (TextView) findViewById(R.id.textview);
        
        //Create a SpannableString obj
        msp = new SpannableString(source);
        
        //Set font (default, default-bold, monospace, serif, san-serif)
        msp.setSpan(new TypefaceSpan("monospace"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new TypefaceSpan("serif"), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //Set font Size (絕對值,單位:像素)
        msp.setSpan(new AbsoluteSizeSpan(20), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new AbsoluteSizeSpan(20, true), 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //dip true: 表示字體大小單位為dip,否則就是像素,同上
        
      //Set font Size (相對值,單位:像素) 參數表示為默認字體大小的倍數
        msp.setSpan(new RelativeSizeSpan(0.5f), 8, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new RelativeSizeSpan(2.5f), 10, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //Set foreground color
        msp.setSpan(new ForegroundColorSpan(Color.MAGENTA), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
      //Set Background color
        msp.setSpan(new BackgroundColorSpan(Color.CYAN), 15, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //Set fontstyle:regular, bold, italic, bold-italic
        msp.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), 18, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 20, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 22, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 24, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //Set underline, strikethrough, subscript, superscript
        msp.setSpan(new UnderlineSpan(), 27, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan (new StrikethroughSpan(), 30, 33, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan (new SubscriptSpan(), 34, 35, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan (new SuperscriptSpan(), 36, 37, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //Links (setMovementMethod  should be added)
        msp.setSpan(new URLSpan("tel:0229205319"), 37, 39, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new URLSpan("mailto:cqchoucq@gmail.com"), 39, 41, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new URLSpan("http://tw.yahoo.com"), 41, 43, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new URLSpan("sms:0229205319"), 43, 45, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new URLSpan("mms:0229205319"), 45, 47, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new URLSpan("geo:38.899533, -77.036476"), 47, 49, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //Set fontSize (相對值,單位:像素)參數表示為默認字體寬度的多少倍
        msp.setSpan(new ScaleXSpan(2.0f), 49, 51, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //2.0f 為寬度的兩倍,即x軸方向放大默認字體的兩倍,而高度不變
        
        
        //Set font (including font name, style, color, linking color)
        ColorStateList csllink = null;
        ColorStateList csl = null;
        
        XmlResourceParser xppcolor = getResources().getXml(R.color.color);
        try {
        csl = ColorStateList.createFromXml(getResources(), xppcolor);
        }catch(XmlPullParserException e) {
        e.printStackTrace();
        }catch(IOException e) {
        e.printStackTrace();
        }
        
        XmlResourceParser xpplinkcolor = getResources().getXml(R.color.linkcolor);
        try {
        csllink = ColorStateList.createFromXml(getResources(), xpplinkcolor);
        }catch(XmlPullParserException e) {
        e.printStackTrace();
        }catch(IOException e) {
        e.printStackTrace();
        }
        
        msp.setSpan(new TextAppearanceSpan("monospace", android.graphics.Typeface.BOLD_ITALIC, 30, csl, csllink), 51, 53, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        
        //Set list item symbol
        msp.setSpan (new BulletSpan(android.text.style.BulletSpan.STANDARD_GAP_WIDTH, Color.GREEN), 0, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //第一個參數表示symbol的寬度,第二個參數表示symbol的顏色
        
        //setPicture
        Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        msp.setSpan(new ImageSpan(drawable), 53, 57, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        mtv.setText(msp);
        mtv.setMovementMethod(LinkMovementMethod.getInstance());
        
    }
}