运用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播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里 ...
随机推荐
- Zabbix探索:Agent配置中Hostname错误引起的Agent.Ping报错
搭好了Zabbix_Server以后,添加了服务器本身和一台Windows的机器做测试,居然有这样的报警. Zabbix agent on zabbix_client is unreachable f ...
- 【译】 AWK教程指南 1前言
前面的话: 这几天写了一个程序,在同一个目录里生成了很多文件,需要统计其中部分文件的总大小,发现经常用到的ls.du等命令都无济于事,我甚至都想到了最笨的方法,写一个脚本:mkdir一个新目录,把要统 ...
- 【DOM】2.闭包
1.什么是闭包? 函数嵌套函数 内部函数可以引用外部函数的参数和变量 参数和变量不会被JS中的垃圾回收机制 所收回 2.闭包有啥好处?应用在哪? ①希望一个变量长期驻扎在内存中 ②避免全局变量的污染 ...
- NOIP2011 铺地毯
1铺地毯 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的 ...
- stm32 堆和栈(stm32 Heap & Stack)【worldsing笔记】
关于堆和栈已经是程序员的一个月经话题,大部分有是基于os层来聊的. 那么,在赤裸裸的单片机下的堆和栈是什么样的分布呢?以下是网摘: 刚接手STM32时,你只编写一个 int main() ...
- 射频识别技术漫谈(14)——S50与S70存取控制【worldsing笔记】
存取控制指符合什么条件才能对卡片进行操作. S50和S70的块分为数据块和控制块,对数据块的操作有"读"."写"."加值"."减值 ...
- 【Android】JSONArray的合并
在Android开发过程中,需要处理解析服务器JSON数据时,或需要进行两个或多个JSONArray合并操作. 比如在进行LIstView的动态更新时. 在此提供一种JSONArray合并的方法,方便 ...
- Info.plist和pch文件的作用
- [置顶] Objective-C ,ios,iphone开发基础:protocol 协议(委托,代理)的声明
协议是为了弥补Objective-c中类只能单继承的缺陷,在Objective-c2.0之前当一个类遵循一个协议的时候,必须在类中实现协议的所有方法,在Objective-c2.0之后协议中的方法就有 ...
- Asp.net中使用资源文件实现网站多语言
首先需要新建一个ASP.NET Web Application.然后右键项目文件Add->Add ASP.NET Folder->App-GlobalResources. 新建好资源文件夹 ...