2010年10月30日 星期六

[Android] 如何自訂ListView的內容 (使用ArrayAdapter同時加入Image和Text)



這邊的程式碼延續上一篇文章的結果 , 如果說我們現在想要在ListView中每一個row
所呈現的資料內容更豐富些 , 不單單只有文字還想加入圖片 , 並且選取ListView裡的
資料時能觸發Click事件 , 如下圖TitleBar會顯示我們所選擇的球員






首先我們要自訂ListView中row的資料呈現內容 , 上圖是在左邊擺了一個ImageView然後右上方擺一個TextView , 下方也擺一個TextSize較小的TextView , 為了達成這樣的效果 , 我們必須把想呈現的佈局方式寫在一個Layout xml檔案裡 , 如下


    
    
                              
        
                
    


將row裡該呈現的佈局都搞定之後 , 接下來就是程式碼的部分


import android.app.TabActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;


public class TabWidgetListViewTest extends TabActivity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        EPlayer = getResources().getStringArray(R.array.EPlayer);
        WPlayer = getResources().getStringArray(R.array.WPlayer);
        Postion = getResources().getStringArray(R.array.Position);
        // 分別將東西區先發球員和球員位置的資料當作ListView 的內容        
        // res/values/strings.xml 已經宣告了string-array
        
        icons = new int[]{R.drawable.marketplace , R.drawable.email , R.drawable.contacts , R.drawable.mms , R.drawable.application};
        
        
        // 首先我們先處理ListView所要呈現的內容
              
        
        ListEPlayer = (ListView) findViewById(R.id.ListViewEast);
        ListEPlayer.setAdapter(new IconTextAdapter(this , android.R.layout.simple_list_item_1 , EPlayer , Postion , icons));
        ListEPlayer.setOnItemClickListener(OICL);
        
        // 這邊的例子選用原本的範本 android.R.layout.simple_list_item_1 
        // 然後都丟入我們自己的接收器IconTextAdapter中 , 參數多了一個String[] Position
        // 然後再判斷Item點擊事件
        
        
        ListEPlayer.setTextFilterEnabled(true);
        //添加按鍵過濾的功能
         
        
        ListWPlayer = (ListView) findViewById(R.id.ListViewWest);
        ListWPlayer.setAdapter(new IconTextAdapter(this , android.R.layout.simple_list_item_1 , WPlayer , Postion , icons));
        ListWPlayer.setOnItemClickListener(OICL);
        ListWPlayer.setTextFilterEnabled(true);
        //對另一個ListView做同樣的操作載入西區先發球員的資料
        
        mTabHost = getTabHost();
        //我們的TabWidgetListViewTest 是繼承 TabActivity的
 //所以這邊是透過他的method getTabHost()
 //來取得我們在main.xml中宣告的TabHost
 
        
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1")
          //將Tab加入我們要的資料
          .setIndicator("東區先發球員" , this.getResources().getDrawable(R.drawable.aemail))
          //在Tab上標示名稱和加上Icon
          .setContent(R.id.ListViewEast));
                //Tab內容為main.xml檔案中宣告的ListView , 而ListView的內容我們先前已經處理好了
        
        mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("西區先發球員" , this.getResources().getDrawable(R.drawable.browser)).setContent(R.id.ListViewWest));
         
        mTabHost.setCurrentTab(0);
        //預設該顯示哪個Tab的資料
    }
    
    TabHost mTabHost;
    ListView ListEPlayer , ListWPlayer;
    String[] EPlayer , WPlayer , Postion;
    int[] icons;
    
    public class IconTextAdapter extends ArrayAdapter
    {
        int[] icons;
        String[] textname , textpostion;
        
  public IconTextAdapter(Context context, int textViewResourceId, String[] itemname, String[] itempostion , int[] images)
  {
   super(context, textViewResourceId, itemname);
   icons = images;
   textname = itemname;
   textpostion = itempostion;
  }
  
  public View getView(int position, View convertView, ViewGroup parent)
   {
            View rowview = convertView;
            if (rowview == null) {
                    LayoutInflater inflater = getLayoutInflater();
                    rowview = inflater.inflate(R.layout.listviewrow, parent, false);
                    //為了要把xml所描述的Layout轉變為View , 也就是我們要的rowview
                    //所以必須使用LayoutInflater來轉化 , 而要取得LayoutInflater的Instance方式還包括
                    //LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    //接著再使用inflate (int resource, ViewGroup root, boolean attachToRoot)
                    //傳回我們要的rowview
            }
            TextView Nmae = (TextView) rowview.findViewById(R.id.name);
            Nmae.setText(textname[position]);
                         
            TextView Postion = (TextView) rowview.findViewById(R.id.position);
            Postion.setText(textpostion[position]);
            
            ImageView icon = (ImageView) rowview.findViewById(R.id.icon);
            icon.setImageResource(icons[position]);
            
            // 我們在listviewrow.xml裡已經把ListView中Row的佈局都排好了 
            // 而這裡的rowview可以想成是之前被我們在佈局中組合出來的
            // 現在我們要為rowview裡面的元件設定Text和Icon
            // 最後再回傳rowview作為ListView中每一個row的顯示內容
            
            
            return rowview;
        }
     }

    public OnItemClickListener OICL =  new OnItemClickListener()
    {
  @Override
  public void onItemClick(AdapterView parent, View view, int position, long id)
  {
   String where;
   if(parent.equals(ListEPlayer))
   where = "你選擇了東區的";   
   else
   where = "你選擇了西區的";
   setTitle(where + ((TextView)view.findViewById(R.id.position)).getText() 
            + ":" + parent.getItemAtPosition(position));
   
   // getItemAtPosition(position)在官網的敘述是這樣的
   // Gets the data associated with the specified position in the list.
   // 上面所說的the data就是當初我們 super(context, textViewResourceId, itemname);
   // 所回傳的itemname了 , 可以參考父類別ArrayAdapter的建構子
   // ArrayAdapter(Context context, int textViewResourceId, T[] objects)
   
  }  
    };     
}






相關文章:

[Android] 如何在TabWidget中加入ListView

[Android] 如何在TabWidget中加入ListView



對於設計Android的使用者介面來說 , TabWidget 和 ListView 都是使用頻率很
的View , 在Android 模擬器中也會常常看的到 , 而現在就是想把這兩個View結合
一起呈現 , 如下圖一樣。





分別有東西區先發球員的兩個Tab , 然後內容使用ListView來呈現球員名單
此外在底下再放置兩個Button , 日後可以用來新增刪除資料


首先直接來看 Layout 檔案
    
        
        
            
            
            
                       
                
                
        
        
        
    



這邊Layout佈局的原因可以搭配著官網的Hello , TabWidget 來看, 首先需要TabHost來裝載整個Activity所要呈現的物件 , 而TabHost有兩個必要的元件 , 分別是TabWidget  FrameLayout , 那麼把他放在一個直立方向(Vertical)的LinearLayout 而根據切換到不同的Tab , 我們想要呈現不一樣的內容 , 而這些不一樣的內容就擺在FrameLayout 裡面 , 因為FrameLayout 的佈局本來就有"層次"的概念 , 所以蠻好理解的接著要注意的就是 , TabWidget 的ID一定要是tabs 而 FrameLayout的ID名稱一定要為tabcontent 否則會出錯 , 然後放入兩個ListView , 此外在外面的LinearLayout 中, 再擺一個LinearLayout(水平方向) , 裡面放入兩個Button 就完成 Layout佈局了。


接著回到我們的程式碼中

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TabHost;


public class TabWidgetListViewTest extends TabActivity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        EPlayer = getResources().getStringArray(R.array.EPlayer);
        WPlayer = getResources().getStringArray(R.array.WPlayer);
        // 分別為東西區先發球元的資料要當作ListView 的內容        
        // res/values/strings.xml 已經宣告了string-array
               
        
        //首先我們先處理ListView所要呈現的內容
              
        
        ListEPlayer = (ListView) findViewById(R.id.ListViewEast);
        ListEPlayer.setAdapter(new ArrayAdapter(this , android.R.layout.simple_list_item_1 , EPlayer));
        
        // ListView中Item的內容是需要Adapter來連接的
        // 所以現在把要呈現在ListView中的Item (String[] EPlayer)
        // 和範本 android.R.layout.simple_list_item_1 都丟入接收器ArrayAdapter中
        // 除了ArrayAdapter之外還有許多其他的接受器像是SimpleAdapter等等
        
        
        ListEPlayer.setTextFilterEnabled(true);
        //添加按鍵過濾的功能
         
        
        ListWPlayer = (ListView) findViewById(R.id.ListViewWest);
        ListWPlayer.setAdapter(new ArrayAdapter(this , android.R.layout.simple_list_item_1 , WPlayer));
        ListWPlayer.setTextFilterEnabled(true);
        //對另一個ListView做同樣的操作載入西區先發球員的資料
        
        mTabHost = getTabHost();
        //我們的TabWidgetListViewTest 是繼承 TabActivity的
 //所以這邊是透過他的method getTabHost()
 //來取得我們在main.xml中宣告的TabHost
 
        
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1")
          //將Tab加入我們要的資料
          .setIndicator("東區先發球員" , this.getResources().getDrawable(R.drawable.aemail))
          //在Tab上標示名稱和加上Icon
          .setContent(R.id.ListViewEast));
                //Tab內容為main.xml檔案中宣告的ListView , 而ListView的內容我們先前已經處理好了
        
        mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("西區先發球員" , this.getResources().getDrawable(R.drawable.browser)).setContent(R.id.ListViewWest));
         
        mTabHost.setCurrentTab(0);
        //預設該顯示哪個Tab的資料
    }
    
    TabHost mTabHost;
    ListView ListEPlayer , ListWPlayer;
    String[] EPlayer , WPlayer;
}

如果對於註解中提到的按鍵過濾不清楚的話 , 可以參考盧老師的
如何在 ListView 上加上按鍵過濾的功能這篇文章


到這邊就完成了一開始圖片所呈現的佈局了 , 可是我們可以發現最下面一筆資料會被
Button擋住 , 造成我們需要移動捲軸 , 可不可以把每一列的TextView改小呢?
偶然看到盧老師的這篇文章:親愛的,我把 AutoCompleteTextView 縮小了
裡面提到把Android Native Layout:simple_list_item_1.xml 抓出來修改
就可以對TextView的格式作更改了 , 所以我們可以自己做一個TextView格式
的xml檔案 , 然後擺在res/layout中當範本 , 這個檔案可以在下面的目錄找到
Your_Android_SDK_Location\platforms\android-Version\data\res\layout


原始的 simple_list_item_1 內容如下



對內容稍作修改 , 順便修改檔名




接著把程式碼稍作修改

ListEPlayer.setAdapter(new ArrayAdapter(this , R.layout.simplelistitem1 , EPlayer));
ListWPlayer.setAdapter(new ArrayAdapter(this , R.layout.simplelistitem1 , WPlayer));

下圖是修改後的佈局結果




下一篇文章會提到在對ListView每一列作修改不要只單純顯示文字 , 另外再對選擇item作事件判斷




相關文章:

[Android] 如何自訂ListView的內容 (使用SimpleAdapter同時加入Image和Text)

[Android] 如何自訂ListView的內容 (使用ArrayAdapter同時加入Image和Text)

2010年10月27日 星期三

[Android] 如何在桌面建立捷徑圖示 (2.接受Intent.ACTION_CREATE_SHORTCUT動作)



在上一篇 [Android] 如何在桌面建立捷徑圖示 (1.Launcher 的 BroadcastReceiver)文章介紹透過Launcher的權限在桌面建立捷徑 , 但其實我們還可以在桌面的
空白處長按不放 , 系統即會詢問我們是否要在桌面加入物件 , 如下圖





在這邊可以選擇要加入的物件類別 , 如果說我們想要替我們的程式產生捷徑



使用系統內建的功能 , 這邊許多城市都可以產生出捷徑 , 而我們的程式會被系統放在
應用程式下點選之後桌面就會出現程式捷徑了 ,  可是這樣產生的捷徑固定動作就是前
往該應用程式 , 如果我們想透過長按的方式呼叫出清單並自訂我們捷徑的動作的話
該如何實作呢?


首先我們需要在 AndroidManifest.xml 添加屬性 , 這邊多加了一行 
<action android:name="android.intent.action.CREATE_SHORTCUT"/>










          

現在可以看到ShortcutTest 出現在清單上了 


接下來就是程式碼的部分


import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class ShortcutTest extends Activity 
{
    @Override
    
    public void onCreate(Bundle savedInstanceState)
    {        
     super.onCreate(savedInstanceState);

        // 如果intent的動作是被要求建立一個捷徑 , 那麼進入判斷式子建立捷徑 , 然後終止Activity

        if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction()))
        {
            setupShortcut();
            finish();
            return;
        }
     
     setContentView(R.layout.main);     
     TextView Info = (TextView) findViewById(R.id.TextView);        
        Info.setText("請回到桌面 , 在空白處長按 , 選取建立捷徑");
    
    }
    
    private void setupShortcut() 
 {
     Intent shortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
     //也可以使用 Intent.ACTION_MAIN
     
     shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Shortcut");
      shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,Intent.ShortcutIconResource.fromContext(this,R.drawable.icon));
        
     Intent intent = new Intent(); 
        intent.setClassName(this, this.getClass().getName());
        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
       
        setResult(RESULT_OK, shortcutIntent);
  /*
   * setResult (int resultCode, Intent data)
   * Call this to set the result that your activity will return to its caller.
           Parameters
           resultCode: The result code to propagate back to the originating activity, often    RESULT_CANCELED or RESULT_OK
           data:       The data to propagate back to the originating activity.
           See Also
           RESULT_CANCELED
           RESULT_OK
           RESULT_FIRST_USER
           setResult(int)
   * */
 }
    
}

當我們執行這個程式的時候會出現這樣的畫面



(*)由於我們的程式碼裡面有一個是否為 Intent.ACTION_CREATE_SHORTCUT 
動作的判斷式所以直接從應用程式中執行的話只會出現上面的提示
沒有任何產生捷徑的動作 , 所以必須從剛剛的清單選取
ShortcutTest此時系統會宣告一個android.intent.action.CREATE_SHORTCUT
的Intent並呼叫 
startActivityForResult(Intent intent, int requestCode) 

來等候ShortcutTest 的回應這

個時候
ShortcutTest 接獲Intent.ACTION_CREATE_SHORTCUT

的Intent


就會呼叫判斷式中的setupShortcut() , 最後再以SetResult(int)回傳資訊給系統

告知要建立捷徑




之後桌面就會成功的出現我們要的捷徑了




打星號的部份雖然可以成功執行 , 但是細節部分是我的推測 , 有興趣的人可以再試試
在清單中要加入捷徑時 , 在應用程式底下的apps , 會直接的產生捷徑 , 而和應用程
式同
一層Level的物件, 該Level 中
共同點都是會先執行該程式
 , 但並不是每個都可以
成功產生捷徑
ex. 書籤,直接傳訊,直接撥號 
Google 定位倒是可以。

所以
ShortcutTest
出現在該Level 也就會
被執行一次 , 所以接到 
Intent.ACTION_CREATE_SHORTCUT後 , 再完成捷徑的回傳程式就自finish() , 好讓
畫面跳回桌面 , 這邊都是自己的實驗和推測 , 有錯誤的話歡迎討論。



[NBA] NBA 2k11



隨著今天NBA 2010-11 Season 開打 , 今天緯來體育台早上7:30直播熱火vs塞爾提克
10:30 火箭vs湖人 , 真是熱血沸騰阿!!!! 今天要分享的是 2K11這款年度籃球遊戲大作
為了這款遊戲買了SONY PS2 的手把來玩 , 這遊戲實在做得太逼真了 , 除了球員臉
孔之外....另外今年的封面人物是喬神!!!! 看他打球是我國小的事情了....











































NBA 2K11 將會有一個新模式 , 該模式允許玩家親身體會喬丹職業生涯的傳奇時刻
「挑戰喬丹」模式將會專注來自傳奇的芝加哥公牛隊的10場比賽 , 每場比賽會要求玩家
完成數據任務 , 就像飛人籃球一樣 ,  全部挑戰成功之後 , 玩家就可以把新秀時期的Jordan選入自己喜歡的隊伍!!! 下面是Jordan Chanllenge 的影片~~







另外補上開頭影片 , 真逼真呀



本來想說貼圖片的 , 但是有影片何必看圖片呢~




這款遊戲真的要配上手把 , 鍵盤沒辦法表達出那麼複雜的動作 , 我幾個朋友都說要
為了他去買手把 , 官方網站還出了控制的教學影片 , 看了真的歎為觀止 , 運球動作
可以做到那麼細緻!!!!




另外My Player的模式也相當的好玩 , 看到PTT裡得大大們都在討論就知道他的魅力了
有趣的是當大家的自創球員打完比賽的時候 , 會招開記者會回答許多記者的問題 , 而
根據你回答的選項 , 會對你的數值有所影響 , 而對岸遊俠網的高手真的太厲害了
將記者會的問題都作了中文翻譯....高手高手高高手 , 以下是影片






以上是簡單的介紹 , 想要獲得更多的資訊可以到 巴哈姆特 - NBA 2K series
或是PTT - NBAGAME

2010年10月26日 星期二

[Music] Olivia ong 王儷婷 - 我願意



Olivia ong - 王儷婷 , 幾個月前朋友傳了她的 You and Me 給我 , 當時覺得她的
聲音很舒服 , 而且長得又漂亮~ 這幾天在Youtube上聽到她翻唱王菲的我願意
天那~~~真的好好聽 , 是輕快板的我願意 , 然後就一直Replay整天.....








思念是一種很玄的東西 如影隨行
無聲又無息出沒在心底
轉眼 吞沒我在寂寞裡

我無力抗拒 特別是夜裡
想你到無法呼吸
恨不能立即 朝你狂奔去
大聲的告訴你

願意為你 我願意為你
我願意為你 忘記我姓名
就算多一秒 停留在你懷裡
失去世界也不可惜

我願意為你 我願意為你
我願意為你 被放逐天際
只要你真心 拿愛與我回應
甚麼都願意 甚麼都願意 為你

我甚麼都願意 甚麼都願意 為你


再追加Bossa Nova 版本



我一開始以為她是大陸人是因為她的中文腔調....
















相關文章

更多Olivia 的圖片
[Music] Olivia ong 王儷婷 - 夢一場

[Android] 如何在桌面建立捷徑圖示 (1.Launcher 的 BroadcastReceiver)



這幾天在找關於建立捷徑的資料 , 從中歸類出兩種方法 , 首先是第一種透過Launcher
的BroadcastReceiver 的方法建立快捷 , Launcher 為了讓其他應用程式能建立自己的捷
所以就註冊了一個BroadcastReceiver 專門接收其他應用程式發出的建立捷徑訊息
下面是Launcher的AndroidManifest.xml文件中Install-ShortcutReceiver的註冊訊息


 

 
 


接下來我們就要宣告並發送一個用來告知Launcher要建立桌面捷徑的Intent , 不過首先我
從Launcher那取得權限 , 權限名稱宣告如下:

private static final String INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";



接著我們需要宣告一個Intent , 用他來告知Launcher建立桌面捷徑 , 而對於這一個用來
Creates a shortcut 的Intent來說 , 他必須包含三個資訊 , 下面是Android Reference


Activity Action: Creates a shortcut.
Input: Nothing.
Output: An Intent representing the shortcut. The intent must contain three extras: 
SHORTCUT_INTENT (value: Intent), 
SHORTCUT_NAME (value: String),
SHORTCUT_ICON (value: Bitmap) or SHORTCUT_ICON_RESOURCE (value: ShortcutIconResource).


程式碼實作如下:

public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Intent shortcutIntent = new Intent(INSTALL_SHORTCUT);
        
        // 如果宣告的Intent是用來建立桌面捷徑的話
        // 必須在Intent中加入名稱 , 圖示 , 要執行的動作
        // 所以此時 shortcutIntent.putExtra 分別載入
        // 上面所需要的三個資訊          
       
     
     shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME,getString(R.string.app_name));
        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,Intent.ShortcutIconResource.fromContext(this,R.drawable.logo));
        //可以用 SHORTCUT_ICON (value: Bitmap)代替
        
        shortcutIntent.putExtra("duplicate", false);
        // 如果桌面上已經存在了之前建立的捷徑
        // 那麼參數false代表不能再建立相同的捷徑
        // 預設為true , 代表允許重複建立捷徑
        // 網路上有人使用 putExtra(EXTRA_SHORTCUT_DUPLICATE, false);
        // 我是使用Android 2.2的版本 , EXTRA_SHORTCUT_DUPLICATE 似乎已經被移除了
        // 所以使用 "duplicate" 代替
        
        
        Intent TaskIntent = new Intent();
        // 這邊宣告的Intent代表要執行動作
        
        TaskIntent.setComponent(new ComponentName(this.getPackageName(),".ShortcutTest"));        
        // 執行主程式
        
        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,TaskIntent);
        sendBroadcast(shortcutIntent);
        // 通知Launcher
    }


另外也別忘了在AndroidManifest.xml要加上uses-permission的標籤




成功之後就會出現以下的結果




                                當成功產生捷徑的時候 , 會有一個Toast訊息





接著可以看到桌面多出了一個Shortcut的捷徑!!!!


點擊捷徑就可以執行我們的主程式了 , 另外如果想把捷徑當作快速撥號的話 , 只要稍作修改如下
Intent TaskIntent = new Intent(Intent.ACTION_CALL,Uri.parse("tel://119"));
//撥號動作 , 打119


相關文章:
[Android] 如何在桌面建立捷徑圖示 (2.接受Intent.ACTION_CREATE_SHORTCUT動作)

Google Analytics