从Actvity将变量传递到自定义视图类 [英] Passing a variable to a Custom View Class from Actvity
问题描述
我正在使用canvas.drawLine()
方法测试将音频绘制到画布中.我能够在画布上进行静态绘制.基本上,我有一个测试应用程序,它具有两个按钮START和STOP,以及一个Canvas,其中我尝试绘制从FFT获得的音频频率.当我按下开始"按钮时,它将开始使用AudioRecord
类录制声音,并将数据收集到缓冲区中,该缓冲区通过FFT运行以获取频率.这还处于初期.现在,我只是想弄清楚如何将这些频率值传递给我的Custom View类的onDraw
方法.这是从布局开始的相关代码.
I am testing drawing audio frequency into canvas using canvas.drawLine()
method. I am able to do static draw into canvas. Basically I have a test app which has two buttons START and STOP and a Canvas where i am trying to draw the audio frequencies obtained from FFT. When i hit the START button it starts recording sound using AudioRecord
class and collects data into buffer which i run through FFT to get the frequencies. This is in very early stage. Right now i am only trying to figure out how to pass these frequency values to onDraw
method of my Custom View class. Here are the relevent codes starting from the layout.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.example.testapp.WaveForm
android:id="@+id/waveForm1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="78dp" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button1"
android:layout_alignBottom="@+id/button1"
android:layout_alignRight="@+id/waveForm1"
android:layout_marginRight="19dp"
android:text="STOP" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/waveForm1"
android:layout_alignParentTop="true"
android:text="START" />
</RelativeLayout>
我认为它非常早.这是我的自定义视图类
I think its very starighforward. Here is my Custom View class
WaveForm.java
package com.example.testapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class WaveForm extends View {
private Paint mLinePaint;
float x ;
float y;
public WaveForm(Context context, AttributeSet attrs) {
super(context, attrs);
mLinePaint = new Paint();
mLinePaint.setStyle(Paint.Style.STROKE);
mLinePaint.setARGB(255, 0, 0, 255);
mLinePaint.setAntiAlias(true);
mLinePaint.setStrokeWidth(10);
x = 0.0f;
y = 0.0f;
}
@Override
protected void onDraw(Canvas canvas) {
//Instead of 50 here i would like to pass the value obtained from the Activity class
canvas.drawLine(x, 0, y, 50, mLinePaint);
y = y + 1.0f;
x = x + 1.0f;
super.onDraw(canvas);
}
}
正如我在onDraw方法的注释中提到的那样,我想传递在Activity中获得的频率值,而不是50. 最后是我的活动:
As i mentioned in the comment in the onDraw method, i would like to pass the frequency value i obtained in the Activity instead of 50. Finally here is my Activity:
MainActivity.java
package com.example.testapp;
import android.app.Activity;
import android.graphics.Canvas;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
boolean recording = false;
AudioRecord audioRecord;
double[] x;
double[] y;
double currentPoint = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View myInstance = (View) findViewById(R.id.waveForm1);
Button start = (Button) findViewById(R.id.button1);
start.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
int sampleRateInHz=44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(AudioSource.MIC, sampleRateInHz, channelConfig, AudioFormat.ENCODING_PCM_16BIT, AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, AudioFormat.ENCODING_PCM_16BIT));
byte[] audioData = new byte[bufferSizeInBytes/4];
FFT myFFT = new FFT(audioData.length);
Canvas canvas = new Canvas();
recording = true;
audioRecord.startRecording();
while(recording) {
audioRecord.read(audioData,0, bufferSizeInBytes/4);
//convert to double here
for(int i=0; i<audioData.length; i++) {
x[i] = (double)audioData[i];
y[i] = 0;
}
double[] samples = myFFT.fft(x, y);
for(int i=0; i<samples.length; i++) {
currentPoint = samples[i];
myInstance.draw(canvas);
myInstance.invalidate();
}
}
}
});
Button stop = (Button) findViewById(R.id.button2);
stop.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
recording = false;
audioRecord.stop();
}
});
}
}
currentPoint
变量是我试图传递给onDraw
方法的内容.预先感谢您的浏览.
The currentPoint
variable is what i am trying to pass to the onDraw
method. Thanks in advance for taking a look.
推荐答案
在WaveForm
中为currentPoint
变量创建Getter/Setter以从MainActivity
获取值,然后将draw
调用为:
Create Getter/Setter for currentPoint
variable inside WaveForm
to get value from MainActivity
before calling draw
as:
public class WaveForm extends View {
private double currentPoint = 50;
public void setCurrentPoint(double currentPoint){
this.currentPoint=currentPoint;
}
public double getCurrentPoint(){
return this.currentPoint;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawLine(x, 0, y, getCurrentPoint(), mLinePaint);
...
}
}
并从MainActivity
中通过在调用onDraw
之前调用setCurrentPoint
方法来设置currentPoint
值:
and from MainActivity
set currentPoint
value by calling setCurrentPoint
method before calling onDraw
:
for(int i=0; i<samples.length; i++) {
currentPoint = samples[i];
myInstance.setCurrentPoint(currentPoint);
myInstance.draw(canvas);
myInstance.invalidate();
}
这篇关于从Actvity将变量传递到自定义视图类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!