运用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播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里 ...
随机推荐
- TPL
namespace TPLTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } pr ...
- 4、什么构成了我们Android应用程序?(七大件)
一.应用程序四大组件 [Activity] Activity是Android应用程序的一个界面,可以通过这个界面查看联系人,打电话戒玩游戏. b. 一个应用程序通常包含多个Activity. c. A ...
- 黑盒测试用例设计方法&理论结合实际 -> 正交试验法
一. 概念 依据Galois理论,从大量的(实验)数据(测试例)中挑选适量的,有代表性的点(例),从而合理地安排实验(测试)的一种科学实验设计方法.类似的方法有:聚类分析方法,因子方法方法等. 二. ...
- Unicode中跟汉字相关的一些内容的总结陈词
UniHan 这几天琢磨着怎么方便的给汉字注音, 因为要知道具体哪些Unicode是给汉字用的, 就读了读Unicode的官方文档. 目前unicode已经发展到了7.0. 不看不知道, 发现Unic ...
- 【原创】linux命令bc使用详解
最近经常要在linux下做一些进制转换,看到了可以使用bc命令,如下: echo "obase=10;ibase=16;CFFF" | bc 用完以后就对bc进行了进一步的了解, ...
- HW6.24
public class Solution { public static void main(String[] args) { int count = 0; int color; int numbe ...
- HDU-4689 Derangement DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4689 题意:初始序列1,2...n,求所有满足与初始序列规定大小的错排数目.. 这道题目感觉很不错~ ...
- HDU-4678 Mine 博弈SG函数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4678 题意就不说了,太长了... 这个应该算简单博弈吧.先求联通分量,把空白区域边上的数字个数全部求出 ...
- 单点登录与消息队列以及在J2EE中的实现方案
前言 这次为大家简单介绍两个在WEB开发中经常使用的概念——单点登录和消息队列以及具体到J2EE中的一些实现方案.本文原创性的工作比较少,主要是一些总结概括和自己的理解. 单点登录SSO SSO的业务 ...
- 射频识别技术漫谈(8)——动物标签【worldsing笔记】
动物标签也是工作在TTF模式的ID(Identification)卡.之所以通常称为动物标签,估计是因为一来和识别人的ID卡相区分,二是因为动物不如人听话,人的ID卡可以做成卡片形状拿在手上,而动物不 ...