解决方法
创建类并扩展View.然后为您的类创建Listener接口.
public class WaveformCls extends View { public interface WaveformListener { public void waveformTouchStart(float x); public void waveformTouchMove(float x); public void waveformTouchEnd(); public void waveformFling(float x); public void waveformDraw(); };
根据您的要求创建Paint对象.
创建一个初始化所有Paint对象的方法.
public WaveformView(Context context,AttributeSet attrs) { super(context,attrs); // We don't want keys,the markers get these setFocusable(false); mGridPaint = new Paint(); mGridPaint.setAntiAlias(false); mGridPaint.setColor( getResources().getColor(R.drawable.grid_line)); mSelectedLinePaint = new Paint(); mSelectedLinePaint.setAntiAlias(false); mSelectedLinePaint.setColor( getResources().getColor(R.drawable.waveform_selected)); mUnselectedLinePaint = new Paint(); mUnselectedLinePaint.setAntiAlias(false); mUnselectedLinePaint.setColor( getResources().getColor(R.drawable.waveform_unselected)); mUnselectedBkgndLinePaint = new Paint(); mUnselectedBkgndLinePaint.setAntiAlias(false); mUnselectedBkgndLinePaint.setColor( getResources().getColor( R.drawable.waveform_unselected_bkgnd_overlay)); mBorderLinePaint = new Paint(); mBorderLinePaint.setAntiAlias(true); mBorderLinePaint.setStrokeWidth(1.5f); mBorderLinePaint.setPathEffect( new DashPathEffect(new float[] { 3.0f,2.0f },0.0f)); mBorderLinePaint.setColor( getResources().getColor(R.drawable.selection_border)); mPlaybackLinePaint = new Paint(); mPlaybackLinePaint.setAntiAlias(false); mPlaybackLinePaint.setColor( getResources().getColor(R.drawable.playback_indicator)); mTimecodePaint = new Paint(); mTimecodePaint.setTextSize(12); mTimecodePaint.setAntiAlias(true); mTimecodePaint.setColor( getResources().getColor(R.drawable.timecode)); mTimecodePaint.setShadowLayer( 2,1,getResources().getColor(R.drawable.timecode_shadow)); mGestureDetector = new GestureDetector( context,new GestureDetector.SimpleOnGestureListener() { public boolean onFling( MotionEvent e1,MotionEvent e2,float vx,float vy) { mListener.waveformFling(vx); return true; } }); mSoundFile = null; mLenByZoomLevel = null; mValuesByZoomLevel = null; mHeightsAtThisZoomLevel = null; mOffset = 0; mPlaybackPos = -1; mSelectionStart = 0; mSelectionEnd = 0; mDensity = 1.0f; mInitialized = false; }
您需要覆盖onTouchEvent
@Override public boolean onTouchEvent(MotionEvent event) { if (mGestureDetector.onTouchEvent(event)) { return true; } switch(event.getAction()) { case MotionEvent.ACTION_DOWN: mListener.waveformTouchStart(event.getX()); break; case MotionEvent.ACTION_MOVE: mListener.waveformTouchMove(event.getX()); break; case MotionEvent.ACTION_UP: mListener.waveformTouchEnd(); break; } return true; } public void setSoundFile(CheapSoundFile soundFile) { mSoundFile = soundFile; mSampleRate = mSoundFile.getSampleRate(); mSamplesPerFrame = mSoundFile.getSamplesPerFrame(); computeDoublesForAllZoomLevels(); mHeightsAtThisZoomLevel = null; }
覆盖在屏幕上绘制波形的绘制方法.
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mSoundFile == null) return; if (mHeightsAtThisZoomLevel == null) computeIntsForThisZoomLevel(); // Draw waveform int measuredWidth = getMeasuredWidth(); int measuredHeight = getMeasuredHeight(); int start = mOffset; int width = mHeightsAtThisZoomLevel.length - start; int ctr = measuredHeight / 2; if (width > measuredWidth) width = measuredWidth; // Draw grid double onePixelInSecs = pixelsToSeconds(1); boolean onlyEveryFiveSecs = (onePixelInSecs > 1.0 / 50.0); double fractionalSecs = mOffset * onePixelInSecs; int integerSecs = (int) fractionalSecs; int i = 0; while (i < width) { i++; fractionalSecs += onePixelInSecs; int integerSecsNew = (int) fractionalSecs; if (integerSecsNew != integerSecs) { integerSecs = integerSecsNew; if (!onlyEveryFiveSecs || 0 == (integerSecs % 5)) { canvas.drawLine(i,i,measuredHeight,mGridPaint); } } } // Draw waveform for (i = 0; i < width; i++) { Paint paint; if (i + start >= mSelectionStart && i + start < mSelectionEnd) { paint = mSelectedLinePaint; } else { drawWaveformLine(canvas,mUnselectedBkgndLinePaint); paint = mUnselectedLinePaint; } drawWaveformLine( canvas,ctr - mHeightsAtThisZoomLevel[start + i],ctr + 1 + mHeightsAtThisZoomLevel[start + i],paint); if (i + start == mPlaybackPos) { canvas.drawLine(i,mPlaybackLinePaint); } } // If we can see the right edge of the waveform,draw the // non-waveform area to the right as unselected for (i = width; i < measuredWidth; i++) { drawWaveformLine(canvas,mUnselectedBkgndLinePaint); } // Draw borders canvas.drawLine( mSelectionStart - mOffset + 0.5f,30,mSelectionStart - mOffset + 0.5f,mBorderLinePaint); canvas.drawLine( mSelectionEnd - mOffset + 0.5f,mSelectionEnd - mOffset + 0.5f,measuredHeight - 30,mBorderLinePaint); // Draw timecode double timecodeIntervalSecs = 1.0; if (timecodeIntervalSecs / onePixelInSecs < 50) { timecodeIntervalSecs = 5.0; } if (timecodeIntervalSecs / onePixelInSecs < 50) { timecodeIntervalSecs = 15.0; } // Draw grid fractionalSecs = mOffset * onePixelInSecs; int integerTimecode = (int) (fractionalSecs / timecodeIntervalSecs); i = 0; while (i < width) { i++; fractionalSecs += onePixelInSecs; integerSecs = (int) fractionalSecs; int integerTimecodeNew = (int) (fractionalSecs / timecodeIntervalSecs); if (integerTimecodeNew != integerTimecode) { integerTimecode = integerTimecodeNew; // Turn,e.g. 67 seconds into "1:07" String timecodeMinutes = "" + (integerSecs / 60); String timecodeSeconds = "" + (integerSecs % 60); if ((integerSecs % 60) < 10) { timecodeSeconds = "0" + timecodeSeconds; } String timecodeStr = timecodeMinutes + ":" + timecodeSeconds; float offset = (float) ( 0.5 * mTimecodePaint.measureText(timecodeStr)); canvas.drawText(timecodeStr,i - offset,(int)(12 * mDensity),mTimecodePaint); } } if (mListener != null) { mListener.waveformDraw(); } }
以下是Rindroid的完整源代码,对您有用
Source code for waveform