运用surfaceView与MediaPlayer实现播放视频的功能
该程序运用了surfaceView与MediaPlayer结合,实现播放视频,surfaceView详情请见
SurfaceView的使用
使用了第三方包Volly里面的方法StringQueue下载json数据,ImageLoader下载图片数据,Volley请见
MyApp:主要作用是创建请求队列,设置为全局变量
public class MyApp extends Application {
private static RequestQueue requestQueue; @Override
public void onCreate() {
super.onCreate();
requestQueue = Volley.newRequestQueue(this);
}
public static RequestQueue getRequestQueue(){
return requestQueue;
}
}
main函数:
public class MainActivity extends AppCompatActivity { private ListView listview;
/*装载数据的集合*/
private List<QSBK.ItemsBean> dataList = new ArrayList<>();
/*请求队列*/
private RequestQueue requestQueue;
/*自定义适配器*/
private QSAdapter qsAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
//加载数据
loadData();
//设置适配器
qsAdapter = new QSAdapter(this, dataList);
listview.setAdapter(qsAdapter);
} /**
* 加载数据
*/
private void loadData() {
//得到请求队列
requestQueue = MyApp.getRequestQueue();
StringRequest stringRequest = new StringRequest(Request.Method.GET, String.format(uri.URL_VIDEO, ), new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//解析gson
Gson gson = new Gson();
QSBK qsbk = gson.fromJson(response, QSBK.class);
//添加数据,并通知适配器更新
dataList.addAll(qsbk.getItems());
qsAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
stringRequest.setTag("DATA");
requestQueue.add(stringRequest);
} @Override
protected void onDestroy() {
//设置标记,请求队列根据标记取消当前请求
requestQueue.cancelAll("DATA");
super.onDestroy();
}
}
QSAdapter:
public class QSAdapter extends QSBaseAdapter implements MediaPlayer.OnPreparedListener {
private ImageLoader imageLoader;
private int currentPosition = -1;
private MediaPlayer mediaPlayer; public QSAdapter(Context context, List<QSBK.ItemsBean> dataList) {
super(context, dataList);
imageLoader = new ImageLoader(MyApp.getRequestQueue(),new MyImageLruCache());
mediaPlayer = new MediaPlayer();
//媒体播放器设置准备监听
mediaPlayer.setOnPreparedListener(this);
}
监听事件作用:开始播放视频
/**
* 播放器的准备监听
* @param mp
*/
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
listView的优化,复用控件,将布局传入ViewHolder中
并利用ImageLoader下载图片
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if(convertView == null){
convertView = layoutInflater.inflate(R.layout.listview_item_video,parent,false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
QSBK.ItemsBean itemsBean = dataList.get(position);
if(itemsBean.getUser()!= null &&itemsBean.getUser().getLogin()!= null&&itemsBean.getUser().getIcon()!= null) {
viewHolder.tvContent.setText(itemsBean.getContent());//设置内容
viewHolder.tvLogin.setText(itemsBean.getUser().getLogin());//设置用户名
//获得监听
ImageLoader.ImageListener imageListener = imageLoader.getImageListener(viewHolder.icon, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
//头像获取(+ id掉后4位 + "/" + id + "/thumb/" + icon图片名.jpg)
//userIcon======http://pic.qiushibaike.com/system/avtnew/1499/14997026/thumb/20140404194843.jpg
//加载图片
imageLoader.get(String.format(uri.URL_USER_ICON, itemsBean.getUser().getId() / 10000, itemsBean.getUser().getId(), item sBean.getUser().getIcon()), imageListener);//设置图标
ImageLoader.ImageListener imageListener1 = imageLoader.getImageListener(viewHolder.picUrl, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
动态设置图片的高度:
注意:surfaceView如果不设置固定高度,就没有显示,包裹内容也没有显示
//动态的设置图片的宽高
ViewGroup.LayoutParams layoutParams = viewHolder.picUrl.getLayoutParams();
layoutParams.height = itemsBean.getPic_size().get(1);
//请求重新布局
viewHolder.picUrl.requestLayout();
//设置视频的高度
ViewGroup.LayoutParams layoutParams1 = viewHolder.sfvLowUrl.getLayoutParams();
layoutParams1.height = itemsBean.getPic_size().get(1);
viewHolder.sfvLowUrl.requestLayout();
为图片设置一个tag,目的是当点击图片时,需要在监听事件中得到该索引,以此来确定播放的视频
viewHolder.picUrl.setTag(position);
//判断手指点击的视频对应的索引是否等于当前正在显示的页面的索引
if(currentPosition == position) {
try {
//设置图片不显示,视频显示
viewHolder.picUrl.setVisibility(View.GONE);
viewHolder.sfvLowUrl.setVisibility(View.VISIBLE);
//设置数据源为当前手指点击的视频资源
mediaPlayer.setDataSource(context, Uri.parse(itemsBean.getLow_url()));
//异步准备,会调用准备监听
mediaPlayer.prepareAsync();
//得到操作surfaceView 的接口
SurfaceHolder holder = viewHolder.sfvLowUrl.getHolder();
//绑定生命周期
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
//媒体播放器与surfaceView进行绑定
mediaPlayer.setDisplay(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
} catch (IOException e) {
e.printStackTrace();
}
}else{
//设置图片显示,视频不显示
viewHolder.sfvLowUrl.setVisibility(View.GONE);
viewHolder.picUrl.setVisibility(View.VISIBLE);
imageLoader.get(itemsBean.getPic_url(),imageListener1);//加载覆盖视频的图片
}
}
return convertView;
}
ViewHolder:
class ViewHolder{
ImageView icon,picUrl;
SurfaceView sfvLowUrl;
TextView tvContent,tvLogin;
public ViewHolder(View view){
icon = (ImageView) view.findViewById(R.id.img_icon);
picUrl = (ImageView) view.findViewById(R.id.img_pic_url);
sfvLowUrl = (SurfaceView) view.findViewById(R.id.sfv_low_url);
tvContent = (TextView) view.findViewById(R.id.tv_content);
tvLogin = (TextView) view.findViewById(R.id.tv_login);
//为图片设置监听,点击图片播放视频
picUrl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//得到当前索引
currentPosition = (int) v.getTag();
if(mediaPlayer!= null){
//重置媒体播放器,回到初始状态
mediaPlayer.reset();
} //点击更新适配器,不设置会只在滑动屏幕时才调用getView方法 notifyDataSetChanged(); } }); } }
MyImageLruCache
class MyImageLruCache implements ImageLoader.ImageCache {
private LruCache<String,Bitmap>lruCache;
public MyImageLruCache(){
lruCache = new LruCache<String,Bitmap>((int) (Runtime.getRuntime().maxMemory()/8)){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return lruCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
lruCache.put(url,bitmap);
}
}
QSBKAdapter:
public abstract class QSBaseAdapter extends BaseAdapter {
public Context context;
public List<QSBK.ItemsBean>dataList;
public LayoutInflater layoutInflater;
public QSBaseAdapter(Context context,List<QSBK.ItemsBean>dataList){
this.context = context;
this.dataList = dataList;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return dataList.size();
} @Override
public Object getItem(int position) {
return dataList.get(position);
} @Override
public long getItemId(int position) {
return position;
} }
qsbkBaseAdapter
xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center_vertical"> <ImageView
android:id="@+id/img_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="hahha"
android:textSize="25sp"
android:textColor="#00eedd"/>
</LinearLayout>
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="25dp"
android:text="神走位"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<SurfaceView
android:id="@+id/sfv_low_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/img_pic_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:src="@mipmap/ic_launcher"/>
</FrameLayout> </LinearLayout>
layout
uri:
public class uri {
// 视频
public final static String URL_VIDEO = "http://m2.qiushibaike.com/article/list/video?page=%d"; //头像获取(+ id掉后4位 + "/" + id + "/thumb/" + icon图片名.jpg)
//userIcon======http://pic.qiushibaike.com/system/avtnew/1499/14997026/thumb/20140404194843.jpg
public final static String URL_USER_ICON="http://pic.qiushibaike.com/system/avtnew/%s/%s/thumb/%s";
}
效果:
播放音频
android中播放音频可以使用MediaPlayer类来实现,一下是它的一些方法:
方法名 功能描述
setDataSource() 设置要播放的音频文件的位置。
prepare() 在开始播放之前调用这个方法完成准备工作。
start() 开始或继续播放音频。
pause() 暂停播放音频。
reset() 将 MediaPlayer 对象重置到刚刚创建的状态。
seekTo() 从指定的位置开始播放音频。
stop() 停止播放音频。调用这个方法后的 MediaPlayer 对象无法再播放音频。
release() 释放掉与 MediaPlayer 对象相关的资源。
isPlaying() 判断当前 MediaPlayer 是否正在播放音频。
getDuration() 获取载入的音频文件的时长。
运用surfaceView与MediaPlayer实现播放视频的功能的更多相关文章
- MediaPlayer简单使用,绑定surfaceView实现播放视频的功能
转载自 Android MediaPlayer使用方法简单介绍 播放音频 android中播放音频可以使用MediaPlayer类来实现,一下是它的一些方法: 方法名 功能描述 setDataSour ...
- MediaPlayer类——播放视频和音乐
1)如何获得MediaPlayer实例: 可以使用直接new的方式: MediaPlayer mp = new MediaPlayer(); 也可以使用create的方式,如: MediaPlayer ...
- [Xcode 实际操作]六、媒体与动画-(17)使用MediaPlayer框架播放视频
目录:[Swift]Xcode实际操作 本文将演示视频的播放功能. 在项目名称上点击鼠标右键,弹出右键菜单, 选择[Add Files to "DemoApp"],往项目中导入文件 ...
- 使用MediaPlayer和SurfaceView播放视频
使用VideoView播放视频简单.方便,丹有些早期的开发者更喜欢使用MediaPlayer来播放视频,但由于MediaPlayer主要用于播放音频,因此它没有提供图像输出界面,此时 需要借助于Sur ...
- Android SurfaceView + MediaPlayer实现分段视频无缝播放
Android当中实现视频播放的方式有两种,即:通过VideoView实现或者通过SurfaceView + MediaPlayer实现. 由浅至深,首先来看下想要在Android上播放一段视频,我们 ...
- 使用MediaPlayer类和SurfaceView来播放视频
MediaPlayer可以播放视频,只需需要SurfaceView的配合,SurfaceView主要用于显示MediaPlayer播放的视频流媒体的画面渲染. SurfaceView是配合MediaP ...
- android 随手记 videoview循环播放网络视频 和mediaplayer+sufaceview播放网络视频
1:videoview循环播放视频 1>xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res ...
- WPF播放视频
在现在的项目中需要使用到播放视频的功能,本来打算使用VLC来做的.后来发现WPF 4.0之后新增了MediaElement类,可以实现视频播放. <Grid> <Grid.RowDe ...
- [转]Android WebView播放视频(包括全屏播放),androidwebview
Android WebView播放视频(包括全屏播放),androidwebview 最近项目开发中用到了WebView播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里 ...
随机推荐
- HDU 5288 OO’s Sequence
题意:给一个序列,函数f(l, r)表示在[l, r]区间内有多少数字不是其他数字的倍数,求所有区间的f(l, r)之和. 解法:第一次打多校……心里还有点小激动……然而一道签到题做了俩点……呜呜呜… ...
- Java中调用参数是数组的存储过程
Java中调用参数是数组的存储过程 1. 存储过程以及类型定义如下: --The array in oracle CREATE OR REPLACE TYPE idArray AS TABLE OF ...
- VTL说明文档
关于这个指南 这个指南是针对Velocity模版语言(VTL)的说明.更多其它的信息,请参考Velocity用户指南(http://velocity.apache.org/engine/release ...
- 浏览器插件 - Chrome 对 UserScript 的声明头(metadata)兼容性一览
1.这里的UserScript指的是,油猴插件或者Tampermonkey插件等支持的格式如下例子: // ==UserScript== // @name // @namespace http://A ...
- 多线程与网络之cookies
1. 网络请求中的cookie 1.1 删除cooki NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCook ...
- Solution for latex error:”Unknown graphics extension: .eps“ or "Can not find XXX"
Sample code: \begin{figure*} \centering % Requires \usepackage{graphicx} \includegraphics[width=7in] ...
- Android的Spinner
使用Spinner遇到不少坑啊 3.自定义spinner样式 <style name="AppTheme" parent="Theme.AppCompat.Ligh ...
- hdoj 2046 骨牌铺方格
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- UIKit: UIResponder(转自南峰子博客)
有问题可以加本人QQ:564702640(验证:博客园) 我们的App与用户进行交互,基本上是依赖于各种各样的事件.例如,用户点击界面上的按钮,我们需要触发一个按钮点击事件,并进行相应的处理,以给用户 ...
- Qt Creator编辑器乱问题
新安装的Qt Creator 打开原来的工程源码时提示:无法用 "UTF-8"-编码解码 "main.cpp". 无法编辑 解决办法:修改项目属性的编辑器设 ...