編輯:關於Android編程
實現一個播放器裡的全屏播放功能
視頻播放器的核心是:VideoView
使用AndroidStudio設置Activity的全橫屏會出現閃退
解決方法:
把運行類的繼承改成Activity就可以了
有兩種實現全屏的方法
第一種是配置xml第二種是運行類中編寫代碼實現
第一種實現方式:
在xml配置一下當前Activity為橫屏不可切換豎屏
1、在清單文件AndroidManifest.xml的Activity標簽中加入android:screenOrientation="landscape"
2、在清單文件AndroidManifest.xml的application標簽中加入android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
這裡的視頻文件是網上的鏈接 所以要記得加入INTERNET權限
第二種:
在運行類中加入代碼實現全屏
requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
現在要實現主頁的Activity跳轉到全屏的Activity播放的話不能在全屏播放的類中加上
requestWindowFeature(Window.FEATURE_NO_TITLE);
會使主頁的Activity沒有標題 如果就像讓它無標題那就設置 這裡的類如果不是繼承Activity的話 點擊播放就會閃退
想實現的效果如下圖:


主要效果是為了實現全屏的功能 所以不完善其他功能 視頻文件也是指定好的網上文件 沒有什麼緩沖等等
主頁面很簡單就是一個按鈕 點擊按鈕後打開全屏播放視頻
xml布局如下
package com.example.szh.day10;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class Index extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_index);
}
public void player3(View view){
Intent intent = new Intent(this,VideoViewActivity.class);
startActivity(intent);
}
}
第二個界面全屏功能
已具備的功能:
1、在全屏狀態下可以左右滑動定位到影片的進度位置 這裡設置的為1秒
2、seekBar控件可以滑動定位到指定視頻位置播放
3、暫停
4、播放
5、停止
6、單擊視頻播放器的時候回出現控制器 控制器在2秒後隱藏 控制器的顯示和隱藏調用了簡單的動畫效果
代碼如下
package com.example.szh.day10;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.VideoView;
import java.util.Timer;
import java.util.TimerTask;
public class VideoViewActivity extends Activity {
private VideoView videoView;
private SeekBar seekBar;
private Timer timer;//javase中的計時器
private TimerTask timerTask;//任務棧
private LinearLayout control;//視頻的控制器對應的布局ID
private int pause = 0;//暫停用來獲取暫停時影片的進度
private int startX;//落下的X坐標
int seek =0;//左右滑動時更新seek的值修改到SeekBar中
int up = 0;//計算用戶落下的坐標和離開時的坐標可供下面判斷左右滑動
int change = 0;//用戶滑動的坐標變化
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_view);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
control = (LinearLayout) findViewById(R.id.control);
seekBar = (SeekBar) findViewById(R.id.sb);
videoView = (VideoView) findViewById(R.id.videoView);
//播放地址
videoView.setVideoPath("http://hc.yinyuetai.com/uploads/videos/common/5BAA0126EA2C38ACF34DA" +
"07ECF52DCBB.flv?sc\\u003d63348fe3ecf23d32\\u0026br\\u003d549\\u0026vid\\u003d32456" +
"\\u0026aid\\u003d311\\u0026area\\u003dHT\\u0026vst\\u003d2");
//開始播放
videoView.start();
//setOnPreparedListener數據准備事件,准備好了才給SeekBar賦值
/*
* int duration = videoView.getDuration();//獲取視頻的時長
* seekBar.setMax(duration);//設置seekBar的最大值為視頻的時長
* 這裡的賦值不能寫在監聽事件以外
* 之前我寫在了timerTask裡面導致播放斷斷續續
* 寫在了videoView.start();之後又獲取不到視頻的長度
* 想了許久後發現之前寫的MP3播放是需要准備監聽事件去解決主線程阻塞的情況,
* 於是就想 是不是MP4也需要讓它先判斷是否准備完成、於是上網浏覽了下
* setOnPreparedListener的用法後才知道 視頻也是需要這個事件才可以
*
* */
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
int duration = videoView.getDuration();//獲取視頻的時長
seekBar.setMax(duration);//設置seekBar的最大值為視頻的時長
}
});
/*
* 新建javase中的計時器和任務棧
* 任務棧中要實現SeekBar的進度的實時更新
*
* */
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
//獲取當前視頻的時間
int progess = videoView.getCurrentPosition();
//設置SeekBar的進度
seekBar.setProgress(progess);
}
};
//每1秒執行一次 立刻執行
timer.schedule(timerTask, 0, 1000);
//SeekBar的滑動事件
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
//值的改變 不實現這個功能
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
//開始觸摸SeekBar監聽事件不實現這個功能
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
//用戶滑動後離開SeekBar調用的事件
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//獲取離開時的值
int progress = seekBar.getProgress();
//設置視頻從該值開始播放
videoView.seekTo(progress);
}
});
}
/*
* 開始播放按鈕
* */
public void start(View view){
//先判斷是否暫停
if(pause!=0){
videoView.start();
videoView.seekTo(pause);
pause=0;
}else if(!videoView.isPlaying()&&pause==0){
videoView.start();
}
}
/*
* 暫停 並把當前視頻的時間賦值給pause變量
* */
public void pause(View view){
videoView.pause();
pause = videoView.getCurrentPosition();
}
/*
* 停止 設置視頻到0秒播放並且暫停
* */
public void stop(View view){
videoView.seekTo(0);
videoView.pause();
}
//Activity被銷毀後要釋放掉資源
@Override
protected void onDestroy() {
timer.cancel();
timerTask.cancel();
timer = null;
timerTask = null;
super.onDestroy();
}
//為Activity設置觸摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
//event.getAction()獲取事件的狀態
switch (event.getAction()){
//當用戶單擊屏幕的時候控制被調出
case MotionEvent.ACTION_DOWN://按下
//獲取用戶按下時的X坐標
startX = (int) event.getX();
//把判斷左右滑動的值歸0
up=0;
//判斷控制器是否隱藏 一開始布局的配置是先讓控制隱藏
if(control.getVisibility()== View.VISIBLE){//如果控制器可見就設置為不可見
control.setVisibility(View.INVISIBLE);//隱藏
//移動的動畫 這裡不做詳細解析
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF
,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0F,Animation.RELATIVE_TO_SELF,1.0F);
//動畫的時間
ta.setDuration(200);
//動畫開始
control.startAnimation(ta);
}else if(control.getVisibility()== View.INVISIBLE){//如果控制器不可見就設置可見
control.setVisibility(View.VISIBLE);//顯示
//移動的動畫 這裡不做詳細解析
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF
,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0f);
//動畫的時間
ta.setDuration(200);
//動畫開始
control.startAnimation(ta);
//顯示後用戶沒有再進行頁面的任何操作時 2秒後自動隱藏控制器
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
control.setVisibility(View.INVISIBLE);//隱藏
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF
,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0F,Animation.RELATIVE_TO_SELF,1.0F);
ta.setDuration(200);
control.startAnimation(ta);
}
});
}
}.start();
}
break;
case MotionEvent.ACTION_MOVE://移動
change = (int) event.getX();//獲取到移動的X軸的值
up = startX - change;//實時賦值給up變量
break;
case MotionEvent.ACTION_UP://離開
up = 0;
break;
}
//使用startX - change得到的值 結果為負 就是向右移動 反之向左移動
if(up<0){
//獲取當前視頻的播放進度
int currentPosition = videoView.getCurrentPosition();
//當前視頻的播放進度再加1秒
seek = currentPosition + 1000;
//這個值不能大於視頻的長度
if (seek <= videoView.getDuration()) {
videoView.seekTo(seek);
}
}else if(up>0){
//獲取當前視頻的播放進度
int currentPosition = videoView.getCurrentPosition();
//當前視頻的播放進度減1秒
seek = currentPosition - 1000;
//這個值不能小於0
if (seek >= 0) {
videoView.seekTo(seek);
}
}
return super.onTouchEvent(event);
}
}
主清單文件如下
功能並不完善 以後有時間的話回頭繼續寫 目標把它做成一個功能完善的視頻播放器~~~~~~~~~~~~~~~~
Android FM模塊學習之二 FM搜索頻率流程
上一篇大概分析了一下FM啟動流程,若不了解Fm啟動流程的,可以去打開前面的鏈接先了解FM啟動流程,接下來我們簡單分析一下FM的搜索頻率流程。 在了解源碼之前,我們先看一下
Android入門之ListView應用解析(一)
Android中的ListView是一個經常用到的控件,ListView裡面的每個子項Item可以使一個字符串,也可以是一個組合控件。本文先來說說ListView的實現:
Android 從底部彈出Dialog(橫向滿屏)的實例代碼
項目中經常需要底部彈出框,這裡我整理一下其中我用的比較順手的一個方式(底部彈出一個橫向滿屏的dialog)。效果圖如下所示(只顯示關鍵部分):步驟如下所示:1.定義一個d
基於Android實現轉盤按鈕代碼
先給大家展示下效果圖:package com.lixu.circlemenu; import android.app.Activity; import android.o