Wednesday, August 25, 2010

simpleCursorAdapter和mutiple choice的問題

原本想說,simpleCursorAdapter的建構子是這樣︰
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
那我只要將c.query()的回傳值Cursor放入,並指定欄位from和接收並顯示的位置to,就可以資料庫的資料一筆一筆顯示出來,
本來我資料庫還包括了_open這個boolean值


為的是要讓我的mutiple choice能控制是否被選取
結果...結果...
G前輩幫我花了一些時間去找原始碼,發現...
simpleCursorAdapter只收Text,不收其它值
simpleCursorAdapter的to位置,可以收android.R.id.text1
讓我們要顯示出來的文字可以在multiple-choice的xml標籤中顯示。

Sunday, August 22, 2010

ProgressDialog提示等待視窗

  哼,只不過是一個小視窗告知使用者︰你必須等待。這麼簡單的小東西我小鰻一下就能搞定!
  結果我一搞就搞了一個下午才搞懂。
  在SDK範例大全中,看到很多的ProgressDialog都有跟著執行緒做視窗的結束,起先我以為ProgressDialog就是要跟著執行緒了,研究到最後,才發現…其實不用。
  仔細看看程式碼,書裡寫的是︰
// 顯示Progress對話方塊
      myDialog = ProgressDialog.show
                 (
                   要顯示視窗的Context,
                   標題的文字,
                   視窗內文,
                   boolean值
                 );
      
      new Thread()
      { 
        public void run()
        { 
          try
          { 
            /* 在這裡寫上要背景執行的程式片段 */
            /* 為了明顯看見效果,以暫停3秒作為示範 */
            sleep(3000);
          }
          catch (Exception e)
          {
            e.printStackTrace();
          }
          finally
          {
            myDialog.dismiss();    // 卸載所建立的myDialog物件
          }
        }
      }.start(); //開始執行執行緒
ok,很清楚的知道,書裡在ProgressDialog的實作下,跟了一個Thread,好讓程式能夠在3秒以內完成並結束。

  但是,Thread這一段就算不寫也沒關係,反正只要用任何方法,讓
myDialog.dismiss();
能夠被執行到,視窗自然就會消失,畫面返回主程式了。

  小鰻真正在實作時,除了摸索Thread倒底要不要寫這個問題以外,還搞了一個小烏龍。
  ProgressDialog本身是能夠接受New出實體的,於是,我在
myDialog = ProgressDialog.show
                 (
                   要顯示視窗的Context,
                   標題的文字,
                   視窗內文,
                   boolean值
                 );
的上面,又加上一段
myDialog = new ProgressDialog(this);
也難怪我在執行myDialog.dismiss()時,怎麼樣也關不掉視窗!

Monday, August 16, 2010

我的隨手新聞RSS解析

話說︰
  小鰻最近在忙一個專案,其中有一段剛好跟RSS有關,研究了3、4天的SDK範例大全和另一本開發實務的書,在這裡稍微把概念記錄下來。
  android有提供幾種方式去抓取RSS資料來源,最為人知的就是使用SAXParser分析器了。
  RSS說簡單了,也只不過是一個xml檔(也有可能是其他的副檔名)。它有一定的規範與格式,所以在解析各大新聞臺的RSS時,也變得有跡可尋。

  以下是常看到的RSSxml檔案格式
  
<itme>
    <title>新聞的標題</title>
    <link>新聞的連結網址</link>
    <description>新聞內容簡述</description>
    <pubDate>發佈新聞的時間</pubDate>
</item>
  所以啦,所謂的RSS解析器,說白一點,就是在這些標籤裡,把字取出來啦!
  通常各大網站都會提供RSS新聞的連結,像yam新聞的RSS網址是這樣子的︰
http://c.yam.com/news/o5link/r.c?http://n.yam.com/RSS/Rss_life.xml
所以,到時候程式裡一定要有個地方能夠存這個網址。
------------------------------------------------------

RSS解析器裡會有4個工人分工合作著
(1)XMLReader - 閱讀工人
(2)MyAdapter(繼承自BaseAdapter) - 版面配置工人
(3)MyHandler(繼承自DefaultHandler) - 文字分配工人
(4)一個具物件導向特性的類別News - 模版工人

要能夠解析一份RSS,Android交給了4個工人幫忙
(1)XMLReader
第1個工人既然叫閱讀工人,我們就來看看這個工人是怎麼讀書的吧︰
path = "http://c.yam.com/news/o5link/r.c?http://n.yam.com/RSS/Rss_life.xml";
URL url = null;

try{
    url = new URL(path);//呼叫網址進來
    SAXParserFactory spf = SAXParserFactory.newInstance();//先蓋一個工廠
    SAXParser sp = spf.newSAXParser();//工廠有一個知識不太高的解析工人
    XMLReader xr = sp.getXMLReader();//也有一個閱讀工人
    MyHandler myHandler = new MyHandler();//用到了我們之後建立的分配工人
    xr.setContentHandler(myHandler);//將閱讀工人和分配工人做結合
    xr.parse(new InputSource(url.openStream()));//閱讀工人用parse去開啟一個InputStream放資料
    
    data = myHandler.getParsedData();//getParsedData()方法會在myHandler裡看到
}catch(Exception e){
    log.i("message","wrong!");
    }
原來光一個閱讀工人,就已經做了一些的前置動作了。

(2)MyAdapter
其實這個版面配置工人還真的是可有可無,要不是主編要求取出來的"新聞發佈時間"不能和"新聞標題"一樣大,還真的是不用請版面配置工人出來,用原本的android預設配置就好
這個配置工人,android希望我們繼承自BaseAdapter,而且,還規範了我們必須實作以下4個method
//建構子
public MyAdapter(Context context,List lt){
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount(){
    return 數量;
    }
@Override
public int getItem(int position){
    return position;
    }
@Override
public int getItemId(){
    return position;
    }
@Override
public View getView(int position,View convertView,ViewGroup par){
    ViewHolder holder;
    if(convertView == null){
    convertView = mInflater.inflate(R.layout.news_row, null);
    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(R.id.text);
    convertView.setTag(holder);
    }else{
    holder = (ViewHolder) convertView.getTag();
    }
    return convertView;
  }

class ViewHolder{//為自己訂的版面的xml做一個類別
    TextView text;
    }
}
最後面這段「為自己訂的版面的xml做一個類別」是什麼意思呢?
其實配置工人通常會帶一個小老婆出現︰
news_row.xml
他們其實是很親密的,正所謂孟不離焦啊!
一個負責外表(xml),另一個是對應的骨架(class ViewHolder)

(3)MyHandler
既然叫Handler,當然什麼事都要幫你搞定囉!
它也有幾個一定要我們覆寫的method
public class MyHandler extends DefaultHandler{
    private List<News> li;

    public List getParsedData(){//這個是我們自己寫的,沒有一定要覆寫
    return li;
    }
    
    @Override
    pubilc void starDocument() throws SAXExcption{
    li = new ArrayList<News>();//在程式解析之初,先建立一個ArrayList容器
    }

    @Override
    pubilc void endDocument() throws SAXExcption{
    }

    @Override
    pubilc void starElement(String namespaceURI, String localName, String qName, Attributes atts) thtows SAXException{
    news = new News();//在程式解析之初,先產生實體
    }

    @Override
    pubilc void endElement(String namespaceURI, String localName, String qName, Attributes atts) thtows SAXException{
    //更多程式碼
    }

    @Override  //取標籤內的字的方式
    pubilc void characters(char ch[], int start, int length){
    //更多程式碼    
    }
}
這段的程式跑法是︰
starElement()→characters()→endElement()→starElement()→characters()→endElement().....
將一個一個的標籤辨識出來並跑完



(4)News類別
既然叫模版工人,就是說從解析器解出來的字串,要有一個一個的對應去接收資料,好讓容器能歸納整理咩

所以,模版的程式碼超基本
public class News{
    private String title="";  //新聞的標題存在這裡
    private String link="";  //新聞的連結網址存在這裡
    private String desc="";  //新聞的大綱描述存在這裡
    private String date="";  //新聞的發佈時間存在這裡
//以下是一堆的getter和setter
//像︰
    public String getTitle(){
    return title;
    }
    public String setTitle(String title){
    this.title = title;
    }
    //更多程式碼    
}

最後最後,有一個超關鍵,如果你忽略了,可能都不知道為什麼會無法解析或上網咧!

請你在AndroidManifest.xml這個apk基本配面版中的<application>區塊外,做以下的新增
<uses-permission android:name="android.permission.INTERNET" />
因為android預設的apk連網功能是關閉的,必須透過上述的設定將上網權限打開。

好啦!大功告成。
程式不多不少,但是就是因為大家的配合,才產生出了好用的RSS隨手新聞。

下臺一鞠躬(笑)。

Thursday, August 12, 2010

intent和ActivityResult

一開始不懂為什麼Activity會有一個onActivityResult(),為什麼在A畫有等待接收B畫面的回傳值的功能,不是直接從Bintent過來就好了嗎?
產生這個問題後,馬上去問k前輩
他說
 一般來說,我們用intent是為了讓畫面能從A跳到B,但是如果我們又從Bintent到A,在Android中,會產生出2個A畫面,而且intent回去的A,是A2
但是,如果在B畫面setResult傳回A的onActivityResult(),此時雖然也是回A畫面,但是回的是最先開始的A1畫面,這樣解釋能理解嗎?

自訂Adapter的inflater方法

想要替Gallery或ListView去自制樣板時,通常會用到inflater指令。

然而這個Adapter會實作以下四個method︰

public class myAdapter extends baseAdapter
1.public int getCount() //決定了要跑出幾條清單
2.public Object getItem(int position)
3.public long getItemId(int position
4.public View getView(int position, View convertView, ViewGroup parent)//顯示的前置作業

Layout的顯現前置作業,通常都是在getView()裡去交待的
經實驗後,發現邏輯是
(1)進來跑一次的getView()→輸出position=0→out程式區塊
(2)重覆步驟1,但這次是跑position=1
(3)依此類推
★以上3個步驟,實驗後發現居然run了3遍這3個步驟


如︰
(1)Gallery經過setAdapter後的自製Adapter,會一次建立一個ImageView的實體,並取得資源,一經滑動到那個位置(Position),馬上重新執行一次getView(),去重新取得新的資源
(2)在ListView的setAdapter後的自製Adapter,也是一次一個getView()的方式去完成一格的list清單,重覆呼叫,直到整個ListView都將資料呈現出來為止

Wednesday, August 11, 2010

在Google Blogger使用程式碼標註「SyntaxHighlighter」


一、前言

資訊業版的部落格常常需要貼上程式語法,
但文字和程式碼黏成一塊,
對觀看的讀者來說實在是很吃力的一件事。

因此筆者在這邊推薦一套程式語法的「高亮」標註工具︰
SyntaxHighlighter。

一起來看看它的魅力吧!

二、文章開始


將SyntaxHighlighter語法貼進Blogger中

將下列程式碼複製到你的Blogger中的在[範本]→[網頁即時狀態]→[編輯HTML]→"<head>"標籤底下

    
    
    
    
註︰因為Blogger的一些BUG,在貼上上述的code並儲存時可能會遇到您的 HTML 不被接受: 缺少結尾的標記: SCRIPT 之類的警語,請修改成對應的語法。

攢寫SyntaxHighlighter語法

如何寫漂亮的程式框架和程式呢?
將下面這段寫在你的html頁面中
如果你的程式標註使用的是JAVA︰
程式碼寫在這裡...
 

如果你的程式標註使用的是C++︰
程式碼寫在這裡...
 

如果你的程式標註使用的是javascript︰
程式碼寫在這裡...
 

如果你的程式標註使用的是objective-c︰
程式碼寫在這裡...
 

如果你的程式標註使用的是shell︰
 
程式碼寫在這裡...

如果你的程式標註使用的是html︰
 
程式碼寫在這裡...

如果你的程式標註使用的是純文字︰
 
程式碼寫在這裡...

如果還想知道更多語法的用法,
可以參考SyntaxHighlighter官網

更換SyntaxHighlighter背景主題

可以參考官網教學
將上面

改成其它的.css主題檔。


其它有趣的用法


1.不要看到行數
 
程式碼寫在這裡...
執行結果如下
程式碼寫在這裡...

2.不要看到右邊的問號
 
程式碼寫在這裡...
執行結果如下
程式碼寫在這裡...

3.替特定行數畫下重點
 
程式碼第1行
程式碼第2行
程式碼第3行
執行結果如下
程式碼第1行
程式碼第2行
程式碼第3行

4.特殊符號表 

參考網址