android 自己定义视频播放器之2/1
非常久没更新博客,相信大家年后都比較忙。
今天给大家带来了一款视频播放器,首先确认的得有几点。
1、首先得有个播放视频的view。
2、加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量;
3、视频当然得有快进和快退,左右滑动快进和快退;
4、可全屏播放;
5、临时仅仅做了离线播放。下篇博客再去研究在线播放。视频路径 这是视频本地路径,视频资源的话你们自己去找。目录会自己主动创建。放在该目录以下就能够了
private String Path = Environment.getExternalStorageDirectory() + “/wywVideo/
首先先贴上效果图:
咱们依据效果图一步一步的来。先进行布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.wyw.activity.FullVideoView
android:id="@+id/video_VideoView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/video_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="@+id/video_img_center_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<RelativeLayout
android:id="@+id/video_relative_right"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_above="@+id/video_relative_buttom"
android:layout_alignParentRight="true"
android:background="@color/lightgray_50" >
<ImageView
android:id="@+id/video_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:src="@drawable/right_video_img" />
<ListView
android:id="@+id/video_listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/video_imageView"
android:paddingRight="10dp" >
</ListView>
</RelativeLayout>
<RelativeLayout
android:id="@+id/video_relative_buttom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:background="@color/gray_50" >
<ImageView
android:id="@+id/video_img_last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_centerVertical="true"
android:src="@drawable/last_video_selector" />
<ImageView
android:id="@+id/video_img_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/video_img_last"
android:src="@drawable/start_video_df" />
<ImageView
android:id="@+id/video_img_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/video_img_start"
android:src="@drawable/next_video_selector" />
<ImageView
android:id="@+id/video_img_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/video_img_full"
android:src="@drawable/right_show_img" />
<ImageView
android:id="@+id/video_img_full"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="30dp"
android:src="@drawable/big_video_selector" />
<TextView
android:id="@+id/video_txt_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/video_img_next"
android:text="@string/play_time"
android:textColor="@color/white" />
<ImageView
android:id="@+id/video_videoview_pres_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_toLeftOf="@+id/video_txt_max_time"
android:layout_toRightOf="@+id/video_txt_current_time"
android:background="@drawable/video_num_bg" />
<ImageView
android:id="@+id/video_videoview_pres_front"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_toRightOf="@+id/video_txt_current_time"
android:background="@drawable/video_num_front" />
<TextView
android:id="@+id/video_txt_max_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_toLeftOf="@+id/video_img_voice"
android:text="@string/play_time"
android:textColor="@color/white" />
</RelativeLayout>
<ImageView
android:id="@+id/video_img_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/video_brightness_bg"
android:visibility="gone" />
<FrameLayout
android:id="@+id/video_frame"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_below="@+id/video_img_center"
android:layout_centerHorizontal="true"
android:layout_marginTop="-30dp"
android:visibility="gone" >
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="@drawable/video_num_bg" />
<ImageView
android:id="@+id/video_img_pres_front"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/video_num_front" />
</FrameLayout>
</RelativeLayout>
该布局的图为
在这里咱们先把显示亮度和声音的布局隐藏掉。当须要的时候在显示出来。
如今则须要自己定义一个可全屏播放的自己定义VideoView出来代码例如以下:
package com.wyw.activity;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;
public class FullVideoView extends VideoView {
public FullVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public FullVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public FullVideoView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
};
}
好,如今呢关键的部分来了。
首先呢得有滑动依据手势来区分和调节音量还是亮度或者是快进快退。
然后依据大小动态显示各自的进度条。然后呢在抬起手势中该隐藏的隐藏该初始化的初始化。播放时间呢我是用了一个延时线程,1000毫秒运行一次也就是1秒运行一次,正在播放长度大于视频总长度的话呢我就会吧当前线程给干掉。
这样就达到了时间1秒1跳的效果。我们还须要把视频长度转换成时间。
好了,说了这么多应该也几乎相同能明确大概意思了,该动真家伙了。
以下贴代码:
package com.wyw.activity;
import java.io.File;
import java.util.ArrayList;
import com.wyw.videodemo.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.ThumbnailUtils;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore.Video.Thumbnails;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
/**
* 视频播放界面
*
* @author WangYuWen
* @version 1.0
* @date 2015年3月5日
*/
public class MainActivity extends BaseActivity {
/** 右边列表控件 */
private ListView listview;
/** 右边缩放控件 */
private RelativeLayout right_relative;
/** 上一首 */
private ImageView img_last;
/** 下一首 */
private ImageView img_next;
/** 播放 */
private ImageView img_start;
/** 全屏播放 */
private ImageView img_full;
/** 加减声音 */
private ImageView img_voice;
/** 列表适配器 */
private VideoListAdapter adapter;
/** 列表集合 */
private ArrayList<VideoListBean> list;
/** 播放视频的背景图片 */
private ImageView video_img;
/** 亮度或者声音的图片 */
private ImageView img_center;
/** 调节进度 */
private ImageView img_pres_white;
/** 底部视图栏 */
private RelativeLayout buttom_relative;
private View view;
private FullVideoView video_VideoView;
/** 当前播放时间 */
private TextView txt_current_time;
/** 总时间 */
private TextView txt_max_time;
/** 当前播放进度 */
private ImageView img_white;
/** 播放进度背景 */
private ImageView img_bg;
/** 拖放进度 */
private ImageView img_center_speed;
private AudioManager mAudioManager;
/** 最大音量 */
private int mMaxVolume;
/** 当前声音 */
private int mVolume = -1;
/** 当前亮度 */
private float mBrightness = -1f;
/** 屏幕宽度 */
private int width;
/** 屏幕高度 */
private int height;
/** 手势 */
private GestureDetector mGestureDetector;
/** 视频总长度 */
private long mVideo_total_length;
/** 视频当前长度 */
private long mVideo_current_length;
/** 按下手势时的X点 */
private float downX = 0;
/** 按下手势时的Y点 */
private float downY = 0;
/** 移动手势时的Y点 */
private float moveY = 0;
/** 移动手势时的X点 */
private float moveX = 0;
/** 记录上一次移动手势时的X点 */
private float OldMoveX = 0;
/** 记录上一次移动手势时的y点 */
private float OldMoveY = 0;
/** 双数才运行(在用到的地方有具体的解释) */
private int evens = 0;
/** 是否显示全屏 */
private boolean isVH = true;
/** 是否快进了 */
private boolean isVideo = false;
/** 是否调节了音量 */
private boolean isVoice = false;
/** 是否调节了亮度 */
private boolean isBright = false;
/** 是否点击了開始播放 */
private boolean isStart = false;
/** 当前播放位置 */
private int index_position = 0;
private static final int handKey = 123;
/** 视频路径 这是视频本地路径,资源的话你们自己去找,目录有创建,*/
private String Path = Environment.getExternalStorageDirectory() + "/wywVideo/";
@Override
protected int getContentViewId() {
return R.layout.activity_video_list;
}
@SuppressWarnings("deprecation")
@Override
protected void findViews() {
img_last = (ImageView) findViewById(R.id.video_img_last);
img_start = (ImageView) findViewById(R.id.video_img_start);
img_next = (ImageView) findViewById(R.id.video_img_next);
img_full = (ImageView) findViewById(R.id.video_img_full);
img_voice = (ImageView) findViewById(R.id.video_img_voice);
video_img = (ImageView) findViewById(R.id.video_img);
img_center = (ImageView) findViewById(R.id.video_img_center);
img_pres_white = (ImageView) findViewById(R.id.video_img_pres_front);
txt_current_time = (TextView) findViewById(R.id.video_txt_current_time);
txt_max_time = (TextView) findViewById(R.id.video_txt_max_time);
img_white = (ImageView) findViewById(R.id.video_videoview_pres_front);
img_bg = (ImageView) findViewById(R.id.video_videoview_pres_bg);
img_center_speed = (ImageView) findViewById(R.id.video_img_center_speed);
video_VideoView = (FullVideoView) findViewById(R.id.video_VideoView);
view = findViewById(R.id.video_frame);
// 获取屏幕宽度
width = getWindowManager().getDefaultDisplay().getWidth();
// 获取屏幕高度
height = getWindowManager().getDefaultDisplay().getHeight();
right_relative = (RelativeLayout) findViewById(R.id.video_relative_right);
buttom_relative = (RelativeLayout) findViewById(R.id.video_relative_buttom);
// 右边试图宽度为屏幕宽度的3分之1
right_relative.getLayoutParams().width = width / 3;
listview = (ListView) findViewById(R.id.video_listview);
widgetListener();
}
@Override
protected void init() {
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
File file = new File(Path);
if (!file.exists()) {
file.mkdirs();
}
list = new ArrayList<VideoListBean>();
mGestureDetector = new GestureDetector(this, new MyGestureListener());
adapter = new VideoListAdapter(MainActivity.this, list);
listview.setAdapter(adapter);
new Thread(runnable2).start();
}
/** 点击事件 */
private void widgetListener() {
/** 列表点击事件 */
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?
> parent, View view, int position, long id) {
index_position = position;
txt_max_time.setText(R.string.play_time);
img_start.setImageResource(R.drawable.start_video_df);
video_VideoView.stopPlayback();
setVideo(position);
}
});
/** 上一首 */
img_last.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
index_position--;
if (index_position>=0) {
txt_max_time.setText(R.string.play_time);
img_start.setImageResource(R.drawable.start_video_df);
video_VideoView.stopPlayback();
setVideo(index_position);
}else{
index_position=0;
}
}
});
/** 下一首 */
img_next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
index_position++;
img_start.setImageResource(R.drawable.start_video_df);
txt_max_time.setText(R.string.play_time);
video_VideoView.stopPlayback();
setVideo(index_position);
}
});
/** 播放 */
img_start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
video_img.setVisibility(View.GONE);
if (video_VideoView.isPlaying()) {
video_VideoView.pause();
img_start.setImageResource(R.drawable.start_video_df);
} else {
mVideo_total_length = video_VideoView.getDuration();// 获取视频总长度
// 设置总时长(总长度换算成时间)
txt_max_time.setText(length2time(mVideo_total_length));
isStart = true;
video_VideoView.start();
img_start.setImageResource(R.drawable.pause_video_df);
handler.postAtTime(runnable, 0);
}
}
});
/** 全屏 */
img_full.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isVH) {
WindowManager.LayoutParams params = getWindow().getAttributes();
params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(params);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
right_relative.setVisibility(View.GONE);
buttom_relative.setVisibility(View.GONE);
isVH = false;
} else {
WindowManager.LayoutParams params = getWindow().getAttributes();
params.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(params);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
buttom_relative.setVisibility(View.VISIBLE);
isVH = true;
}
}
});
/** 是否显示右边视图点击事件 */
img_voice.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (right_relative.isShown()) {
right_relative.setVisibility(View.GONE);
} else {
right_relative.setVisibility(View.VISIBLE);
}
}
});
/** 右边视图 */
right_relative.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
right_relative.setVisibility(View.GONE);
}
});
}
private Runnable runnable2 = new Runnable() {
@Override
public void run() {
doSearch(Path);
Message message = handler.obtainMessage();
message.what = handKey;
handler.sendMessage(message);
}
};
/**
* 搜索该路径以下的全部文件
*
* @version 1.0
* @createTime 2015年3月12日,下午2:11:47
* @updateTime 2015年3月12日,下午2:11:47
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param path
*/
private void doSearch(String path) {
File file = new File(path);
if (file.exists()) {
if (file.isDirectory()) {
File[] fileArray = file.listFiles();
for (File f : fileArray) {
if (f.isDirectory()) {// 推断是否目录
// 目录为true
doSearch(f.getPath());
} else {
if (f.getName().endsWith("mp4") || f.getName().endsWith("3gp")) {
VideoListBean bean = new VideoListBean();
bean.setVideo_name(f.getName());
bean.setVideo_path(f.getAbsolutePath());
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(f.getAbsolutePath(), Thumbnails.MINI_KIND);
if (bitmap != null) {
bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() * 300 / bitmap.getHeight(), 300, true);
bean.setVideo_imgbg(bitmap);
}
list.add(bean);
}
}
}
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
// 处理手势结束
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
endGesture();
break;
}
return super.onTouchEvent(event);
}
/**
* 手势结束
*
* @version 1.0
* @createTime 2015年3月5日,上午11:36:43
* @updateTime 2015年3月5日,上午11:36:43
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void endGesture() {
if (!isVideo && !isVoice && !isBright) {
if (right_relative.isShown()) {
right_relative.setVisibility(View.GONE);
}
if (buttom_relative.isShown()) {
buttom_relative.setVisibility(View.GONE);
} else {
buttom_relative.setVisibility(View.VISIBLE);
}
}
isVideo = false;
isVoice = false;
isBright = false;
OldMoveX = 0;
OldMoveY = 0;
// 隐藏
img_center.setVisibility(View.GONE);
img_center_speed.setVisibility(View.GONE);
view.setVisibility(View.GONE);
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handKey) {
setVideo(index_position);
adapter.notifyDataSetChanged();
}
};
};
/**
* 设置Video该播放视频的准备和视频的背景图片
*
* @version 1.0
* @createTime 2015年3月12日,下午2:17:55
* @updateTime 2015年3月12日,下午2:17:55
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param position
*/
@SuppressWarnings("deprecation")
private void setVideo(int position) {
if (list.size() > position && position>-1) {
Drawable drawable = new BitmapDrawable(list.get(position).getVideo_imgbg());
video_VideoView.setVideoPath(list.get(position).getVideo_path());
video_VideoView.requestFocus();
video_img.setVisibility(View.VISIBLE);
video_img.setBackgroundDrawable(drawable);
}
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
mVideo_current_length = video_VideoView.getCurrentPosition();
if (mVideo_current_length >= mVideo_total_length) {
mVideo_current_length = mVideo_total_length;
}
/** 设置当前时长 */
txt_current_time.setText(length2time(mVideo_current_length));
/** 设置视频进度 */
LayoutParams layoutParams = (LayoutParams) img_white.getLayoutParams();
layoutParams.width = (int) (((float) img_bg.getWidth()) / mVideo_total_length * mVideo_current_length);
img_white.setLayoutParams(layoutParams);
handler.postDelayed(runnable, 1000);
if (mVideo_current_length >= mVideo_total_length) {
handler.removeCallbacks(runnable);
}
}
};
/**
* 调节音量
*
* @version 1.0
* @createTime 2015年3月5日,上午11:16:35
* @updateTime 2015年3月5日,上午11:16:35
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param num
*/
private void setVoiceNum(float num) {
evens++;//这里为什么要用个双数运行呢,由于手势滑动的太快音量仅仅有15,控制了下音量增减速度,不然略微滑动一下就到了最高或者最低这是我们用户不喜欢看到的。
mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (mVolume < 0) {
mVolume = 0;
}
if (num < 0 && evens % 2 == 0) {
mVolume -= 1;
} else if (num > 0 && evens % 2 == 0) {
mVolume += 1;
}
if (mVolume > mMaxVolume) {
mVolume = mMaxVolume;
} else if (mVolume < 0) {
mVolume = 0;
}
img_center.setImageResource(R.drawable.video_voice_bg);
img_center.setVisibility(View.VISIBLE);
view.setVisibility(View.VISIBLE);
// 变更声音
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolume, 0);
// 变更进度条
ViewGroup.LayoutParams lp = img_pres_white.getLayoutParams();
lp.width = DisplayUtils.dip2px(MainActivity.this, 100) * mVolume / mMaxVolume;
img_pres_white.setLayoutParams(lp);
}
/**
* 调节视频进度
*
* @version 1.0
* @createTime 2015年3月5日,下午4:48:07
* @updateTime 2015年3月5日,下午4:48:07
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param distanceX
*/
private void onVideoSpeed(float distanceX) {
mVideo_current_length = video_VideoView.getCurrentPosition();// 当前播放长度
if (distanceX > 0) {// 往左滑动 --
img_center_speed.setVisibility(View.VISIBLE);
img_center_speed.setImageResource(R.drawable.retreat_video);
mVideo_current_length -= 1000;// 快进之后长度
} else if (distanceX < 0) {// 往右滑动 ++
img_center_speed.setVisibility(View.VISIBLE);
img_center_speed.setImageResource(R.drawable.speed_video);
mVideo_current_length += 1000;// 快进之后长度
}
if (mVideo_current_length >= mVideo_total_length) {
mVideo_current_length = mVideo_total_length;
} else if (mVideo_current_length <= 0) {
mVideo_current_length = 0;
}
video_VideoView.seekTo((int) mVideo_current_length);
// //定位播放在哪个位置
handler.postDelayed(runnable, 0);
}
/**
* 将进度长度转变为进度时间
*
* @version 1.0
* @createTime 2015年3月5日,下午4:25:05
* @updateTime 2015年3月5日,下午4:25:05
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param length
* @return
*/
@SuppressLint("DefaultLocale")
private String length2time(long length) {
length /= 1000L;
long minute = length / 60L;
long hour = minute / 60L;
long second = length % 60L;
minute %= 60L;
return String.format("%02d:%02d:%02d", hour, minute, second);
}
/**
* 调节亮度
*
* @version 1.0
* @createTime 2015年3月5日,上午11:16:44
* @updateTime 2015年3月5日,上午11:16:44
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param percent
*/
private void onBrightnessSlide(float percent) {
WindowManager.LayoutParams lpa = getWindow().getAttributes();
mBrightness = lpa.screenBrightness;
img_center.setImageResource(R.drawable.video_brightness_bg);
img_center.setVisibility(View.VISIBLE);
view.setVisibility(View.VISIBLE);
lpa.screenBrightness = mBrightness + percent;
if (lpa.screenBrightness > 1.0f) {
lpa.screenBrightness = 1.0f;
} else if (lpa.screenBrightness < 0.01f) {
lpa.screenBrightness = 0.01f;
}
getWindow().setAttributes(lpa);
// 变更亮度进度条
ViewGroup.LayoutParams lp = img_pres_white.getLayoutParams();
lp.width = (int) (DisplayUtils.dip2px(MainActivity.this, 100) * lpa.screenBrightness);
img_pres_white.setLayoutParams(lp);
}
private class MyGestureListener extends SimpleOnGestureListener {
/** 双击 */
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
/** 滑动 */
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// e1==按下的点 e2==移动的点
downX = e1.getX();
downY = e1.getY();
moveX = e2.getX();
moveY = e2.getY();
if (OldMoveX == 0) {
OldMoveX = downX;
OldMoveY = downY;
}
if (Math.abs(moveY - downY) < Math.abs(moveX - downX) && !isVoice && !isBright && isStart) {
handler.removeCallbacks(runnable);
onVideoSpeed((OldMoveX - moveX) / width);
OldMoveX = moveX;
isVideo = true;
} else {
if (downX > width * 4 / 5 && !isVideo && !isBright) {// 右边滑动
setVoiceNum((OldMoveY - moveY) / height);
OldMoveY = moveY;
isVoice = true;
} else if (downX < width / 5 && !isVideo && !isVoice) {// 左边滑动
onBrightnessSlide((OldMoveY - moveY) / height);
OldMoveY = moveY;
isBright = true;
}
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
}
方便一些朋友写。我这里也把适配器和数据集的代码也贴进来。
首先是数据(bean):
package com.wyw.activity;
import android.graphics.Bitmap;
public class VideoListBean{
/** 视频id */
private String Video_Id;
/** 视频名字 */
private String Video_name;
/** 视频路径 */
private String Video_path;
/** 视频展示配置表-封面图URL */
private Bitmap Video_imgbg;
/** 创建时间 */
private String Create_time;
public Bitmap getVideo_imgbg() {
return Video_imgbg;
}
public void setVideo_imgbg(Bitmap video_imgbg) {
Video_imgbg = video_imgbg;
}
public String getCreate_time() {
return Create_time;
}
public void setCreate_time(String create_time) {
Create_time = create_time;
}
public String getVideo_Id() {
return Video_Id;
}
public void setVideo_Id(String video_Id) {
Video_Id = video_Id;
}
public String getVideo_name() {
return Video_name;
}
public void setVideo_name(String video_name) {
Video_name = video_name;
}
public String getVideo_path() {
return Video_path;
}
public void setVideo_path(String video_path) {
Video_path = video_path;
}
}
适配器:
package com.wyw.activity;
import java.util.ArrayList;
import com.wyw.videodemo.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class VideoListAdapter extends BaseAdapter {
private Context context;
private ArrayList<VideoListBean> list;
public VideoListAdapter(Context context,ArrayList<VideoListBean> list){
this.context=context;
this.list=list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
final VideoListBean bean = list.get(position);
if (convertView==null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_video_listview, null);
viewHolder.img_video = (ImageView) convertView.findViewById(R.id.item_video_img);
viewHolder.txt_name = (TextView) convertView.findViewById(R.id.item_video_txt_name);
viewHolder.txt_time = (TextView) convertView.findViewById(R.id.item_video_txt_time);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txt_name.setText(bean.getVideo_name());
viewHolder.img_video.setImageBitmap(bean.getVideo_imgbg());
viewHolder.txt_time.setText(DateUtils.getDay());
return convertView;
}
private class ViewHolder{
/**视频图片*/
private ImageView img_video;
/**视频名字*/
private TextView txt_name;
/**视频时间*/
private TextView txt_time;
}
}
隐藏各个控件我认为应该要有动画才好看。这个就交给你们延伸了。下次呢我会加上动画以及研究下在线播放解码之类的。
希望大家多多关注我的博客。多多支持我。
如有好意见或更好的方式欢迎留言谈论。
尊重原创转载请注明:(http://blog.csdn.net/u013895206) 侵权必究!
以下是地址传送门:
http://download.csdn.net/detail/u013895206/8494817
android 自己定义视频播放器之2/1的更多相关文章
- android实现控制视频播放次数
android实现控制视频播放次数,实质就是每个视频片段播放完后,通过MediaPlayer设置监听器setOnCompletionListener监听视频播放完毕,用Handler发送消息再次激活视 ...
- Android自己定义DataTimePicker(日期选择器)
Android自己定义DataTimePicker(日期选择器) 笔者有一段时间没有发表关于Android的文章了,关于Android自己定义组件笔者有好几篇想跟大家分享的,后期会记录在博客中.本篇 ...
- Android UI--自定义ListView(实现下拉刷新+加载更多)
Android UI--自定义ListView(实现下拉刷新+加载更多) 关于实现ListView下拉刷新和加载更多的实现,我想网上一搜就一堆.不过我就没发现比较实用的,要不就是实现起来太复杂,要不就 ...
- Android自己定义组件系列【7】——进阶实践(4)
上一篇<Android自己定义组件系列[6]--进阶实践(3)>中补充了关于Android中事件分发的过程知识.这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpa ...
- ANDROID自己定义视图——onLayout源代码 流程 思路具体解释
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 在自己定义view的时候.事实上非常easy.仅仅须要知道3步骤: 1.測量- ...
- Android 自己定义View (二) 进阶
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自己定义View之旅.前面已经介绍过一个自己定义View的基础 ...
- Android 自己定义ScrollView ListView 体验各种纵向滑动的需求
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38950509.本文出自[张鸿洋的博客] 1.概述 群里的一个哥们有个需求是这种: ...
- Android自己定义控件系列五:自己定义绚丽水波纹效果
尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自己定义控件实现一个比較有趣的效果 ...
- Android几种视频播放方式,VideoView、SurfaceView+MediaPlayer、TextureView+MediaPlayer,以及主流视频播放器开源项目
简单的说下一Android的几种视频播放功能: 1.VideoView:最简单的视频播放 <FrameLayout xmlns:android="http://schemas.andr ...
随机推荐
- 读取csv文件并打印其结果
In [5]: import pandas as pd In [6]: df=pd.read_csv('https://raw.githubusercontent.com/alstat/Analysi ...
- SpringBoot中mybatis配置自动转换驼峰标识没有生效
mybatis提供了一个配置: #开启驼峰命名转换 mybatis.configuration.map-underscore-to-camel-case=true 使用该配置可以让mybatis自动将 ...
- mysql字符生命周期
mysql的字符集,对数据的导入导出很关键,明白自己集在不同阶段不同场景下的意义即为重要! 01.查看mysql当前字符集 show variables like '%cahr%'; 02.用户请求m ...
- Nginx 日志改成 JSON 格式
Nginx 日志默认为普通文本的格式,例如,下面是 Nginx 的一行访问日志: 10.88.122.105 - - [02/Dec/2017:09:15:04 +0800] "GET /j ...
- Linux-LVS为何不能完全替代DNS轮询
转自:链接 上一篇文章“一分钟了解负载均衡的一切”引起了不少同学的关注,评论中大家争论的比较多的一个技术点是接入层负载均衡技术,部分同学持这样的观点: 1)nginx前端加入lvs和keepalive ...
- Emacs的sr-speedbar中使能Go-mode
sr-speedbar使用了speedbar的文件检索功能,但是Emacs24自带的speedbar不支持go文件预览,下面是在speedbar中使能go-mode的一种方法: 1,按F10启动菜单栏 ...
- HTTP 接口响应数据解析
转自:https://blog.csdn.net/hubanbei2010/article/details/79878567 作为产品线的支撑角色QA/CI/CD等,http api解析是互联网公司中 ...
- Seqlite学习
之前没有接触过数据库编程,尼玛,面试神码的最恶心了,非得神码都懂点,好吧,最近开始研究下,先从SQLite开始吧,贴上找到SQliteDB.之后搜集资料,慢慢学习!
- React(0.13) 定义一个input组件,使其输入的值转为大写
<!DOCTYPE html> <html> <head> <title>React JS</title> <script src=& ...
- numpy中的np.random.mtrand.RandomState
1 RandomState 的应用场景概述 在训练神经网络时,苦于没有数据,此时numpy为我们提供了 “生产” 数据集的一种方式. 例如在搭建神经网络(一)中的 4.3 准备数据集 章节中就是采用n ...