Draw Text inside an Arc using canvas - android

I am working in an android application to draw a circle and divide them equally and bind text inside the divided portion in the circle(like pichart). I have drawn a circle and divided them equally, but I want to bind text inside the divided portion. Please look into my code and give a solution. Thanks in advance.
public class MainActivity extends Activity {
/** Called when the activity is first created. */
float values[] = { 130, 130, 130, 130, 130 };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout linear = (LinearLayout) findViewById(R.id.linearlay);
values = calculateData(values);
linear.addView(new MyGraphview(this, values));
}
private float[] calculateData(float[] data) {
float total = 0;
for (int i = 0; i < data.length; i++) {
total += data[i];
}
for (int i = 0; i < data.length; i++) {
data[i] = 360 * (data[i] / total);
}
return data;
}
public class MyGraphview extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float[] value_degree;
private int[] COLORS = { Color.YELLOW, Color.GREEN, Color.WHITE,
Color.CYAN, Color.RED };
RectF rectf = new RectF(10, 10, 300, 300);
Rect rect = new Rect(10, 10, 300, 300);
int temp = 0;
String rotatedtext;
Path path;
public MyGraphview(Context context, float[] values) {
super(context);
path = new Path();
value_degree = new float[values.length];
for (int i = 0; i < values.length; i++) {
value_degree[i] = values[i];
}
paint.setTextSize(16);
rotatedtext = "Rotated :)";
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < value_degree.length; i++) {
if (i == 0) {
paint.setColor(COLORS[i]);
canvas.drawArc(rectf, 0, value_degree[i], true, paint);
} else {
temp += (int) value_degree[i - 1];
paint.setColor(COLORS[i]);
canvas.drawArc(rectf, temp, value_degree[i], true, paint); //
}
}
}
}
}

Try this:
private String[] STRINGS = { "Yellow", "GREEN", "WHITE", "CYAN", "RED" }; // Array of strings, just for the sample
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
temp = 0;
int centerX = (rect.left + rect.right) / 2;
int centerY = (rect.top + rect.bottom) / 2;
int radius = (rect.right - rect.left) / 2;
radius *= 0.5; // 1 will put the text in the border, 0 will put the text in the center. Play with this to set the distance of your text.
for (int i = 0; i < data.length; i++)
{
if (i > 0)
temp += (int) data[i - 1]; // rewrote your code here a bit, to avoid duplicate code.
paint.setColor(COLORS[i]);
canvas.drawArc(rectf, temp, data[i], true, paint);
paint.setColor(Color.BLACK); // set this to the text color.
float medianAngle = (temp + (data[i] / 2f)) * (float)Math.PI / 180f; // this angle will place the text in the center of the arc.
canvas.drawText(STRINGS[i], (float)(centerX + (radius * Math.cos(medianAngle))), (float)(centerY + (radius * Math.sin(medianAngle))), paint);
}
}
Also, for nicer results, make sure to set the Align.CENTER property in the paint before drawing any text:
paint.setTextSize(16);
paint.setTextAlign(Align.CENTER);
Hope this helps :)

Related

Android path disappears after changing path offset and then calling invalidate

I've managed to draw a staircase and also a smiley face (called Avatar in the code) using paths in my custom view. Id like to move the happy face up the stairs using my nextStep function. nextStep iterates the current step and then calls a function called moveToStep(int step) which offsets the Avatar to the location of the specified step. Lastly, nextStep calls this.invalidate so that onDraw gets called again in hopes that the Avatar is redrawn at the new offset. The problem is that after nextStep is called, the Avatar disappears even though the staircase still remains. I know its not offscreen because I checked the coordinates the smiley is offset to.
Custom View Code
public class StaircaseView extends View {
// setup initial color
private final int paint_color = Color.BLACK;
private int curr_step = 1;
int STEPS = 5;
private float avatar_radius;
// defines paint and canvas
private Paint DrawPaint;
private int view_width, view_height, view_size;
private Path StaircasePath, Avatar;
private float scale, side_length;
private char constrainer;
public StaircaseView(Context context, AttributeSet attrs) {
super(context, attrs);
setupPaint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("StaircaseView", "onDraw called");
canvas.drawPath(StaircasePath, DrawPaint);
canvas.drawPath(Avatar, DrawPaint);
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
view_height = yNew;
view_width = xNew;
view_size = Math.min(view_height, view_width);
if (view_width == view_size) {
constrainer = 'w';
} else {
constrainer = 'h';
}
scale = (float)view_size/100;
Log.i("StaircaseView", "onSizeChanged --> view width: " + String.valueOf(xNew) + ", view height: " + String.valueOf(yNew) + ", scale: " + String.valueOf(scale) + ", view size: " + String.valueOf(view_size));
float padding = 5 * scale;
StaircasePath = createStaircase(padding);
avatar_radius = 7*scale;
Avatar = createAvatar(0, 0, avatar_radius);
StaircasePath.offset(0, view_height);
moveToStep(curr_step);
}
public void nextStep() {
if (curr_step < STEPS) {
curr_step++;
} else {
curr_step = 1;
}
moveToStep(curr_step);
this.invalidate();
}
private void moveToStep(int step) {
float x = step * side_length - avatar_radius;
float y = view_height - (step - 1) * side_length - avatar_radius;
Log.i("StaircaseView", String.valueOf(x) + ", " + String.valueOf(y));
Avatar.offset(x, y);
}
// Setup paint with color and stroke styles
private void setupPaint() {
DrawPaint = new Paint();
DrawPaint.setColor(paint_color);
DrawPaint.setAntiAlias(true);
DrawPaint.setStrokeWidth(5);
DrawPaint.setStyle(Paint.Style.STROKE);
DrawPaint.setStrokeJoin(Paint.Join.ROUND);
DrawPaint.setStrokeCap(Paint.Cap.ROUND);
}
private Path createStaircase(float padding) {
if (constrainer == 'w') {
side_length = (view_size-padding)/(STEPS+1);
} else {
side_length = (view_size-padding)/STEPS;
}
Path path = new Path();
float curr_x = 0;
float curr_y = 0;
path.moveTo(curr_x, curr_y);
curr_x += side_length;
path.lineTo(curr_x, curr_y);
for(int i=0; i<STEPS; i++) {
curr_y -= side_length;
path.lineTo(curr_x, curr_y);
curr_x += side_length;
path.lineTo(curr_x, curr_y);
}
path.lineTo(curr_x, 0);
path.lineTo(0, 0);
return path;
}
private Path createShape(ArrayList<PointF> points) {
Path path = new Path();
path.moveTo(points.get(0).x, points.get(0).y);
for(int i=1; i< points.size(); i++) {
path.lineTo(points.get(i).x, points.get(i).y);
}
return path;
}
private Path createAvatar(int x, int y, float radius){
Path avatar = new Path();
float width = radius*2;
avatar.addCircle(x, y, radius, Path.Direction.CW);
avatar.addCircle(x - (radius /2), y - (radius / 5), radius/5, Path.Direction.CW);
avatar.addCircle(x + (radius / 2), y - (radius / 5), radius / 5, Path.Direction.CW);
avatar.addRect((float) x - (radius / 5), (float) y - (radius / 5), (float) x + (radius / 5), (float) y - (radius/5), Path.Direction.CCW);
return avatar;
}
}
After looking at this question decided to figure out another way to do this. So what I did was I changed my moveToStep method to return the coordinates to move the Avatar to instead of offsetting him. I then passed these coordinates to the createAvatar method as start coordinates. It worked after that.
New Code
/**
* Created by yako on 11/5/15.
*/
public class StaircaseView extends View {
// setup initial color
private final int paint_color = Color.BLACK;
private int curr_step = 1;
int STEPS = 5;
private float avatar_radius;
// defines paint and canvas
private Paint DrawPaint;
private int view_width, view_height, view_size;
private Path StaircasePath, Avatar;
private float scale, side_length;
private char constrainer;
public StaircaseView(Context context, AttributeSet attrs) {
super(context, attrs);
setupPaint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("StaircaseView", "onDraw called");
canvas.drawPath(StaircasePath, DrawPaint);
canvas.drawPath(Avatar, DrawPaint);
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
view_height = yNew;
view_width = xNew;
view_size = Math.min(view_height, view_width);
if (view_width == view_size) {
constrainer = 'w';
} else {
constrainer = 'h';
}
scale = (float)view_size/100;
Log.i("StaircaseView", "onSizeChanged --> view width: " + String.valueOf(xNew) + ", view height: " + String.valueOf(yNew) + ", scale: " + String.valueOf(scale) + ", view size: " + String.valueOf(view_size));
float padding = 5 * scale;
// Log.i("StaircaseView", String.valueOf(view_height/2 + padding/2));
StaircasePath = createStaircase(padding);
// Center the staircase in the view
// if (constrainer == 'w') {
// StaircasePath.offset(padding/2, view_height - (view_height - view_width - padding*2));
// } else {
// StaircasePath.offset(view_height/2 - padding/2, view_height-padding/2);
// }
avatar_radius = 7*scale;
Avatar = createAvatar(moveToStep(curr_step), avatar_radius);
StaircasePath.offset(0, view_height);
}
public void nextStep() {
if (curr_step <= STEPS) {
curr_step++;
} else {
curr_step = 1;
}
Avatar = createAvatar(moveToStep(curr_step), avatar_radius);
this.invalidate();
}
private float[] moveToStep(int step) {
float[] offset = new float[2];
offset[0] = step * side_length - avatar_radius;
offset[1] = view_height - (step - 1) * side_length - avatar_radius;
Log.i("StaircaseView", "Moving avatar to "+ String.valueOf(offset[0]) + ", " + String.valueOf(offset[1]));
return offset;
}
// Setup paint with color and stroke styles
private void setupPaint() {
DrawPaint = new Paint();
DrawPaint.setColor(paint_color);
DrawPaint.setAntiAlias(true);
DrawPaint.setStrokeWidth(5);
DrawPaint.setStyle(Paint.Style.STROKE);
DrawPaint.setStrokeJoin(Paint.Join.ROUND);
DrawPaint.setStrokeCap(Paint.Cap.ROUND);
}
private Path createStaircase(float padding) {
if (constrainer == 'w') {
side_length = (view_size-padding)/(STEPS+1);
} else {
side_length = (view_size-padding)/(STEPS+1);
}
Path path = new Path();
float curr_x = 0;
float curr_y = 0;
path.moveTo(curr_x, curr_y);
curr_x += side_length;
path.lineTo(curr_x, curr_y);
for(int i=0; i<STEPS; i++) {
curr_y -= side_length;
path.lineTo(curr_x, curr_y);
curr_x += side_length;
path.lineTo(curr_x, curr_y);
}
path.lineTo(curr_x, 0);
path.lineTo(0, 0);
return path;
}
private Path createShape(ArrayList<PointF> points) {
Path path = new Path();
path.moveTo(points.get(0).x, points.get(0).y);
for(int i=1; i< points.size(); i++) {
path.lineTo(points.get(i).x, points.get(i).y);
}
return path;
}
private Path createAvatar(float[] offset, float radius){
float x = offset[0];
float y = offset[1];
Path avatar = new Path();
float width = radius*2;
avatar.addCircle(x, y, radius, Path.Direction.CW);
avatar.addCircle(x - (radius /2), y - (radius / 5), radius/5, Path.Direction.CW);
avatar.addCircle(x + (radius / 2), y - (radius / 5), radius / 5, Path.Direction.CW);
avatar.addRect((float) x - (radius / 5), (float) y - (radius / 5), (float) x + (radius / 5), (float) y - (radius/5), Path.Direction.CCW);
return avatar;
}
}

Achart engine custom point style in android

Hi I want to draw custom point style in scattered chart in achartengine.
Is it possible using achartengine?? If yes then how to do this?
I was able to use custom point style by overriding onDraw(Canvas canvas) method of graphical view
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCommonPointBitmap != null ) {
float halfWitdhCommonPointBitmap = (float) mCommonPointBitmap.getWidth() / 2;
float halfHeightCommonPointBitmap = (float) mCommonPointBitmap.getHeight() / 2;
// float halfWitdhyouPointBitmap = (float) mYouPointBitmap.getWidth() / 2;
// float halfHeightyouPointBitmap = (float) mYouPointBitmap.getHeight() / 2;
List<double[]> screenPoints = getSeriesSelectionList();
if (!CommonUtils.isCollectionNullOrEmpty(screenPoints)) {
int[] margins = mXYChart.getRenderer().getMargins();
// Info: margin order: top, left, bottom, right
canvas.clipRect(getLeft() + margins[1], getTop() - margins[0], getRight() - margins[3], getBottom()
- margins[2]);
for (int i = 0; i < screenPoints.size(); i++) {
double[] screenPoint = screenPoints.get(i);
if (screenPoint != null) {
float pointLeftX = (float) screenPoint[0] - halfWitdhCommonPointBitmap;
float pointTopY = (float) screenPoint[1] - halfHeightCommonPointBitmap;
canvas.drawBitmap(mCommonPointBitmap, pointLeftX, pointTopY, null);
}
}
}
}
}
List<double[]> screenPoints = null;
XYSeries xySeries = mXYChart.getDataset().getSeriesAt(0);
int itemCount = xySeries.getItemCount();
if (itemCount > 0) {
screenPoints = new ArrayList<double[]>(itemCount);
double[] realPoints = new double[2];
for (int itemIndex = 0; itemIndex < itemCount; itemIndex++) {
realPoints[0] = xySeries.getX(itemIndex);
realPoints[1] = xySeries.getY(itemIndex);
screenPoints.add(mXYChart.toScreenPoint(realPoints));
}
}
return screenPoints;
}
A somewhat simpler solution in my opinion would be by subclassing the Scatterchart for example, and then Overriding its draw series method
Something like this:
public class BitmapChart extends ScatterChart{
public Bitmap awesomeBitmap;
private static final long serialVersionUID = 1L;
public BitmapChart(XYMultipleSeriesDataset dataset,
XYMultipleSeriesRenderer renderer, Context context) {
super(dataset, renderer);
awesomeBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_awesome_bitmap_resource);
}
#Override
public void drawSeries(Canvas canvas, Paint paint, List<Float> points,
SimpleSeriesRenderer renderer, float yAxisValue, int seriesIndex, int startIndex) {
int length = points.size();
for (int i = 0; i < length; i += 2) {
canvas.drawBitmap(awesomeBitmap, points.get(i), points.get(i+1), paint);
}
}
}
Then you can use it like this:
BitmapChart chart = new BitmapChart(yourDataset,yourChartRenderer,thisContext);
yourChartView = new GraphicalView(thisContext, chart);

How to draw a pie chart using RectF which will be easy to support multiple screen size in android?

Hi I am using following code to draw a pie chart in android :-
public class Chart extends View
{
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float[] value_degree;
private String[] Title_value;
RectF rectf = new RectF(50, 5, 200, 150);
Rect rect = new Rect(50, 5, 200, 150);
float temp = 0;
public Chart(Context context, float[] values, String[] heading)
{
super(context);
value_degree = new float[values.length];
Title_value = new String[heading.length];
for (int i = 0; i < values.length; i++)
{
value_degree[i] = values[i];
Log.i("abc", "" + values[i]);
Title_value[i] = heading[i];
}
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Random r;
int centerX = (rect.left + rect.right) / 2;
int centerY = (rect.top + rect.bottom) / 2;
int radius = (rect.right - rect.left) / 2;
int color;
radius *= 0.5; // 1 will put the text in the border, 0 will put the text
// in the center. Play with this to set the distance of
// your text.
for (int i = 0; i < value_degree.length; i++)
{
if (i == 0)
{
r = new Random();
color = Color.argb(100, r.nextInt(256), r.nextInt(256),
r.nextInt(256));
paint.setColor(color);
Log.i("Color", "" + color);
canvas.drawArc(rectf, temp, value_degree[i], true, paint);
paint.setColor(Color.BLACK); // set this to the text color.
paint.setTextSize(12);
/*
* paint.setTextAlign(Align.CENTER);
*/float medianAngle = (temp + (value_degree[i] / 2f))
* (float) Math.PI / 180f; // this angle will place the
// text in the center of the
// arc.
canvas.drawText(Title_value[i],
(float) (centerX + (radius * Math.cos(medianAngle))),
(float) (centerY + (radius * Math.sin(medianAngle))),
paint);
} else
{
temp += value_degree[i - 1];
r = new Random();
color = Color.argb(255, r.nextInt(256), r.nextInt(256),
r.nextInt(256));
paint.setColor(color);
Log.i("Else Color", "" + color);
canvas.drawArc(rectf, temp, value_degree[i], true, paint);
paint.setColor(Color.BLACK); // set this to the text color.
paint.setTextSize(12);
/*
* paint.setTextAlign(Align.CENTER);
*/float medianAngle = (temp + (value_degree[i] / 2f))
* (float) Math.PI / 180f; // this angle will place the
// text in the center of the
// arc.
canvas.drawText(Title_value[i],
(float) (centerX + (radius * Math.cos(medianAngle))),
(float) (centerY + (radius * Math.sin(medianAngle))),
paint);
}
}
}
}
It is showing chart in good quality in small screen sizes. But when I check it on big screen like S4 or other same screen size device it is shows a pie chart in very small size.
What should I do so it will draw perfectly on small as well as big screens?
Please help me, suggest something.
Also suggest how can I take color value to each slice in pie chart as it is assigned randomly.

Create waveform of audio file in android [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I want to create the wave forms of audio file in android. Can anyone provide me an example source code?
Create class and extend View. Then create Listener interface for your class.
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();
};
Create Paint object as per your requirement.
Create one method which is initialized all Paint object.
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, 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;
}
You need to override 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 the draw method which draw wave on your screen.
#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, 0, 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, i, 0, measuredHeight,
mUnselectedBkgndLinePaint);
paint = mUnselectedLinePaint;
}
drawWaveformLine(
canvas, i,
ctr - mHeightsAtThisZoomLevel[start + i],
ctr + 1 + mHeightsAtThisZoomLevel[start + i],
paint);
if (i + start == mPlaybackPos) {
canvas.drawLine(i, 0, i, measuredHeight, 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, i, 0, measuredHeight,
mUnselectedBkgndLinePaint);
}
// Draw borders
canvas.drawLine(
mSelectionStart - mOffset + 0.5f, 30,
mSelectionStart - mOffset + 0.5f, measuredHeight,
mBorderLinePaint);
canvas.drawLine(
mSelectionEnd - mOffset + 0.5f, 0,
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();
}
}
Here is complete source code of Rindroid which is useful for you
Source code for waveform

Android Bitmap is black

I'm trying to draw a map from a textfile onto a Bitmap, but the Bitmap is all black
First i load a textfile that looks like this (shortened):
0000000000 (200 width)
0111111110
0111100010
0000111110
0000111000
0000000000
(120 height)
Where "1" is ground and "0" is a wall, 1 should be white and 0 should be black.
Code:
public Map(String map) {
this.map = map;
init();
}
public void init() {
mapArray = new int[WIDTH*HEIGHT];
String[] splitMap = map.split("\n");
int width = splitMap[0].length();
int height = splitMap.length;
int[] colors = new int[WIDTH * HEIGHT];
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
int type = Integer.valueOf(splitMap[y].charAt(x));
setType(x, y, type);
if(type == WALL) {
setColor(x, y, Color.rgb(0, 0, 0), colors);
} else if(type == GROUND) {
setColor(x, y, Color.rgb(255, 255, 255), colors);
} else if(type == GOAL) {
setColor(x, y, Color.rgb(255, 255, 255), colors);
}
}
}
bitmap = Bitmap.createBitmap(colors, WIDTH, HEIGHT, Config.ARGB_8888);
}
public void setColor(int x, int y, int color, int[] colors) {
for(int y1 = 0; y1 < 4; y1++) {
for(int x1 = 0; x1 < 4; x1++) {
colors[(x + x1) + (y + y1) * WIDTH] = color;
}
}
}
public void setPixel(int x, int y, int color) {
for(int y1 = 0; y1 < 4; y1++) {
for(int x1 = 0; x1 < 4; x1++) {
bitmap.setPixel(x + x1, y + y1, color);
}
}
}
public void setType(int x, int y, int type) {
for(int y1 = 0; y1 < 4; y1++) {
for(int x1 = 0; x1 < 4; x1++) {
mapArray[(x + x1) + (y + y1) * WIDTH] = type;
}
}
}
public int getType(int x, int y) {
return mapArray[x + y * WIDTH];
}
public void doDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, null);
}
private final static int WALL = 0;
private final static int GROUND = 1;
private final static int GOAL = 2;
private final static int WIDTH = 800;
private final static int HEIGHT = 480;
private int[] mapArray = null;
private String map = null;
public Bitmap bitmap;
int type = Integer.valueOf(splitMap[y].charAt(x));
That's the line that's causing the problem.
scala> Integer.valueOf('1')
res3: java.lang.Integer = 49
scala> Integer.valueOf('0')
res4: java.lang.Integer = 48
The problem is that charAt gives you a char, which you then convert into an integer. What you really want to do is Integer.parseInt(splitMap[y].substring(x,x+1)
Integer.valueOf("0".substring(0,1))
res7: java.lang.Integer = 0
This illustrates a lesson though - never leave a switch statement without providing a default; similarly never leave an if/else if/... without leaving an else. Even if you're expecting never to hit it, you should put some noticeable error message if you do; it will help you debug.

Categories

Resources