2010年11月15日 星期一

[Android] 如何使用VideoView播放影片



在之前的文章[Android Tips] 如何在Layout檔案中使用自訂的View , 成功的使用了自訂的VideoView了 , 現在該讓他播放個影片來看看 , 根據Android的文件 , 能播放的影音檔案為3gp和mp4 , 程式碼如下



import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.MediaController;

public class CustomVideoViewTest extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        CVView = (CustomVideoView)findViewById(R.id.VideoView);
        MediaController controller = new MediaController(this); 
        CVView.setMediaController(controller); 
        //CVView.setVideoPath("android.resource://com.android/"+R.raw.video);
        //播放Local端的影音資源 , SD Card or res/raw 裡的影音檔
        CVView.setVideoURI(Uri.parse("http://www.dubblogs.cc:8751/Android/Test/Media/mp4/test.mp4"));
        //播放遠端的影音資源 , 影音串流
        CVView.requestFocus();
        CVView.start();
    }    
    CustomVideoView CVView;
}

另外應用程式要連接網路需要加上
android:name="android.permission.INTERNET : Allows applications to open network sockets

    


執行結果如下






另外關於VideoView大小的問題





  

可以看到VideoView的寬和高屬性都已經設為"fill_parent"了 , 但事實上執行的結果並不會填滿整個parent layout , 如果想更改大小的話目前比較簡單的方法是寬設為"xxdip"來解決 , 不過只有更改寬的dip才會起作用 , 高的部分怎麼改都一樣 , 應該是有更好的方法來修改VideoView的寬和高。在網路上看到一篇文章有解決這個問題 , 照他的方法做程式碼如下


import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.VideoView;

public class CustomVideoView extends VideoView
{

 public CustomVideoView(Context context)
 {
  super(context);
  // TODO Auto-generated constructor stub
  Log.d("Go to", "Context context");
 }

 public CustomVideoView(Context context, AttributeSet attrs)
 {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  mVideoWidth = 0;
     mVideoHeight = 0;
  Log.d("Go to", "Context context, AttributeSet attrs");
 } 
 //可以發現進入的是CustomVideoView(Context context, AttributeSet attrs)這個建構子
    //所以留著覆寫他 , 否則程式會強制關閉
 
 public void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
 {
  int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
        setMeasuredDimension(width,height);
 }
 
 private int mVideoWidth;
    private int mVideoHeight;
}


接著使用之前文章的 [Android Tips] 如何隱藏Title Bar和Notification Bar , 執行成功了結果如下












2010年11月14日 星期日

[NBA] Stephen Curry



玩了2K11快一個月了發現有個球員很好用 , 速度快又準防守又好 , 就是他 Stephen Curry , 上一季就有聽過他的大名了 , 去年三分球大賽有備邀請參賽 , 年度新秀票選第二名 , 2009球季新秀第一隊From Davidson 大學 , 第一輪第七順位被勇士選走。 


之前只是覺得他投籃的姿勢很優美 , 然後覺得他的體型在NBA來說真的很像國中生....雖然長得也很像 , 名符其實的哇哇臉 , 玩了2K11之後越來越喜歡他了 , 查了一下才發現他是Dell Curry的兒子 , Dell Curry 也是一個射手 , 記得國中玩NBA LIVE 他還在暴龍隊 , 兒子也遺傳到老爸 , 是個能切能投的後衛 , 而且Stephen Curry還有一個弟弟 Seth Curry剛念大學也打校隊。

Stephen Curry在大學的球風比較像SG , 所以勇士隊選到他的時候 , 很多人懷疑他的位置會不會和隊上的Monta Ellis 重疊 , 後來老尼決定讓他們一起上場 , 不過剛進NBA的前一個月 Curry有一段低潮 , 是之後越打越好才有機會角逐新人王的 , 今年新的球季剛開始就受傷了 , 現在復出希望他有好的表現^^

現在來看看他去年球季的MIX






另外這個漂亮的假動作腳步




小時候的Stephen Curry和老爸Dell Curry在球場上





Stephen Curry - The Future (Video Mix)


[Android] 如何在Layout檔案中使用自訂的View



如果現在在Layout檔案裡面拉了一個View的物件 , 但是想對這個View進行修改的動作自訂成我們想要的樣式和功能 , 假設現在在main.xml檔案裡面拉了一個VideoView





  




如果我們想要修改這個ViedoView的樣貌和功能的話 , 那必定要寫一個class extends VideoView
程式碼如下:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.VideoView;

public class CustomVideoView extends VideoView
{

 public CustomVideoView(Context context)
 {
  super(context);
  // TODO Auto-generated constructor stub
  Log.d("Go to", "Context context");
 }

 public CustomVideoView(Context context, AttributeSet attrs)
 {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  Log.d("Go to", "Context context, AttributeSet attrs");
 } 
 //可以發現進入的是CustomVideoView(Context context, AttributeSet attrs)這個建構子
    //所以留著覆寫他 , 否則程式會強制關閉
}


接著我們要修改main.xml裡原本VideoView的定義名稱







那在Activity中該如何取用呢?


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

public class CustomVideoViewTest extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        CVView=(CustomVideoView)findViewById(R.id.VideoView);
    }
    
    CustomVideoView CVView;
}



大功告成!!!!

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



這篇的內容是修改自前面的 [Android Tips] 如何自訂ListView的內容 (使用ArrayAdapter同時加入Image和Text)這篇主旨是要使用SimpleAdapter來實現 , 此外可以動態的新增和刪除資料 , 首先Layout檔案的內容沒有更改和之前的文章一樣 , 至於程式碼的部分如下




package com.android;

import java.util.ArrayList;
import java.util.HashMap;
import android.app.TabActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;


public class TabWidgetListViewTest extends TabActivity implements Button.OnClickListener
{
    /** 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所要呈現的內容            
        
        ListTextImageItemEast = new ArrayList[HashMap[String, Object]();  
        //宣告ArrayList裡面的元素為HashMap
        
        for(int i = 0;i < 5;i++)  
        {  
          HashMap[String, Object] map = new HashMap[String, Object](); 
          // key使用String變數 , element存放Object元素
          map.put("ImageItem", icons[i]); 
          map.put("PlayerItem",EPlayer[i]); 
          map.put("PostionItem", Postion[i]);  
          ListTextImageItemEast.add(map); // 加入到ArrayList中 
        }
        
        ListEPlayer = (ListView) findViewById(R.id.ListViewEast);
        SAE = new SimpleAdapter(this,   
          ListTextImageItemEast, //使用的ArrayList
                R.layout.listviewrow, //相對應的Layout檔案
                new String[] {"ImageItem","PlayerItem","PostionItem"},   
                new int[] {R.id.icon,R.id.name,R.id.position});  
                // 每個HashMap中的Title對應到RowView裡的subView Id
        ListEPlayer.setAdapter(SAE);  
        ListEPlayer.setOnItemClickListener(OICL);
        //然後再判斷Item點擊事件
        
        ListEPlayer.setTextFilterEnabled(true);
        //添加按鍵過濾的功能
         
        
        ListWPlayer = (ListView) findViewById(R.id.ListViewWest);
        ListTextImageItemWest = new ArrayList[HashMap[String, Object]]();  
        
        for(int i = 0;i < 5;i++)  
        {  
          HashMap[String, Object] map = new HashMap[String, Object]();  
          map.put("ImageItem", icons[i]);
          map.put("PlayerItem",WPlayer[i]);  
          map.put("PostionItem", Postion[i]);  
          ListTextImageItemWest.add(map);  
        }
        
        ListWPlayer = (ListView) findViewById(R.id.ListViewWest);
        SAW = new SimpleAdapter(this,   
          ListTextImageItemWest,
                R.layout.listviewrow,
                new String[] {"ImageItem","PlayerItem", "PostionItem"},   
               
                new int[] {R.id.icon,R.id.name,R.id.position});  
 
        ListWPlayer.setAdapter(SAW);  
        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的資料
        
        Button buttongernerate = (Button) findViewById(R.id.buttongernerate);
        Button buttondelete = (Button) findViewById(R.id.buttondelete);
        buttongernerate.setOnClickListener(this);
        buttondelete.setOnClickListener(this);
        //對新增和刪除按鈕設置點擊事件
    }
    
    TabHost mTabHost;
    ListView ListEPlayer , ListWPlayer , TempLV;
    SimpleAdapter SAE , SAW , TempA;
    String[] EPlayer , WPlayer , Postion;
    int[] icons;
    ArrayList[HashMap[String, Object]] ListTextImageItemEast;
    ArrayList[HashMap[String, Object]] ListTextImageItemWest;
    
    HashMap TempHMap;    
    boolean Choose = false; //按鈕開關
    int TempPosition;
    
    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 = "你選擇了西區的";
   
   TempHMap = (HashMap [String, Object]) parent.getItemAtPosition(position);
   
   setTitle(where + ((TextView)view.findViewById(R.id.position)).getText() 
            + ":" + TempHMap.get("PlayerItem"));
   //這邊提供兩種方法來取得被點選RowView的內容
   
   /*
    * 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)
    * */
   TempLV = (ListView) parent;
   TempPosition = position;
   Choose = true;
  }  
    };

 @Override
 public void onClick(View ButtonView)
 {
  // TODO Auto-generated method stub
  
  if(Choose)
  {
   switch(ButtonView.getId())
   {
       case R.id.buttongernerate: //新增所選擇的資料           
     if(TempLV.equals(ListEPlayer))
     {
      ListTextImageItemEast.add(TempHMap);;
      TempA = SAE;
     }
     else
     {
      ListTextImageItemWest.add(TempHMap);;
      TempA = SAW;
     }
     TempA.notifyDataSetChanged();
      //提醒SimpleAdapter作資料得更新
    break;
    
       case R.id.buttondelete: //刪除所選擇的資料
        if(TempLV.equals(ListEPlayer))
     {
         ListTextImageItemEast.remove(TempPosition);
      TempA = SAE;
     }
     else
     {
      ListTextImageItemWest.remove(TempPosition);
      TempA = SAW;
     }
        TempA.notifyDataSetChanged();
       break;
   }
  }
  Choose = false;
  //Log.d("Choose" , Choose+"");
 }
}

當你點選了ListView中的Item之後 , 新增或是刪除的按鈕才會發揮作用


此外為了避免 HTML Tag is broken的錯誤 , 所以使用[] 代替<> , 程式要能work需要作符號的修改



相關文章:

[Android Tips] 如何在TabWidget中加入ListView


2010年11月8日 星期一

[Android] 如何隱藏Title Bar和Notification Bar



有時候想呈現繪圖背景或是想播放Video影像時 , 會想在狹小的螢幕多爭取一點空間
這時候乾脆就把Title Bar和Notification Bar隱藏獲取更多螢幕空間吧!!!! 步驟很簡單


先看下面的圖片 , 這時候Title Bar和Notification Bar都還在



接下來為了要隱藏Title Bar這邊有幾個方法 , 首先可以在AndroidMenifest.xml , 在對Activity 作屬性定義的時候可以加上 android:theme 來設置 Activity 的主題 


    
        
                  
                                    
            
                
                
            
        
    
 

仔細看可以發現 AndroidMenifest.xml多了兩行註解
<!-- android:theme="@style/myThemeOne" -->
<!-- android:theme="@style/myThemeTwo" -->
這是我們自定義的style , 使用他們來替換都可以得到一樣的效果 , 而style Resource是要放置在res/values下的 , 可以參考這邊 , 在這邊我把
@style/myThemeOne放在原本的string.xml檔案裡

android:theme="@style/myThemeTwo放在style.xml裡 , 但是都必須放在res/values下


    Hello World, Test
    ThereIsTitleBar    
     




 



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





如果說還想把Notification Bar隱藏的話 , 只要加上這段程式碼

public class NoTitleBar extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //這行程式碼也可以隱藏Title Bar但是位置要放對
        setContentView(R.layout.main);        
        //Remove notification bar
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
     //this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
     }
}


成功之後如下



連Notification Bar都消失了

其實想達到同樣的效果還可以這樣 , 在AndroidMenifest.xml Activity Theme這個定義
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"

另外下面這篇文章對於 Android提供的Theme資料整理的很詳細 , 很棒


Google Analytics