最近在做一款视频剪辑的app时,功能中会有视频时长剪切,需要选取视频的一块时长然后进行剪切。于是自定义了一个时长剪切View,下面简单分享下心得:
目录
1.明确需求
自定义View的大致效果
功能:
1)左右可以拖动伸缩
2)左边的拖动条不可超出右边的拖动条
3)未选中区域暗黑显示
4)左右拖动条上方动态显示相应的时间
自定义View的适用范围
当前自定义View,适用于任何目标View的时长剪切。
2.代码设计
模型构建
由上面的效果图,可以将自定义View划分成6个部分:左遮罩、右遮罩、上下边框线、中间选择区域、左拖动条、右拖动条。
设计历程:最开始研究时长剪切这个功能的时候,总将预览帧列表与剪切耦合到一起。参照https://www.jianshu.com/p/55dcb62ca0b3
这篇文章的思路才设计出这个View。
上代码
根据我的上篇博客https://www.jianshu.com/p/51fe99e9eb70的套路:
1)定义画笔
private Paint markPaint = new Paint(); //遮罩绘制器
private Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //边框绘制器
private Paint handleThumbPaint; //拖动条绘制器
... //定义画笔的属性
2)定义一些参数变量
包括画笔的宽度、遮罩、边框、拖动条的宽度、整体实际绑定的值。
- 整体实际绑定的值
一般是100,但是用户也可以自行设定。
3)作画
在onDraw方法中,绘制左遮罩、右遮罩、上下边框线、中间选择区域、左拖动条、右拖动条。
注意这里的拖动条是绘制的图片,调用
```canvas.drawBitmap```方法。
4)动画
定义拖动目标的枚举类型:
public enum TouchHandle {
LEFT, //左边拖动条
RIGHT, //右边拖动条
CENTER, //中间进度拖动条
NONE //无任何拖动目标
}
在onTouchEvent方法的MotionEvent.ACTION_DOWN方法里,根据x、y判断触摸区域,定义找到拖动目标。
在onTouchEvent方法的MotionEvent.ACTION_MOVE里,根据触摸目标和位移,调用invalidate()方法,从而刷新onDraw方法,并且将参数回传。
5)添加监听
/**
* 拖动选择后的结果
*/
public interface OnRankListener{
void onRank(TouchHandle touchHandle,float startValue,float endValue,float selectValue,float startX,float endX,float rightX);
}
监听拖动结果的实际值与坐标值,给出坐标值是为了在外部动态的改变时间View的位置(这里我就没有将时间画出来了,这样会增加这个View的复杂度。)
3.如何使用这个View
布局,保持和目标View同高。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
>
<com.camnter.easyrecyclerview.widget.EasyRecyclerView
android:id="@+id/erv_images"
android:layout_width="match_parent"
android:layout_height="@dimen/rank_bar_height"
/>
<com.cz.pro1mediaeditmagichand.view.cut.RankBar
android:id="@+id/rank_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/rank_bar_height"/>
</FrameLayout>
rankBar.setFillValue(mediaDetailBean.getDuration());
rankBar.setMinSelectValue(MIN_CUT_DURATION);
rankBar.setOnRankListener();
4.取预览帧
自定义View的功能完成了,但是时长剪切的整体功能并没有完成。
1)取预览帧
参照https://www.jianshu.com/p/55dcb62ca0b3可以将预览帧取出来
2)确定预览帧的个数
https://www.jianshu.com/p/55dcb62ca0b3的方法,我看得不是很明白,就自己写了一个算法:
这样就能保证视频的帧数均匀的分布在列表上
/**
* 根据分段函数,2元一次方程,来合理分配帧数。(用数学,用理性的思维来解决问题。)
帧数(y)
*
30 ###########
* #
* #
10 ##########
*
*
* **********10****120***************************** 时长(x)
* @return
*/
private int getThumbsCount(){
long duration = mediaDetailBean.getDuration();
if(duration < 10*1000){
return 10;
}else if(duration >= 10*1000 && duration <= 120*1000){
return (int) ((2.0/11) * duration/1000f + 90.0/11);
}else{
return 30;
}
}
# 源码:
如有疑惑或者好的建议,或者想纠正作者的博文,请联系如下
公众号:微信公众号搜索“修符道人”或者扫描下方二维码
微信号:XinYi1349308479
QQ邮箱:1349308479@qq.com
0 条评论