




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第9單元綜合實(shí)戰(zhàn)Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)9.1視頻播放器【知識(shí)描述】對(duì)于一個(gè)視頻播放器來(lái)說(shuō)一般會(huì)具有拖動(dòng)條,用戶拖動(dòng)拖動(dòng)條滑塊可以實(shí)現(xiàn)視頻的快進(jìn)和快退,在播放的過(guò)程中,拖動(dòng)條應(yīng)該不斷地更新播放的時(shí)間和顯示視頻總時(shí)長(zhǎng),同時(shí)視頻播放器還需要提供暫停/繼續(xù)播放功能。9.1.1界面布局界面主體部分首先需要添加一個(gè)SurfaceView用于顯示播放的內(nèi)容,然后需要顯示拖動(dòng)條和播控按鈕。<RelativeLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"><SurfaceViewandroid:id="@+id/svew"android:layout_width="match_parent"android:layout_height="match_parent"/><LinearLayoutandroid:id="@+id/llview"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignBottom="@id/svew"android:background="#777777"android:orientation="vertical"android:paddingBottom="15dp"android:alpha="0.8">9.1.1界面布局<SeekBarandroid:id="@+id/seek_bar"android:layout_width="match_parent"android:layout_height="wrap_content"android:indeterminate="false"/><LinearLayoutandroid:id="@+id/llview_progress"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:layout_marginLeft="5dp"android:gravity="left"android:orientation="horizontal"><ImageViewandroid:id="@+id/img_play_pause"android:layout_width="30dp"android:layout_height="30dp"android:clickable="true"android:src="@drawable/pause"/><TextViewandroid:id="@+id/txt_cur_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="00:00:00"android:textColor="#FFFFFF"android:textSize="18sp"/><TextViewandroid:id="@+id/txt_total_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="00:00:00"android:textColor="#FFDDBB"android:textSize="18sp"/></LinearLayout></LinearLayout></RelativeLayout>9.1.1界面布局在布局文件中,外層的視圖容器使用的布局方式為相對(duì)布局方式,其中添加了一個(gè)SurfaceView視圖,layout_width和layout_height的值都為match_parent,這樣可以使播放內(nèi)容占滿整個(gè)畫(huà)面。其后定義了一個(gè)縱向線性布局,用于顯示拖動(dòng)條和播控按鈕等內(nèi)容,通過(guò)設(shè)置android:layout_alignBottom="@id/svew"使得該布局與SurfaceView的底部對(duì)齊,設(shè)置android:alpha屬性讓布局具有一定的透明度。在該布局中,首先定義了一個(gè)SeekBar用于顯示播放的進(jìn)度和拖動(dòng)條,然后定義了一個(gè)橫向線性布局用于顯示播控按鈕和播放時(shí)間。9.1.1界面布局通過(guò)設(shè)置android:clickable="true"使得該圖片可以被單擊,用于實(shí)現(xiàn)暫停/繼續(xù)播放功能。界面具體效果如圖9.1所示。圖9.1界面具體效果9.1.2初始化在瀏覽文件的過(guò)程中,如果瀏覽到的是文件夾,則進(jìn)入下級(jí)目錄;如果瀏覽到的是視頻文件,則調(diào)用本單元設(shè)計(jì)的視頻播放器,并將視頻的路徑作為參數(shù)傳入,如果瀏覽到的是其他文件則返回。privatevoidchange(Filefile){StringfileName=file.getName();if(fileName.endsWith(".avi")||fileName.endsWith(".mp4")||fileName.endsWith(".mkv")){//調(diào)用本單元設(shè)計(jì)的視頻播放器
Intentintent=newIntent(MainActivity.this,VideoPlayerActivity.class);intent.putExtra("videoUrl",file.getAbsolutePath());startActivity(intent);}if(!file.isDirectory()){return;}mTitle.setText(file.getAbsolutePath());List<File>files=fileMgr.getSubFiles(file);mAdpter.updateFiles(files);mAdpter.notifyDataSetChanged();}9.1.2初始化視頻播放Activity啟動(dòng)時(shí),首先在onCreate()方法中設(shè)置一些Window參數(shù)使得播放界面全屏顯示,然后從Intent中獲取視頻的URL,并做一些組件和播放器的初始化工作,代碼具體如下:@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);this.requestWindowFeature(Window.FEATURE_NO_TITLE);this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.activity_video);//獲取視頻的路徑
Intentintent=getIntent();mVideoUrl=intent.getStringExtra("videoUrl");initWidget();initPlayer();mHandler.postDelayed(task,1000);}9.1.2初始化/***初始化組件**/privatevoidinitWidget(){mSurface=(SurfaceView)findViewById(R.id.svew);mSeekBar=(SeekBar)findViewById(R.id.seek_bar);mtxtCurTime=(TextView)findViewById(R.id.txt_cur_time);mtxtTotalTime=(TextView)findViewById(R.id.txt_total_time);mPlayPause=(ImageView)findViewById(R.id.img_play_pause);//設(shè)置播放進(jìn)度的初始值
mtxtCurTime.setText("00:00:00"+"/");mtxtTotalTime.setText("00:00:00");mSeekBar.setProgress(0);mSeekBar.setMax(100);//為播控按鈕設(shè)置單擊事件監(jiān)聽(tīng)
mPlayPause.setOnClickListener(newOnClickListener(){@Override9.1.2初始化publicvoidonClick(Viewv){if(mPlayer.isPlaying()){mPlayer.pause();mPlayPause.setImageResource(R.drawable.play);}else{mPlayer.start();mPlayPause.setImageResource(R.drawable.pause);}}});mSeekBar.setOnSeekBarChangeListener(this);}/***初始化播放器**/9.1.2初始化privatevoidinitPlayer(){mPlayer=newMediaPlayer();try{//設(shè)置視頻源
mPlayer.setDataSource(mVideoUrl);mHolder=mSurface.getHolder();//為SurfaceHolder增加回調(diào)函數(shù)
mHolder.addCallback(newSurfaceHolder.Callback(){@OverridepublicvoidsurfaceDestroyed(SurfaceHolderholder){}@OverridepublicvoidsurfaceCreated(SurfaceHolderholder){mPlayer.setDisplay(holder);}@OverridepublicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){}});9.1.2初始化
//準(zhǔn)備播放源
mPlayer.prepareAsync();//設(shè)置播放器準(zhǔn)備的回調(diào)函數(shù)
mPlayer.setOnPreparedListener(newOnPreparedListener(){@OverridepublicvoidonPrepared(MediaPlayermp){if(null!=mp){mp.start();//準(zhǔn)備完成就播放視頻
mVideoLength=mp.getDuration();//獲取視頻總時(shí)長(zhǎng)并顯示
mtxtTotalTime.setText(CommonUtils.formatVideoLength(mVideoLength));}}});}catch(Exceptione){e.printStackTrace();}}在組件的初始化initWidget()方法中,首先通過(guò)findViewById()方法獲取各個(gè)控件,然后為進(jìn)度的顯示和進(jìn)度條的位置設(shè)置初始值。通過(guò)setOnClickListener()方法為播控按鈕設(shè)置監(jiān)聽(tīng)事件。9.1.2初始化在播放器的初始化initPlayer()方法中,首先創(chuàng)建了一個(gè)MediaPlayer對(duì)象,通過(guò)setDataSource()方法設(shè)置視頻源,然后獲取SurfaceView的SurfaceHolder,為其添加回調(diào)函數(shù)。最后調(diào)用MediaPlayer類的prepareAsync()方法異步準(zhǔn)備播放源,當(dāng)播放源準(zhǔn)備完畢后,會(huì)回調(diào)OnPreparedListener的onPrepared()方法,在其中可以啟動(dòng)MediaPlayer對(duì)象進(jìn)行視頻播放,并且可以獲取視頻的總時(shí)長(zhǎng)。9.1.3播控和進(jìn)度控制在視頻播放中,暫停、繼續(xù)播放和進(jìn)度拖動(dòng)是常見(jiàn)的操作。播控是通過(guò)監(jiān)聽(tīng)圖片的單擊事件實(shí)現(xiàn)的,代碼如下所示://為播控按鈕設(shè)置單擊事件監(jiān)聽(tīng)mPlayPause.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){if(mPlayer.isPlaying()){mPlayer.pause();mPlayPause.setImageResource(R.drawable.play);}else{mPlayer.start();mPlayPause.setImageResource(R.drawable.pause);}}});9.1.3播控和進(jìn)度控制在播控按鈕被單擊后,首先判斷當(dāng)前視頻的狀態(tài).如果處于暫停狀態(tài),則調(diào)用MediaPlayer類的start()方法繼續(xù)播放,同時(shí)更換播控的圖片,顯示暫停按鈕如果處于播放狀態(tài),則調(diào)用MediaPlayer類的pause()方法暫停視頻播放,同時(shí)更換播控的圖片,顯示播放按鈕9.1.3播控和進(jìn)度控制播放界面和暫停界面如圖9.2和圖9.3所示。圖9.2播放狀態(tài)圖9.3暫停界面9.1.3播控和進(jìn)度控制拖動(dòng)拖動(dòng)條滑塊進(jìn)行視頻的快進(jìn)和快退是通過(guò)監(jiān)聽(tīng)OnSeekBarChangeListener事件實(shí)現(xiàn)的。首先在代碼中通過(guò)setOnSeekBarChangeListener()為拖動(dòng)條設(shè)置事件監(jiān)聽(tīng),然后重寫(xiě)OnSeekBarChangeListener的回調(diào)函數(shù),在不同的事件觸發(fā)下執(zhí)行不同的動(dòng)作。privatevoidinitWidget(){…………mSeekBar.setOnSeekBarChangeListener(this);}/***拖動(dòng)條發(fā)生改變時(shí)回調(diào)**/@OverridepublicvoidonProgressChanged(SeekBarseekBar,intprogress,booleanfromUser){mPlayer.seekTo((int)((progress/100.0f)*mVideoLength));}/**9.1.3播控和進(jìn)度控制
*拖動(dòng)條被觸摸時(shí)回調(diào)**/@OverridepublicvoidonStartTrackingTouch(SeekBarseekBar){if(mPlayer.isPlaying()){mPlayer.pause();}}/***拖動(dòng)條被釋放時(shí)回調(diào)**/@OverridepublicvoidonStopTrackingTouch(SeekBarseekBar){if(null!=mPlayer&&!mPlayer.isPlaying()){mPlayer.start();}}onStartTrackingTouch()在拖動(dòng)條被觸摸時(shí)回調(diào),其中可以調(diào)用MediaPlayer的pause()方法暫停視頻的播放。onStopTrackingTouch()在拖動(dòng)條被釋放時(shí)回調(diào),此時(shí)快進(jìn)或快退操作已經(jīng)完成,調(diào)用MediaPlayer的start()方法繼續(xù)播放視頻。9.1.3播控和進(jìn)度控制在播放的過(guò)程中,需要根據(jù)當(dāng)前視頻播放的時(shí)間實(shí)時(shí)更新滑塊的顯示位置和視頻的當(dāng)前播放時(shí)長(zhǎng),這可以通過(guò)Handler和Runnable任務(wù)實(shí)現(xiàn),代碼具體如下:privateRunnabletask=newRunnable(){@Overridepublicvoidrun(){intprogress=mSeekBar.getProgress();intposition=mPlayer.getCurrentPosition();if(0!=mVideoLength&&mPlayer.isPlaying()){//計(jì)算拖動(dòng)條滑塊應(yīng)該處于的位置
progress=(int)((position/(mVideoLength*1.0f))*100);}mSeekBar.setProgress(progress);//更新當(dāng)前應(yīng)該顯示的播放時(shí)間
mtxtCurTime.setText(CommonUtils.formatVideoLength(position)+"/");if(progress>=100){mHandler.removeCallbacks(this);}else{mHandler.postDelayed(this,1000);//每隔1s執(zhí)行一次
}}};9.1.3播控和進(jìn)度控制
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 財(cái)務(wù)經(jīng)理錄用合同
- 蕪湖高新區(qū)度展廳裝修合同項(xiàng)目競(jìng)爭(zhēng)性談判公告
- 儀器設(shè)備租賃合同示范文本
- 銷售合同書(shū)轉(zhuǎn)讓協(xié)議
- 透析中低血壓休克緊急處理
- 小學(xué)道德與法治四年級(jí)上冊(cè) 第一單元 與班級(jí)共成長(zhǎng) 單元作業(yè)設(shè)計(jì)(無(wú)答案)
- 1家的意味表格式公開(kāi)課一等獎(jiǎng)創(chuàng)新教學(xué)設(shè)計(jì) 七年級(jí)上冊(cè)道德與法治
- Brand KPIs for ready-made-food DAucy in Brazil-外文版培訓(xùn)課件(2025.2)
- 實(shí)驗(yàn)活動(dòng) 1 氧氣的實(shí)驗(yàn)室制取與性質(zhì)教學(xué)設(shè)計(jì)-2024-2025學(xué)年九年級(jí)化學(xué)人教版(2024)上冊(cè)
- 藏族民間舞蹈的動(dòng)作組合
- 傳統(tǒng)制造業(yè)市場(chǎng)營(yíng)銷轉(zhuǎn)型方案
- 新版加油站全員安全生產(chǎn)責(zé)任制
- S7-1200 PLC編程及應(yīng)用 第4版習(xí)題答案
- 國(guó)家職業(yè)技術(shù)技能標(biāo)準(zhǔn) 4-08-09-01 商業(yè)攝影師 人社廳發(fā)202332號(hào)
- 專項(xiàng)13-最值模型-將軍飲馬-專題訓(xùn)練
- GB/T 3045-2024普通磨料碳化硅化學(xué)分析方法
- 人格障礙患者的護(hù)理
- 人工智能大模型
- 1輸變電工程施工質(zhì)量驗(yàn)收統(tǒng)一表式(線路工程)-2024年版
- 2024年全國(guó)鄉(xiāng)村振興職業(yè)技能大賽“育嬰”賽項(xiàng)考試題庫(kù)(決賽用)
評(píng)論
0/150
提交評(píng)論