編輯:關於Android編程
最近因公司項目要求需要寫一個播放器,自帶的又不太好用,也不太好看。自能自定義啦。查看了很多資料,都沒有完善的,還好得以為前輩的指點得以完成,感謝Yang。本篇裡面我有可能有些地方寫得不好(都附上了注釋)。希望各路大神指點,虛心受教。
先來個圖(源碼在後面附上)

視頻列表裡面的數據是本地的,如果你需要使用網絡的只需要在此獲取服務器的數據展示就行了。播放頁面在後面。
package com.eteng.moblieplayer.video;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import com.eteng.moblieplayer.BaseActivity;
import com.eteng.moblieplayer.R;
import com.eteng.moblieplayer.adapter.VideoAdapter;
import com.eteng.moblieplayer.beans.VideoBenas;
import com.eteng.moblieplayer.utils.StringTimeUtil;
import org.xutils.view.annotation.ViewInject;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
/**
* Created by zqf on 2016/7/6.
*/
public class VideoActivity extends BaseActivity implements AdapterView.OnItemClickListener {
private ListView video_listview;
private TextView noresources_tv;
private VideoBenas beans;
private List data = new ArrayList();
private VideoAdapter adapter;
private StringTimeUtil util;
public Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
if (data != null && data.size() != 0) {
noresources_tv.setVisibility(View.GONE);
adapter = new VideoAdapter(data, VideoActivity.this, util);
video_listview.setAdapter(adapter);
} else {
noresources_tv.setVisibility(View.VISIBLE);
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settabtitle("視頻列表");
setrightvisible(View.GONE);
video_listview = (ListView) findViewById(R.id.video_listviw);
noresources_tv = (TextView) findViewById(R.id.noresources_tv);
util = new StringTimeUtil();
getAllVideo();
video_listview.setOnItemClickListener(this);
}
private void getAllVideo() {
new Thread(new Runnable() {
@Override
public void run() {
ContentResolver resolver = getContentResolver();
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
//查找的條件
String[] projection = {MediaStore.Video.Media.TITLE, //標題
MediaStore.Video.Media.DESCRIPTION, //描述
MediaStore.Video.Media.SIZE, //大小
MediaStore.Video.Media.DURATION, //時長
MediaStore.Video.Media.DATA}; //絕對路徑
Cursor cursor = resolver.query(uri, projection, null, null, null);
while (cursor.moveToNext()) {
//判斷視頻大小>3MB的才添加進來。
if (cursor.getLong(2) > 3 * 1024 * 1024) {
beans = new VideoBenas();
beans.setTitle(cursor.getString(0));
beans.setDescribe(cursor.getString(1));
beans.setSize(cursor.getLong(2));
beans.setLongtime(cursor.getString(3));
beans.setPath(cursor.getString(4));
data.add(beans);
}
}
handler.sendEmptyMessage(0);
}
}).start();
}
@Override
public void leftonclick() {
finish();
}
@Override
public void rightonclick() {
}
//加載子布局內容
@Override
public View setcontent() {
return View.inflate(VideoActivity.this, R.layout.activity_video, null);
}
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
VideoBenas item = data.get(position);
Intent intent = new Intent(VideoActivity.this, VideoPlayerActivity.class);
intent.setData(Uri.parse(item.getPath()));
intent.putExtra("videotitle",item.getTitle());
startActivity(intent);
}
}
好了,接下來就是播放器頁面了。
package com.eteng.moblieplayer.video;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.eteng.moblieplayer.BaseActivity;
import com.eteng.moblieplayer.R;
import com.eteng.moblieplayer.utils.StringTimeUtil;
import com.eteng.moblieplayer.view.VideoView;
/**
* Created by zqf on 2016/7/6.
* 播放頁面
*/
public class VideoPlayerActivity extends BaseActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnInfoListener {
private VideoView videoView;
//--播放的地址uri
private Uri uri;
private ImageView play_imag, fullview_imag, back_imag, battery_imag;
private SeekBar mseekBar;
private TextView videoTitle, SystemTime;
private TextView videocurrent_time, videototal_time;
private StringTimeUtil utils;
private MyBrodCastReceiver receiver;
//設置電量
private int leave;
//手勢識別器
private GestureDetector detector;
//頂部布局
private RelativeLayout top_layout;
//底部布局
private LinearLayout bottom_layout;
/**
* 判斷是否播放
*/
private boolean isPlayer = false;
/***
* 判斷Activity是否被銷毀
* --true-->銷毀
* --false -->沒有銷毀
*/
private boolean isDestory = false;
//
private static final int PROGRESS = 1;
//隱藏頂部和底部的變量
private static final int HIDE_TOPBOTTOMLAYOUT = 2;
/**
* 網絡加載等待布局
*/
private LinearLayout ll_loading;
/***
* 出現卡的緩沖加載
*/
private ProgressBar pg_buff;
private Handler mhandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case PROGRESS:
//設置進度
int currenttime = videoView.getCurrentPosition();
videocurrent_time.setText(utils.stringfortime(currenttime));
//更新seekbar
mseekBar.setProgress(currenttime);
//更新電量 //電量顯示和系統時間可自行設置多久時間更新一次
setBattery();
//設置系統時間
setsystemTime();
/***
* 得到視頻緩存度
* --緩存比例值-0~100
*/
int Percentage = videoView.getBufferPercentage();
int total = Percentage * mseekBar.getMax();
int secondaryprogress = total / 100;
mseekBar.setSecondaryProgress(secondaryprogress);
if (!isDestory) {
mhandler.removeMessages(PROGRESS);
//消息的死循環--用於更新播放進度
mhandler.sendEmptyMessageDelayed(PROGRESS, 1000);
}
break;
case HIDE_TOPBOTTOMLAYOUT:
hidelayout();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settabvisible(View.GONE);
initView();
initData();
setonclick();
//得到播放地址
uri = getIntent().getData();
videoView.setVideoURI(uri); //設置路徑
videoView.setOnPreparedListener(this); //准備好的監聽事件
}
private void setsystemTime() {
SystemTime.setText(utils.getSystemTime());
}
private void setBattery() {
if (leave <= 5) {
battery_imag.setImageResource(R.mipmap.icv_power_00);
} else if (leave <= 20) {
battery_imag.setImageResource(R.mipmap.icv_power_01);
} else if (leave <= 40) {
battery_imag.setImageResource(R.mipmap.icv_power_02);
} else if (leave <= 60) {
battery_imag.setImageResource(R.mipmap.icv_power_03);
} else if (leave <= 80) {
battery_imag.setImageResource(R.mipmap.icv_power_04);
} else if (leave <= 100) {
battery_imag.setImageResource(R.mipmap.icv_power_05);
}
}
/***
* true--顯示--false--隱藏
*/
private boolean isShowLayout = false;
private void initData() {
videoTitle.setText(getIntent().getStringExtra("videotitle"));
isDestory = false;
utils = new StringTimeUtil();
//注冊電量監聽的廣播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
receiver = new MyBrodCastReceiver();
registerReceiver(receiver, intentFilter);
//實例化
detector = new GestureDetector(VideoPlayerActivity.this, new GestureDetector.OnGestureListener() {
//單擊
@Override
public boolean onDown(MotionEvent e) {
Log.e("TAG", "onDown");
if (isShowLayout) {
removeHideTopBottomLayoutMessage();
hidelayout();
} else {
sendDelayedHideTopBottomLayout();
showLayout();
}
return true;
}
//長按執行的順序---1.onDown-->2.onShowPress-->onLongPress
@Override
public void onShowPress(MotionEvent e) {
Log.e("TAG", "onShowPress");
}
//單擊後執行onDown接著執行的方法
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.e("TAG", "onSingleTapUp");
return false;
}
//滑動
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.e("TAG", "onScroll");
return false;
}
//長按
@Override
public void onLongPress(MotionEvent e) {
Log.e("TAG", "onLongPress");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
}
/***
* 發送延遲隱藏
*/
private void sendDelayedHideTopBottomLayout() {
mhandler.sendEmptyMessageDelayed(HIDE_TOPBOTTOMLAYOUT, 5000);
}
/***
* 移除延遲隱藏的Handler消息
*/
private void removeHideTopBottomLayoutMessage() {
mhandler.removeMessages(HIDE_TOPBOTTOMLAYOUT);
}
/***
* 顯示的方法
*/
private void showLayout() {
isShowLayout = true;
top_layout.setVisibility(View.VISIBLE);
bottom_layout.setVisibility(View.VISIBLE);
}
/***
* 隱藏的方法
*/
private void hidelayout() {
isShowLayout = false;
top_layout.setVisibility(View.GONE);
bottom_layout.setVisibility(View.GONE);
}
/***
* 使用手勢適配器
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
detector.onTouchEvent(event);
return true; //返回true視交由人為處理
}
/***
* 卡或者拖動卡時候出現的回調
*
* @param mp
* @param what
* @param extra
* @return
*/
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START: //開始出現卡或者拖動卡
pg_buff.setVisibility(View.VISIBLE);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END: //結束卡或者拖動卡情況
pg_buff.setVisibility(View.GONE);
break;
}
return true;
}
private class MyBrodCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//返回一個電量的范圍值
leave = intent.getIntExtra("level", 0);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
isDestory = true;
unregisterReceiver(receiver);
receiver = null;
videoView.stopPlayback();
}
public void initView() {
pg_buff = (ProgressBar) findViewById(R.id.pg_buff);
videoView = (VideoView) findViewById(R.id.videoview);
ll_loading = (LinearLayout) findViewById(R.id.ll_loading);
top_layout = (RelativeLayout) findViewById(R.id.topLayout);
bottom_layout = (LinearLayout) findViewById(R.id.bottomLayout);
SystemTime = (TextView) findViewById(R.id.videosystemTime);
battery_imag = (ImageView) findViewById(R.id.videoPower);
back_imag = (ImageView) findViewById(R.id.videoBack);
play_imag = (ImageView) findViewById(R.id.videoPlay);
fullview_imag = (ImageView) findViewById(R.id.videoFullScreen);
mseekBar = (SeekBar) findViewById(R.id.videoPlayProgress);
videoTitle = (TextView) findViewById(R.id.videoTitle);
videocurrent_time = (TextView) findViewById(R.id.videoCurrentProgress);
videototal_time = (TextView) findViewById(R.id.videototalTime);
}
public void setonclick() {
back_imag.setOnClickListener(onclicklistener);
play_imag.setOnClickListener(onclicklistener);
fullview_imag.setOnClickListener(onclicklistener);
videoView.setOnInfoListener(this);
mseekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
/***
*
* @param seekBar-->自身的seekba
* @param progress-->seekbar的位置,視頻的長度和seekbar的位置一一對應
* @param fromUser-->如果是人為的拖動值為--true,如seekbar自身在改變的值--false
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
videoView.seekTo(progress);
}
}
/**
* 手指開始拖動時進行回調
* @param seekBar
*/
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
removeHideTopBottomLayoutMessage();
}
/**
* 手指離開回調
* @param seekBar
*/
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
sendDelayedHideTopBottomLayout();
}
});
/***
* 視頻加載出錯時進行回掉
* --true-->人為處理出錯的結果
*/
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(VideoPlayerActivity.this, "視頻出錯了", Toast.LENGTH_LONG).show();
finish();
return true;
}
});
}
View.OnClickListener onclicklistener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.videoPlay:
if (isPlayer) {
videoView.pause();
play_imag.setImageResource(R.mipmap.icv_play);
} else {
videoView.start();
play_imag.setImageResource(R.mipmap.icv_pause);
}
isPlayer = !isPlayer;
break;
case R.id.videoBack:
finish();
videoView.stopPlayback();
break;
}
}
};
@Override
public void leftonclick() {
}
@Override
public void rightonclick() {
}
//設置子布局
@Override
public View setcontent() {
return View.inflate(VideoPlayerActivity.this, R.layout.activity_videoplayer, null);
}
/***
* 監聽是否准備好了
*
* @param mp
*/
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
play_imag.setImageResource(R.mipmap.icv_pause);
isPlayer = true;
//獲取總時長
int duration = videoView.getDuration();
videototal_time.setText("/" + utils.stringfortime(duration));
//設置seekbar的最大值
mseekBar.setMax(duration);
setsystemTime();
mhandler.sendEmptyMessageDelayed(PROGRESS, 1000);
sendDelayedHideTopBottomLayout();
ll_loading.setVisibility(View.GONE);
}
}
最後結尾來個圖吧!

上次忘記發源碼地址啦,給補上,抱歉
Android——ListView多布局+適配器(二)
package com.example.administrator.newstop.entity;/** * Created by Administrator
Android編程實現3D旋轉效果實例
本文實例講述了Android編程實現3D旋轉效果的方法。分享給大家供大家參考,具體如下:下面的示例是在Android中實現圖片3D旋轉的效果。實現3D效果一般使用Open
Android Fragment動態創建詳解及示例代碼
Android Fragment 動態創建Fragment是activity的界面中的一部分或一種行為。可以把多個Fragment組合到一個activity中來創建一個多
android4.4 webview chromium顯示網頁的chromium內核結構
android4.4 webview chromium是單進程的,圖中所有組件都運行在Browser進程中。 按從上而下的順序介紹這張圖中與顯示網頁相關的chromiu