Android 는 오디 오 정 보 를 사용 하여 동적 파문 을 그립 니 다.

8042 단어 android물결 무늬
일부 음악 류 응용 프로그램 에서 리듬 에 따라 상하 로 기복 이 있 는 파문 정 보 를 자주 보 여 준다.이런 파문 은 음성 정 보 를 형상 적 으로 전달 하고 사용자 의 체험 을 향상 시 킬 수 있다.그러면 어떻게 실현되 었 을 까?Visualizer 클래스 를 사용 하여 현재 재생 중인 소리 정 보 를 얻 고 캔버스 에 그 릴 수 있 습 니 다.파문 으로 보 여주 면 됩 니 다.사용 방법 을 설명해 드 리 겠 습 니 다.
音乐
주요
(1)Visualizer 류 에서 파문 정 보 를 추출 하 는 방식.
(2)동적 권한 관리 방법 을 응용 한다.
(3)사용자 정의 보기 의 전시 와 논 리 를 분리 합 니 다.
1.기초 준비
Android 6.0 은 동적 권한 관 리 를 도입 합 니 다.이 항목 에 서 는 시스템 의 오디 오 정 보 를 사용 하기 때문에 권한 관 리 를 이 항목 에 도입 합 니 다.참고 하 십시오.Gradle 설정 은 Lambda 표현 식 을 도입 하 였 습 니 다.참고 하 십시오.
페이지 레이아웃,사용자 정의 파문 보기 컨트롤 을 사용 합 니 다.

<!--    -->
<me.chunyu.spike.wcl_visualizer_demo.visualizers.WaveformView
android:id="@+id/main_wv_waveform"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
효과.
波纹
2.첫 페이지 논리
동적 권한 관 리 를 추가 하고 페이지 를 시작 할 때 필요 한 오디 오 권한 을 가 져 옵 니 다.
Renderer Factory 공장 클래스 에서 파문 을 만 드 는 그리 기 클래스 Simple WaveformRender.
startVisualiser 방법 으로 현재 음악 을 재생 하 는 오디 오 정 보 를 가 져 옵 니 다.
페이지 가 닫 히 면 onPause 에서 Visualiser 클래스 를 방출 합 니 다.

public class MainActivity extends AppCompatActivity {
private static final int CAPTURE_SIZE = 256; //       ,     
private static final int REQUEST_CODE = 0;
//   
private static final String[] PERMISSIONS = new String[]{
Manifest.permission.RECORD_AUDIO,
Manifest.permission.MODIFY_AUDIO_SETTINGS
};
@Bind(R.id.main_wv_waveform) WaveformView mWvWaveform; //     
private Visualizer mVisualizer; //       
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
RendererFactory rendererFactory = new RendererFactory();
mWvWaveform.setRenderer(rendererFactory.createSimpleWaveformRender(ContextCompat.getColor(this, R.color.colorPrimary), Color.WHITE));
}
@Override protected void onResume() {
super.onResume();
PermissionsChecker checker = new PermissionsChecker(this);

if (checker.lakesPermissions(PERMISSIONS)) {
PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);
} else {
startVisualiser();
}
}
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == PermissionsActivity.PERMISSIONS_DENIED) {
finish();
}
}
//      
private void startVisualiser() {
mVisualizer = new Visualizer(0); //    
mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
if (mWvWaveform != null) {
mWvWaveform.setWaveform(waveform);
}
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
}
}, Visualizer.getMaxCaptureRate(), true, false);
mVisualizer.setCaptureSize(CAPTURE_SIZE);
mVisualizer.setEnabled(true);
}
//   
@Override protected void onPause() {
if (mVisualizer != null) {
mVisualizer.setEnabled(false);
mVisualizer.release();
}
super.onPause();
}
}
Visualizer 클래스
new Visualizer(0),초기 화;setCapture Size,파문 수량 가 져 오기;setEnabled,감청 시작;
setDataCapture Listener,첫 번 째 매개 변 수 는 리 셋 입 니 다.WaveFormData 나 FftData 를 사용 합 니 다.두 번 째 는 업데이트 율 입 니 다.세 번 째 는 WaveFormData 사용 을 판단 하 는 것 이다.네 번 째 는 FftData 를 사용 하 는 것 을 판단 하 는 것 입 니 다.세 번 째\네 번 째 는 모두 리 셋 의 반환 값 과 관련 이 있 습 니 다.
3.파문 보기
페이지 프레임 워 크,디 스 플레이 와 논 리 를 분리 하고 인터페이스 렌 더 링 을 사용 하여 캔버스 와 파형 Waveform 을 입력 하 십시오.

/**
*       
* <p>
* Created by wangchenlong on 16/2/11.
*/
public class WaveformView extends View {
private WaveformRenderer mRenderer; //    
private byte[] mWaveform; //     
public WaveformView(Context context) {
super(context);
}
public WaveformView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WaveformView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public WaveformView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void setRenderer(WaveformRenderer renderer) {
mRenderer = renderer;
}
public void setWaveform(byte[] waveform) {
mWaveform = Arrays.copyOf(waveform, waveform.length); //     
invalidate(); //       ,     
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mRenderer != null) {
mRenderer.render(canvas, mWaveform);
}
}
}
배열 복사 Arrays.copy Of(),파문 설정 후 페이지 invalidate()를 다시 그립 니 다.
4.파문 논리
핵심 부분 renderWaveform,렌 더 링 파문.
페이지 를 격자 스타일 로 나 누 어 파문 값 에 따라 곡선 을 그립 니 다.파문 이 없 으 면 가운데 수평 직선 을 그립 니 다.

/**
*       
* <p>
* Created by wangchenlong on 16/2/12.
*/
public class SimpleWaveformRenderer implements WaveformRenderer {
private static final int Y_FACTOR = 0xFF; // 2 8   = 256
private static final float HALF_FACTOR = 0.5f;
@ColorInt private final int mBackgroundColor;
private final Paint mForegroundPaint;
private final Path mWaveformPath;
private SimpleWaveformRenderer(@ColorInt int backgroundColor, Paint foregroundPaint, Path waveformPath) {
mBackgroundColor = backgroundColor;
mForegroundPaint = foregroundPaint;
mWaveformPath = waveformPath;
}
public static SimpleWaveformRenderer newInstance(@ColorInt int backgroundColor, @ColorInt int foregroundColour) {
Paint paint = new Paint();
paint.setColor(foregroundColour);
paint.setAntiAlias(true); //    
paint.setStrokeWidth(8.0f); //     
paint.setStyle(Paint.Style.STROKE); //   
Path waveformPath = new Path();
return new SimpleWaveformRenderer(backgroundColor, paint, waveformPath);
}
@Override public void render(Canvas canvas, byte[] waveform) {
canvas.drawColor(mBackgroundColor);
float width = canvas.getWidth();
float height = canvas.getHeight();
mWaveformPath.reset();
//     
if (waveform != null) {
//     
renderWaveform(waveform, width, height);
} else {
//     
renderBlank(width, height);
}
canvas.drawPath(mWaveformPath, mForegroundPaint);
}
private void renderWaveform(byte[] waveform, float width, float height) {
float xIncrement = width / (float) (waveform.length); //     
float yIncrement = height / Y_FACTOR; //     
int halfHeight = (int) (height * HALF_FACTOR); //     
mWaveformPath.moveTo(0, halfHeight);
for (int i = 1; i < waveform.length; ++i) {
float yPosition = waveform[i] > 0 ?
height - (yIncrement * waveform[i]) : -(yIncrement * waveform[i]);
mWaveformPath.lineTo(xIncrement * i, yPosition);
}
mWaveformPath.lineTo(width, halfHeight); //     ,     
}
//        
private void renderBlank(float width, float height) {
int y = (int) (height * HALF_FACTOR);
mWaveformPath.moveTo(0, y);
mWaveformPath.lineTo(width, y);
}
}
이동 moveTo 를 그립 니 다.직선 선 을 그립 니 다.
애니메이션 효과

파문 을 그 리 는 것 을 통 해 연속 적 인 데 이 터 를 유사 하 게 그 려 서 더욱 직관 적 으로 보 여주 고 사용자 체험 을 향상 시 킬 수 있다.

좋은 웹페이지 즐겨찾기