需求分析:
1.读取本地里所有的音频文件
2.使用MediaPlayer进行音频播放
3.对音频文件进行剪辑,截取想要的音频片段,可以试听
我做出来的效果图如下:
Demo源代码的下载地址:
https://download.csdn.net/download/qq15577969/10670076
一、先在AndroidManifest.xml清单文件里添加需要的权限
<!-- 允许程序设置内置sd卡的写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 这个权限用于读取音频 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
首先提供一些重要xml布局文件的代码给大家:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainActivity_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="16dp"
android:text="本地音乐" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:alpha="0.3"
android:background="#666" />
<ListView
android:id="@+id/music_listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</ListView>
</LinearLayout>
music_cut_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_circle_dialog_bg"
android:orientation="vertical"
android:paddingTop="30dp"
android:paddingBottom="10dp"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/popupWindow_music_cut_tv_musicName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="歌手 - 歌名.mp3"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/popupWindow_music_cut_tv_musicName"
android:layout_centerHorizontal="true"
android:paddingTop="15dp"
android:text="拖动滑块来剪辑音乐"
android:textColor="#999"
android:textSize="12sp" />
</RelativeLayout>
<TextView
android:id="@+id/popupWindow_music_cut_tv_delta_rule"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="已截取0秒"
android:visibility="gone"
android:textSize="12sp"
android:textColor="#999" />
<com.t20.audiodemo.view.DoubleSlideSeekBar
android:id="@+id/popupWindow_music_cut_doubleSlideSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:equal="1"
custom:hasRule="false"
custom:imageBig="@drawable/green_ball"
custom:imageLow="@drawable/grey_ball"
custom:imageheight="20dp"
custom:imagewidth="20dp"
custom:inColor="#B7D54E"
custom:lineHeight="3dp"
custom:outColor="#C3CBC9"
custom:ruleColor="#0e0e0e"
custom:ruleLineHeight="10dp"
custom:ruleTextColor="#f74104"
custom:ruleTextSize="6sp"
custom:textColor="#DE5B78"
custom:textSize="12sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/popupWindow_music_cut_tv_musicTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:paddingBottom="15dp"
android:textSize="10sp"
android:textColor="#3D91FE"
android:drawableLeft="@drawable/music_audio_test"
android:drawablePadding="2dp"
android:text="点击试听一下" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/popupWindow_music_cut_tv_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:alpha="0.7"
android:text="|"
android:textColor="#C3CBC9"
android:textSize="18sp"
android:typeface="serif" />
<Button
android:id="@+id/popupWindow_music_cut_btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="@id/popupWindow_music_cut_tv_line"
android:background="@null"
android:text="取消"
android:textColor="#666"
android:textSize="16sp" />
<Button
android:id="@+id/popupWindow_music_cut_btn_sure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/popupWindow_music_cut_tv_line"
android:background="@null"
android:text="确定"
android:textColor="#DE5B78"
android:textSize="16sp" />
</RelativeLayout>
</LinearLayout>
music_listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp" >
<FrameLayout
android:layout_width="60dp"
android:layout_height="60dp" >
<ImageView
android:id="@+id/music_iv_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/selector_music_play_pic" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/music_iv_play"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:alpha="0.7"
android:background="@drawable/shape_play_button_background"
android:src="@drawable/music_play" />
</RelativeLayout>
</FrameLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingLeft="5dp" >
<TextView
android:id="@+id/music_tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="歌曲"
android:textColor="#666"
android:textSize="13sp"
android:textStyle="bold" />
<TextView
android:id="@+id/music_tv_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="3dp"
android:text="歌手"
android:textColor="#999"
android:textSize="12sp" />
<TextView
android:id="@+id/music_tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="3dp"
android:text="00:00"
android:textColor="#999"
android:textSize="12sp" />
</LinearLayout>
<ImageView
android:id="@+id/music_iv_cut"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:src="@drawable/music_cut" />
</LinearLayout>
二、重写View ,实现一个可以双向滑动的SeekBar控件
DoubleSlideSeekBar.java
package com.t20.audiodemo.view;
import com.t20.audiodemo.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
/**
* 双向滑动SeekBar
* @author admin
*
*/
/**
* @author admin
*
*/
public class DoubleSlideSeekBar extends View {
/**
* 线条(进度条)的宽度
*/
private int lineWidth;
/**
* 线条(进度条)的长度
*/
private int lineLength=getWidth();
/**
* 字所在的高度
*/
private int textHeight;
/**
* 游标 图片宽度
*/
private int imageWidth;
/**
* 游标 图片高度
*/
private int imageHeight;
/**
* 是否有刻度线
*/
private boolean hasRule;
/**
* 左边的游标是否在动
*/
private boolean isLowerMoving;
/**
* 右边的游标是否在动
*/
private boolean isUpperMoving;
/**
* 字的大小
*/
private int textSize;
/**
* 字的颜色
*/
private int textColor;
/**
* 两个游标内部 线(进度条)的颜色
*/
private int inColor = Color.BLUE;
/**
* 两个游标外部 线(进度条)的颜色
*/
private int outColor = Color.BLUE;
/**
* 刻度的颜色
*/
private int ruleColor = Color.BLUE;
/**
* 刻度上边的字 的颜色
*/
private int ruleTextColor = Color.BLUE;
/**
* 左边图标的图片
*/
private Bitmap bitmapLow;
/**
* 右边图标 的图片
*/
private Bitmap bitmapBig;
/**
* 左边图标所在X轴的位置
*/
private int slideLowX;
/**
* 右边图标所在X轴的位置
*/
private int slideBigX;
/**
* 图标(游标) 高度
*/
private int bitmapHeight;
/**
* 图标(游标) 宽度
*/
private int bitmapWidth;
/**
* 加一些padding 大小酌情考虑 为了我们的自定义view可以显示完整
*/
private int paddingLeft = 30;
private int paddingRight = 30;
private int paddingTop = 10;
private int paddingBottom = 10;
/**
* 线(进度条) 开始的位置
*/
private int lineStart = paddingLeft;
/**
* 线的Y轴位置
*/
private int lineY;
/**
* 线(进度条)的结束位置
*/
private int lineEnd = lineLength + paddingLeft;
/**
* 选择器的最大值
*/
private int bigValue = 100;
/**
* 选择器的最小值
*/
private int smallValue = 0;
/**
* 选择器的当前最小值
*/
private float smallRange;
/**
* 选择器的当前最大值
*/
private float bigRange;
/**
* 单位 元
*/
private String unit = " ";
/**
* 单位份数
*/
private int equal = 20;
/**
* 刻度单位 $
*/
private String ruleUnit = " ";
/**
* 刻度上边文字的size
*/
private int ruleTextSize = 20;
/**
* 刻度线的高度
*/
private int ruleLineHeight = 20;
private Paint linePaint;
private Paint bitmapPaint;
private Paint textPaint;
private Paint paintRule;
public DoubleSlideSeekBar(Context context) {
this(context, null);
}
public DoubleSlideSeekBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DoubleSlideSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DoubleSlideSeekBar, defStyleAttr, 0);
int size = typedArray.getIndexCount();
for (int i = 0; i < size; i++) {
int type = typedArray.getIndex(i);
switch (type) {
case R.styleable.DoubleSlideSeekBar_inColor:
inColor = typedArray.getColor(type, Color.BLACK);
break;
case R.styleable.DoubleSlideSeekBar_lineHeight:
lineWidth = (int) typedArray.getDimension(type, dip2px(getContext(), 10));
break;
case R.styleable.DoubleSlideSeekBar_outColor:
outColor = typedArray.getColor(type, Color.YELLOW);
break;
case R.styleable.DoubleSlideSeekBar_textColor:
textColor = typedArray.getColor(type, Color.BLUE);
break;
case R.styleable.DoubleSlideSeekBar_textSize:
textSize = typedArray.getDimensionPixelSize(type, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
case R.styleable.DoubleSlideSeekBar_imageLow:
bitmapLow = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(type, 0));
break;
case R.styleable.DoubleSlideSeekBar_imageBig:
bitmapBig = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(type, 0));
break;
case R.styleable.DoubleSlideSeekBar_imageheight:
imageHeight = (int) typedArray.getDimension(type, dip2px(getContext(), 20));
break;
case R.styleable.DoubleSlideSeekBar_imagewidth:
imageWidth = (int) typedArray.getDimension(type, dip2px(getContext(), 20));
break;
case R.styleable.DoubleSlideSeekBar_hasRule:
hasRule = typedArray.getBoolean(type, false);
break;
case R.styleable.DoubleSlideSeekBar_ruleColor:
ruleColor = typedArray.getColor(type, Color.BLUE);
break;
case R.styleable.DoubleSlideSeekBar_ruleTextColor:
ruleTextColor = typedArray.getColor(type, Color.BLUE);
break;
case R.styleable.DoubleSlideSeekBar_unit:
unit = typedArray.getString(type);
break;
case R.styleable.DoubleSlideSeekBar_equal:
equal = typedArray.getInt(type, 10);
break;
case R.styleable.DoubleSlideSeekBar_ruleUnit:
ruleUnit = typedArray.getString(type);
break;
case R.styleable.DoubleSlideSeekBar_ruleTextSize:
ruleTextSize = typedArray.getDimensionPixelSize(type, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
case R.styleable.DoubleSlideSeekBar_ruleLineHeight:
ruleLineHeight = (int) typedArray.getDimension(type, dip2px(getContext(), 10));
break;
case R.styleable.DoubleSlideSeekBar_bigValue:
bigValue = typedArray.getInteger(type, 100);
break;
case R.styleable.DoubleSlideSeekBar_smallValue:
smallValue = typedArray.getInteger(type, 100);
break;
default:
break;
}
}
typedArray.recycle();
init();
}
private void init() {
/**游标的默认图*/
if (bitmapLow == null) {
bitmapLow = BitmapFactory.decodeResource(getResources(), R.drawable.grey_ball);
}
if (bitmapBig == null) {
bitmapBig = BitmapFactory.decodeResource(getResources(), R.drawable.green_ball);
}
/**游标图片的真实高度 之后通过缩放比例可以把图片设置成想要的大小*/
bitmapHeight = bitmapLow.getHeight();
bitmapWidth = bitmapLow.getWidth();
// 设置想要的大小
int newWidth = imageWidth;
int newHeight = imageHeight;
// 计算缩放比例
float scaleWidth = ((float) newWidth) / bitmapWidth;
float scaleHeight = ((float) newHeight) / bitmapHeight;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
/**缩放图片*/
bitmapLow = Bitmap.createBitmap(bitmapLow, 0, 0, bitmapWidth, bitmapHeight, matrix, true);
bitmapBig = Bitmap.createBitmap(bitmapBig, 0, 0, bitmapWidth, bitmapHeight, matrix, true);
/**重新获取游标图片的宽高*/
bitmapHeight = bitmapLow.getHeight();
bitmapWidth = bitmapLow.getWidth();
/**初始化两个游标的位置*/
slideLowX = lineStart;
slideBigX = lineEnd;
smallRange = smallValue;
bigRange = bigValue;
if (hasRule) {
//有刻度时 paddingTop 要加上(text高度)和(刻度线高度加刻度线上边文字的高度和) 之间的最大值
paddingTop = paddingTop + Math.max(textSize, ruleLineHeight + ruleTextSize);
} else {
//没有刻度时 paddingTop 加上 text的高度
paddingTop = paddingTop + textSize;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getMyMeasureWidth(widthMeasureSpec);
int height = getMyMeasureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int getMyMeasureHeight(int heightMeasureSpec) {
int mode = MeasureSpec.getMode(heightMeasureSpec);
int size = MeasureSpec.getSize(heightMeasureSpec);
if (mode == MeasureSpec.EXACTLY) {
// matchparent 或者 固定大小 view最小应为 paddingBottom + paddingTop + bitmapHeight + 10 否则显示不全
size = Math.max(size, paddingBottom + paddingTop + bitmapHeight + 10);
} else {
//wrap content
int height = paddingBottom + paddingTop + bitmapHeight + 10;
size = Math.min(size, height);
}
return size;
}
private int getMyMeasureWidth(int widthMeasureSpec) {
int mode = MeasureSpec.getMode(widthMeasureSpec);
int size = MeasureSpec.getSize(widthMeasureSpec);
if (mode == MeasureSpec.EXACTLY) {
size = Math.max(size, paddingLeft + paddingRight + bitmapWidth * 2);
} else {
//wrap content
int width = paddingLeft + paddingRight + bitmapWidth * 2;
size = Math.min(size, width);
}
// match parent 或者 固定大小 此时可以获取线(进度条)的长度
lineLength = size - paddingLeft - paddingRight - bitmapWidth;
//线(进度条)的结束位置
lineEnd = lineLength + paddingLeft + bitmapWidth / 2;
//线(进度条)的开始位置
lineStart = paddingLeft + bitmapWidth / 2;
//初始化 游标位置
slideBigX = lineEnd;
slideLowX = lineStart;
return size;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Y轴 坐标
lineY = getHeight() - paddingBottom - bitmapHeight / 2;
// 字所在高度 100$
textHeight = lineY - bitmapHeight / 2 - 10;
//是否画刻度
if (hasRule) {
drawRule(canvas);
}
if (linePaint == null) {
linePaint = new Paint();
}
//画内部线
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth(lineWidth);
linePaint.setColor(inColor);
linePaint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(slideLowX, lineY, slideBigX, lineY, linePaint);
linePaint.setColor(outColor);
linePaint.setStrokeCap(Paint.Cap.ROUND);
//画 外部线
canvas.drawLine(lineStart, lineY, slideLowX, lineY, linePaint);
canvas.drawLine(slideBigX, lineY, lineEnd, lineY, linePaint);
//画游标
if (bitmapPaint == null) {
bitmapPaint = new Paint();
}
canvas.drawBitmap(bitmapLow, slideLowX - bitmapWidth / 2, lineY - bitmapHeight / 2, bitmapPaint);
canvas.drawBitmap(bitmapBig, slideBigX - bitmapWidth / 2, lineY - bitmapHeight / 2, bitmapPaint);
//画 游标上边的字
if (textPaint == null) {
textPaint = new Paint();
}
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
textPaint.setAntiAlias(true);
canvas.drawText(String.format("%.0f" + unit, smallRange), slideLowX - bitmapWidth / 2, textHeight, textPaint);
canvas.drawText(String.format("%.0f" + unit, bigRange), slideBigX - bitmapWidth / 2, textHeight, textPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//事件机制
super.onTouchEvent(event);
float nowX = event.getX();
float nowY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//按下 在游标范围上
boolean rightY = Math.abs(nowY - lineY) < bitmapHeight / 2;
//按下 在左边游标上
boolean lowSlide = Math.abs(nowX - slideLowX) < bitmapWidth / 2;
//按下 在右边游标上
boolean bigSlide = Math.abs(nowX - slideBigX) < bitmapWidth / 2;
if (rightY && lowSlide) {
isLowerMoving = true;
} else if (rightY && bigSlide) {
isUpperMoving = true;
//点击了游标外部 的线上
} else if (nowX >= lineStart && nowX <= slideLowX - bitmapWidth / 2 && rightY) {
slideLowX = (int) nowX;
updateRange();
postInvalidate();
} else if (nowX <= lineEnd && nowX >= slideBigX + bitmapWidth / 2 && rightY) {
slideBigX = (int) nowX;
updateRange();
postInvalidate();
}
break;
case MotionEvent.ACTION_MOVE:
//左边游标是运动状态
if (isLowerMoving) {
//当前 X坐标在线上 且在右边游标的左边
if (nowX <= slideBigX - bitmapWidth && nowX >= lineStart - bitmapWidth / 2) {
slideLowX = (int) nowX;
if (slideLowX < lineStart) {
slideLowX = lineStart;
}
//更新进度
updateRange();
postInvalidate();
}
} else if (isUpperMoving) {
//当前 X坐标在线上 且在左边游标的右边
if (nowX >= slideLowX + bitmapWidth && nowX <= lineEnd + bitmapWidth / 2) {
slideBigX = (int) nowX;
if (slideBigX > lineEnd) {
slideBigX = lineEnd;
}
//更新进度
updateRange();
postInvalidate();
}
}
break;
//手指抬起
case MotionEvent.ACTION_UP:
isUpperMoving = false;
isLowerMoving = false;
break;
default:
break;
}
return true;
}
private void updateRange() {
//当前 左边游标数值
smallRange = computRange(slideLowX);
//当前 右边游标数值
bigRange = computRange(slideBigX);
//接口 实现值的传递
if (onRangeListener != null) {
onRangeListener.onRange(smallRange, bigRange);
}
}
/**
* 获取当前值
*/
private float computRange(float range) {
return (range - lineStart) * (bigValue - smallValue) / lineLength + smallValue;
}
public int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 画刻度
*/
protected void drawRule(Canvas canvas) {
if (paintRule == null) {
paintRule = new Paint();
}
paintRule.setStrokeWidth(1);
paintRule.setTextSize(ruleTextSize);
paintRule.setTextAlign(Paint.Align.CENTER);
paintRule.setAntiAlias(true);
//遍历 equal份,画刻度
for (int i = smallValue; i <= bigValue; i += (bigValue - smallValue) / equal) {
float degX = lineStart + i * lineLength / (bigValue - smallValue);
int degY = lineY - ruleLineHeight;
paintRule.setColor(ruleColor);
canvas.drawLine(degX, lineY, degX, degY, paintRule);
paintRule.setColor(ruleTextColor);
canvas.drawText(String.valueOf(i) + ruleUnit, degX, degY, paintRule);
}
}
/**
* 写个接口 用来传递最大最小值
*/
public interface onRangeListener {
void onRange(float low, float big);
}
private onRangeListener onRangeListener;
public void setOnRangeListener(DoubleSlideSeekBar.onRangeListener onRangeListener) {
this.onRangeListener = onRangeListener;
}
//设置选择器的最大值
public void setBigValue(int bigValue) {
this.bigValue = bigValue;
}
//设置选择器的最当最大值
public void setBigRange(float bigRange) {
this.bigRange = bigRange;
}
}
上面的DoubleSlideSeekBar需要在res/values/下新建一个attrs.xml ,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--线(进度条)宽度-->
<attr name="lineHeight" format="dimension" />
<!--字的大小-->
<attr name="textSize" format="dimension" />
<!--字的颜色-->
<attr name="textColor" format="color" />
<!--两个游标内部 线(进度条)的颜色-->
<attr name="inColor" format="color" />
<!--两个游标外部 线(进度条)的颜色-->
<attr name="outColor" format="color" />
<!--左边图标的图片-->
<attr name="imageLow" format="reference"/>
<!--右边图标 的图片-->
<attr name="imageBig" format="reference"/>
<!--游标 图片宽度-->
<attr name="imagewidth" format="dimension" />
<!--游标 图片高度-->
<attr name="imageheight" format="dimension" />
<!--是否有刻度线-->
<attr name="hasRule" format="boolean" />
<!--刻度的颜色-->
<attr name="ruleColor" format="color" />
<!--刻度上边的字 的颜色-->
<attr name="ruleTextColor" format="color" />
<!--单位 元-->
<attr name="unit" format="string"/>
<!--单位份数-->
<attr name="equal" format="integer"/>
<!--刻度单位 $-->
<attr name="ruleUnit" format="string"/>
<!--刻度上边文字的size-->
<attr name="ruleTextSize" format="dimension" />
<!--刻度线的高度-->
<attr name="ruleLineHeight" format="dimension" />
<!--选择器的最大值-->
<attr name="bigValue" format="integer"/>
<!--选择器的最小值-->
<attr name="smallValue" format="integer"/>
<declare-styleable name="DoubleSlideSeekBar">
<attr name="lineHeight" />
<attr name="textSize" />
<attr name="textColor" />
<attr name="inColor" />
<attr name="outColor" />
<attr name="imageLow"/>
<attr name="imageBig"/>
<attr name="imagewidth" />
<attr name="imageheight" />
<attr name="hasRule" />
<attr name="ruleColor" />
<attr name="ruleTextColor" />
<attr name="unit" />
<attr name="equal" />
<attr name="ruleUnit" />
<attr name="ruleTextSize" />
<attr name="ruleLineHeight" />
<attr name="bigValue" />
<attr name="smallValue" />
</declare-styleable>
<!--
xml属性 值 解释
lineHeight dimension 控制我们线(进度条)的宽(高)度(例20dp)
textSize dimension 游标上边字的大小(例16sp)
textColor color 游标上边字的颜色 (例#e40627)
inColor color 两个游标之间进度条的颜色 (例#e40627)
outColor color 两个游标外部(游标到进度条两端)进度条的颜色 (例#e40627)
imageLow reference 左边游标的图片 (例@mipmap/imgv_slide)
imageBig reference 右边游标的图片 (例@mipmap/imgv_slide)
imagewidth dimension 游标图片的宽度 (例20dp)
imagewidth dimension 游标图片的高度 (例20dp)
hasRule boolean 是否有刻度线(例 true or false)
ruleColor color 刻度线的颜色 (例#e40627)
ruleTextColor color 刻度线上边的字的颜色 (例#e40627)
unit string 单位 (例 元)
equal integer 单位份数,把全部数据分成equal份(例smallValue是0,bigValue是100,equal是10,则每个刻度大小为(100-0)/10 =10)
ruleUnit string 刻度上边文字的单位 (例 $)
ruleTextSize dimension 刻度上边文字的大小 (例20sp)
ruleLineHeight dimension 刻度线高度(例16dp)
bigValue integer 选择器的最大值 (例 100)
smallValue integer 选择器的最小值 (例 0)
-->
</resources>
三、剪辑窗口使用的是PopupWindow弹出窗,因此需要自定义一个MusicCutPopupWindow.java
package com.t20.audiodemo.view;
import com.t20.audiodemo.R;
import android.app.ActionBar.LayoutParams;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;
public class MusicCutPopupWindow extends PopupWindow {
private Button mButtonCancel; //取消按钮
private Button mButtonSure; //确定按钮
private DoubleSlideSeekBar mDoubleSlideSeekBar; //自定义的双向滑杆进度条
private TextView mTextViewName; //音乐名称
private TextView mTextViewDeltaRule;//差值
private TextView mTextViewMusicTest;//试听按钮
private View mMenuView;
private float minRule=0;
private float maxRule=0;
public float getMinRule() {
return minRule;
}
public void setMinRule(float minRule) {
this.minRule = minRule;
}
public float getMaxRule() {
return maxRule;
}
public void setMaxRule(float maxRule) {
this.maxRule = maxRule;
}
public MusicCutPopupWindow(Context context,OnClickListener itemsOnClick) {
super(context);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMenuView = inflater.inflate(R.layout.music_cut_dialog, null);
mButtonCancel = (Button) mMenuView.findViewById(R.id.popupWindow_music_cut_btn_cancel);
mButtonSure = (Button) mMenuView.findViewById(R.id.popupWindow_music_cut_btn_sure);
mDoubleSlideSeekBar=(DoubleSlideSeekBar) mMenuView.findViewById(R.id.popupWindow_music_cut_doubleSlideSeekBar);
mTextViewDeltaRule= (TextView) mMenuView.findViewById(R.id.popupWindow_music_cut_tv_delta_rule);
mTextViewName=(TextView) mMenuView.findViewById(R.id.popupWindow_music_cut_tv_musicName);
mTextViewMusicTest=(TextView) mMenuView.findViewById(R.id.popupWindow_music_cut_tv_musicTest);
/* //取消按钮
mButtonCancel.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//销毁弹出框
dismiss();
}
});*/
//滑动控件
mDoubleSlideSeekBar.setOnRangeListener(new DoubleSlideSeekBar.onRangeListener() {
@Override
public void onRange(float low, float big) {
minRule=low;
maxRule=big;
float delta=big-low;
mTextViewDeltaRule.setVisibility(View.VISIBLE);
mTextViewDeltaRule.setText("已截取" + String.format("%.0f" , delta)+"秒");
}
});
//设置按钮监听
mButtonCancel.setOnClickListener(itemsOnClick);
mButtonSure.setOnClickListener(itemsOnClick);
mTextViewMusicTest.setOnClickListener(itemsOnClick);
//设置SelectPicPopupWindow的View
this.setContentView(mMenuView);
//设置SelectPicPopupWindow弹出窗体的宽
this.setWidth(LayoutParams.FILL_PARENT);
//设置SelectPicPopupWindow弹出窗体的高
this.setHeight(LayoutParams.WRAP_CONTENT);
//设置SelectPicPopupWindow弹出窗体可点击
this.setFocusable(true);
//设置窗口外也能点击(点击外面时,窗口可以关闭)
this.setOutsideTouchable(true);
//设置SelectPicPopupWindow弹出窗体动画效果
this.setAnimationStyle(R.style.circleDialog);
//实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0x00000000);
//设置SelectPicPopupWindow弹出窗体的背景
this.setBackgroundDrawable(dw);
}
/**
* 设置音乐信息
* @param name
* @param duration
*/
public void setMusicInfo(String name,long duration){
mTextViewName.setText(name);
int big=Integer.parseInt(String.valueOf(duration/1000));
mDoubleSlideSeekBar.setBigValue(big);
mDoubleSlideSeekBar.setBigRange(big);
maxRule=big;
}
}
四、另外要写2个工具类:MusicPlayer用来播放音乐,MusicUtil用来剪辑音乐
MusicPlayer.java
package com.t20.audiodemo.util;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
/**
* 音乐播放器
* @author admin
*
*/
public class MusicPlayer {
//多媒体播放器
private static MediaPlayer mediaPlayer;
public static MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
public static void setMediaPlayer(MediaPlayer mediaPlayer) {
MusicPlayer.mediaPlayer = mediaPlayer;
}
//当歌曲播放到结束位置时,使用Handler来停止播放
public static long endProgress=0;//结束进度
public static Handler handler = new Handler();
public static Runnable run = new Runnable() {
public void run() {
if(endProgress!=0){
if(MusicPlayer.getMediaPlayer().isPlaying()&&MusicPlayer.getMediaPlayer().getCurrentPosition()>=endProgress){
MusicPlayer.reset();
handler.removeCallbacks(run);
}
handler.postDelayed(run, 1000);
}
}
};
/**
* 播放
*/
public static void play(Context context,String path,final int progress){
if(mediaPlayer==null){
//初始化
mediaPlayer=new MediaPlayer();
}
//重置音乐
if(mediaPlayer.isPlaying()){
mediaPlayer.reset();
}
try {
mediaPlayer.setDataSource(path);
//让MediaPlayer进入到准备状态
mediaPlayer.prepareAsync();
//播放音乐
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
if(progress!=0){
mediaPlayer.seekTo(progress);
}
mediaPlayer.start();
//循环播放
mediaPlayer.setLooping(true);
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 播放(一般用于暂停后重新播放)
*/
public static void reStart(){
if(mediaPlayer!=null){
mediaPlayer.start();
}
}
/**
* 暂停
*/
public static void pause(){
if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
}
/**
* 停止
*/
public static void stop(){
if(handler!=null){
handler.removeCallbacks(run);
}
if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}
}
/**
* 重置
*/
public static void reset(){
if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
mediaPlayer.reset();
}
}
}
MusicUtil.java
package com.t20.audiodemo.util;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import android.annotation.SuppressLint;
import android.media.MediaExtractor;
import android.media.MediaFormat;
/**
* 剪切mp3音乐的工具类
* @author admin
*
*/
public class MusicUtil {
//适当的调整SAMPLE_SIZE可以更加精确的裁剪音乐
private static final int SAMPLE_SIZE = 1024*200;
@SuppressLint("InlinedApi")
public static boolean clipMp3(String inputPath, String outputPath, int start, int end){
MediaExtractor extractor = null;
BufferedOutputStream outputStream = null;
try {
extractor = new MediaExtractor();
extractor.setDataSource(inputPath);
int track = getAudioTrack(extractor);
if(track < 0){
return false;
}
//选择音频轨道
extractor.selectTrack(track);
outputStream = new BufferedOutputStream(
new FileOutputStream(outputPath), SAMPLE_SIZE);
start = start * 1000;
end = end * 1000;
//跳至开始裁剪位置
extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
while (true){
ByteBuffer buffer = ByteBuffer.allocate(SAMPLE_SIZE);
int sampleSize = extractor.readSampleData(buffer, 0);
long timeStamp = extractor.getSampleTime();
// >= 1000000是要裁剪停止和指定的裁剪结尾不小于1秒,否则可能产生需要9秒音频
//裁剪到只有8.6秒,大多数音乐播放器是向下取整,这样对于播放器变成了8秒,
// 所以要裁剪比9秒多一秒的边界
if(timeStamp > end && timeStamp - end >= 1000000){
break;
}
if(sampleSize <= 0){
break;
}
byte[] buf = new byte[sampleSize];
buffer.get(buf, 0, sampleSize);
//写入文件
outputStream.write(buf);
//音轨数据往前读
extractor.advance();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(extractor != null){
extractor.release();
}
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
/**
* 获取音频数据轨道
* @param extractor
* @return
*/
@SuppressLint("InlinedApi")
private static int getAudioTrack(MediaExtractor extractor) {
for(int i = 0; i < extractor.getTrackCount(); i++){
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if(mime.startsWith("audio")){
return i;
}
}
return -1;
}
}
五、定义一个实体类Music.java
package com.t20.audiodemo.entity;
import java.io.Serializable;
public class Music implements Serializable {
private String name; //歌曲名称
private String singer; //歌手
private long duration; //歌曲时长
private String path; //歌曲路径
public Music() {
super();
}
public Music(String name, String singer, long duration, String path) {
super();
this.name = name;
this.singer = singer;
this.duration = duration;
this.path = path;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
六、下面开始去活动MainActivity.java实现方法
package com.t20.audiodemo;
import java.util.ArrayList;
import java.util.List;
import com.t20.audiodemo.adapter.MusicListViewAdapter;
import com.t20.audiodemo.adapter.MusicListViewAdapter.OnplayMusicListener;
import com.t20.audiodemo.entity.Music;
import com.t20.audiodemo.util.MusicPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
//音乐ListView视图
private ListView mListViewMusic;
//音乐集合
private List<Music> mMusicList;
//ListView的适配器
private MusicListViewAdapter musicListViewAdapter;
//开始播放的进度
private long startProgress=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 1、隐藏标题栏,在加载布局之前设置(兼容Android2.3.3版本)
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 2、隐藏状态栏
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
//获取控件
mListViewMusic=(ListView) findViewById(R.id.music_listView);
initData();
//设置适配器
musicListViewAdapter=new MusicListViewAdapter(this, mMusicList);
mListViewMusic.setAdapter(musicListViewAdapter);
//监听事件
initEvent();
}
private void initData() {
// TODO Auto-generated method stub
// 读取手机中的音乐文件
mMusicList = new ArrayList<Music>();
/*
* Uri:指明要查询的数据库名称加上表的名称,从MediaStore中我们可以找到相应信息的参数。 Projection:
* 指定查询数据库表中的哪几列,返回的游标中将包括相应的信息。Null则返回所有信息。 selection: 指定查询条件
* selectionArgs:参数selection里有
* ?这个符号是,这里可以以实际值代替这个问号。如果selection这个没有?的话,那么这个String数组可以为null。
* SortOrder:指定查询结果的排列顺序
*/
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver = getContentResolver();
String selection = MediaStore.Audio.Media.MIME_TYPE + "=? ";
String[] selectionArgs = new String[] { "audio/mpeg" };
// 游标
Cursor cursor = contentResolver.query(uri, null, null, null,
MediaStore.Audio.AudioColumns.IS_MUSIC);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
String singer = cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String path = cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
long duration = cursor
.getLong(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
long size = cursor.getLong(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
// 把歌曲名字和歌手切割开
// if (size > 1000 * 800) {
if (name.contains("-")) {
String[] str = name.split("-");
singer = str[0];
if (str[1].contains(".")) {
name = str[1].substring(0, str[1].indexOf('.'));
} else {
name = str[1];
}
} else if (name.contains(".")) {
name = name.substring(0, name.indexOf('.'));
}
Music music = new Music(name, singer, duration, path);
mMusicList.add(music);
// }
}
}
cursor.close();
}
private void initEvent() {
// TODO Auto-generated method stub
/**
* 监听ListView中音乐的播放事件
*/
musicListViewAdapter.setOnplayMusicListener(new OnplayMusicListener() {
//播放完整歌曲
@Override
public void playForFull() {
// TODO Auto-generated method stub
if(musicListViewAdapter!=null){
musicListViewAdapter.setSelectItem(musicListViewAdapter.getSelectItem());
musicListViewAdapter.setHidePlayBtn(true);
musicListViewAdapter.notifyDataSetChanged();
}
Music music=musicListViewAdapter.getCurrentMusic();
MusicPlayer.play(MainActivity.this,music.getPath(), 0);
}
//播放片段歌曲
@Override
public void playforPart() {
// TODO Auto-generated method stub
startProgress=musicListViewAdapter.getCutMusicStartProgress();
MusicPlayer.endProgress=musicListViewAdapter.getCutMusicEndProgress();
String path=musicListViewAdapter.getCutMusicPath();
MusicPlayer.play(MainActivity.this, path,(int)startProgress);
MusicPlayer.handler.post(MusicPlayer.run);
}
});
/**
* 监听ListView子项的点击事件
*/
mListViewMusic.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
if(musicListViewAdapter!=null){
musicListViewAdapter.setHidePlayBtn(false);
musicListViewAdapter.setSelectItem(position);
musicListViewAdapter.notifyDataSetChanged();
}
MusicPlayer.reset();
}
});
}
}
七、ListView的适配器 MusicListViewAdapter.java
package com.t20.audiodemo.adapter;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.t20.audiodemo.MainActivity;
import com.t20.audiodemo.R;
import com.t20.audiodemo.entity.Music;
import com.t20.audiodemo.util.MusicPlayer;
import com.t20.audiodemo.util.MusicUtil;
import com.t20.audiodemo.view.MusicCutPopupWindow;
import android.content.Context;
import android.os.Environment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MusicListViewAdapter extends BaseAdapter {
private Context context;
private List<Music> mMusicList;
private MusicCutPopupWindow musicCutPopupWindow;
private Music currentMusic;
public Music getCurrentMusic() {
return currentMusic;
}
public void setCurrentMusic(Music currentMusic) {
this.currentMusic = currentMusic;
}
public MusicListViewAdapter(Context context, List<Music> mMusicList) {
super();
this.context = context;
this.mMusicList = mMusicList;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mMusicList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final Music music = mMusicList.get(position);
final int currentId=position;
// 加载布局
View view;
final ViewHolder viewHolder;
if (convertView == null) {
view = LayoutInflater.from(context).inflate(
R.layout.music_listview_item, null);
viewHolder = new ViewHolder();
// 获取控件
viewHolder.textViewName = (TextView) view
.findViewById(R.id.music_tv_name);
viewHolder.textViewSinger = (TextView) view
.findViewById(R.id.music_tv_singer);
viewHolder.textViewDuration = (TextView) view
.findViewById(R.id.music_tv_duration);
viewHolder.imageViewPlay = (ImageView) view
.findViewById(R.id.music_iv_play);
viewHolder.imageViewPic = (ImageView) view
.findViewById(R.id.music_iv_pic);
viewHolder.imageViewCut = (ImageView) view
.findViewById(R.id.music_iv_cut);
view.setTag(viewHolder);
} else {
view = convertView;
// 重新获取ViewHolder
viewHolder = (ViewHolder) view.getTag();
}
// 设置控件
viewHolder.textViewName.setText(music.getName());
viewHolder.textViewSinger.setText(music.getSinger());
viewHolder.textViewDuration.setText(formatTime(music.getDuration()));
if (selectItem != -1 && selectItem == position) {
viewHolder.imageViewPic.setEnabled(false);
if (hidePlayBtn) {
viewHolder.imageViewPlay.setVisibility(View.GONE);
} else {
viewHolder.imageViewPlay.setVisibility(View.VISIBLE);
}
} else {
viewHolder.imageViewPic.setEnabled(true);
viewHolder.imageViewPlay.setVisibility(View.VISIBLE);
}
// 判断播放图标是否显示
/*
* if(viewHolder.imageViewPlay.getVisibility()==View.GONE){
* viewHolder.imageViewPic.setEnabled(false); }else{
* viewHolder.imageViewPic.setEnabled(true); }
*/
// 播放音乐按钮
viewHolder.imageViewPlay.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
if (onplayMusicListener != null) {
currentMusic = music;
onplayMusicListener.playForFull();
selectItem = currentId;
}
}
});
// 音乐剪辑
viewHolder.imageViewCut.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
currentMusic = music;
musicCutPopupWindow = new MusicCutPopupWindow(context,
itemsOnClick);
// 设置音乐信息
musicCutPopupWindow.setMusicInfo(currentMusic.getSinger()
+ " - " + currentMusic.getName(),
currentMusic.getDuration());
// 显示窗口
musicCutPopupWindow.showAtLocation(((MainActivity) context)
.findViewById(R.id.mainActivity_root), Gravity.BOTTOM,
0, 0);
}
});
return view;
}
//为弹出窗口实现监听类
private OnClickListener itemsOnClick = new OnClickListener(){
public void onClick(View v) {
switch (v.getId()) {
//确定按钮
case R.id.popupWindow_music_cut_btn_sure:
//获取最小值
float min=musicCutPopupWindow.getMinRule();
//获取最大值
float max=musicCutPopupWindow.getMaxRule();
//开始剪切音乐
if(currentMusic==null){
return;
}
//要剪切的音乐路径
String inputPath=currentMusic.getPath();
Date date=Calendar.getInstance().getTime();
SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddHHmmss");
String str=sdf.format(date);
//剪切后音乐文件路径
File sdDir = null;
boolean sdCardExist = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);// 判断sd卡是否存在
if (!sdCardExist) {
Toast.makeText(context, "SD卡不存在,保存失败", Toast.LENGTH_SHORT).show();
return;
}else{
sdDir = Environment.getExternalStorageDirectory();// 获取根目录
}
File flie=new File(sdDir +"/audio");
//目录不存在就自动创建
if(!flie.exists()){
flie.mkdirs();
}
String outputPath=flie.getPath()+"/new"+"_"+currentMusic.getName()+".mp3";
File audioPath=new File(outputPath);
//文件存在就先删除
if(audioPath.exists()){
try {
audioPath.delete();
audioPath.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
boolean flag=MusicUtil.clipMp3(inputPath, outputPath, (int)min*1000, (int)max*1000);
if(flag){
Toast.makeText(context, "剪辑成功,保存路径:"+outputPath, Toast.LENGTH_SHORT).show();
musicCutPopupWindow.dismiss();
}else{
Toast.makeText(context, "剪辑失败", Toast.LENGTH_SHORT).show();
}
break;
//取消按钮
case R.id.popupWindow_music_cut_btn_cancel:
//关闭弹窗
musicCutPopupWindow.dismiss();
//重置音乐
MusicPlayer.reset();
break;
//试听按钮
case R.id.popupWindow_music_cut_tv_musicTest:
cutMusicStartProgress=(long)((int)musicCutPopupWindow.getMinRule()*1000);
cutMusicEndProgress=(long)((int)musicCutPopupWindow.getMaxRule()*1000);
cutMusicPath=currentMusic.getPath();
if(onplayMusicListener!=null){
onplayMusicListener.playforPart();
}
break;
}
}
};
class ViewHolder{
TextView textViewName;
TextView textViewSinger;
TextView textViewDuration;
ImageView imageViewPlay;
ImageView imageViewPic;
ImageView imageViewCut;
}
private Integer selectItem=-1;
public Integer getSelectItem() {
return selectItem;
}
public void setSelectItem(Integer selectItem) {
this.selectItem = selectItem;
}
//标识是否隐藏播放按钮
private boolean hidePlayBtn;
public void setHidePlayBtn(boolean hidePlayBtn) {
this.hidePlayBtn = hidePlayBtn;
}
/**
* 转换歌曲时间的格式
* @param time
* @return
*/
public static String formatTime(long time) {
if (time / 1000 % 60 < 10) {
String t = time / 1000 / 60 + ":0" + time / 1000 % 60;
return t;
} else {
String t = time / 1000 / 60 + ":" + time / 1000 % 60;
return t;
}
}
// 剪辑歌曲路径
private String cutMusicPath;
// 剪辑歌曲开始进度
private long cutMusicStartProgress;
// 剪辑歌曲结束进度
private long cutMusicEndProgress;
public String getCutMusicPath() {
return cutMusicPath;
}
public void setCutMusicPath(String cutMusicPath) {
this.cutMusicPath = cutMusicPath;
}
public long getCutMusicStartProgress() {
return cutMusicStartProgress;
}
public void setCutMusicStartProgress(long cutMusicStartProgress) {
this.cutMusicStartProgress = cutMusicStartProgress;
}
public long getCutMusicEndProgress() {
return cutMusicEndProgress;
}
public void setCutMusicEndProgress(long cutMusicEndProgress) {
this.cutMusicEndProgress = cutMusicEndProgress;
}
/**
* 自定义用于播放音乐的接口
* @author admin
*
*/
private OnplayMusicListener onplayMusicListener;
public void setOnplayMusicListener(
OnplayMusicListener onplayMusicListener) {
this.onplayMusicListener = onplayMusicListener;
}
public interface OnplayMusicListener{
//播放完整歌曲
void playForFull();
//播放片段歌曲
void playforPart();
}
}