/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Учёные утверждают, что семена подсолнуха растут в последовательности Фибоначчи. Википедия вам в помощь.
Пример для визуального просмотра последовательности. Без объяснений.
Компонент
package ru.alexanderklimov.testapplication;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
public class SunflowerView extends View {
public static final Paint sPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static int SEED_RADIUS;
private static int SCALE_FACTOR;
public static final double TAU = Math.PI * 2;
public static final double PHI = (Math.sqrt(5) + 1) / 2;
private int percent, maxSeeds;
private int xc;
private int yc;
public SunflowerView(Context context, AttributeSet attrs) {
super(context, attrs);
sPaint.setColor(0xFFF87306);
sPaint.setStyle(Style.FILL_AND_STROKE);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
onLayoutChange();
}
void onLayoutChange() {
int height = this.getHeight();
int width = this.getWidth();
SEED_RADIUS = 5;
SCALE_FACTOR = 7;
int maxR = Math.min(height, width) / 2;
int range = (maxR - SEED_RADIUS) / SCALE_FACTOR;
maxSeeds = range * range;
Log.i(VIEW_LOG_TAG, "max " + maxSeeds);
xc = width / 2;
yc = height / 2;
}
/**
* Draw the complete figure for the current number of seeds
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int numSeeds = maxSeeds * this.percent / 100;
for (int i = 0; i < numSeeds; i++) {
double theta = i * TAU / PHI;
double r = Math.sqrt(i) * SCALE_FACTOR;
int x = (int) Math.round(xc + r * Math.cos(theta));
int y = (int) Math.round(yc - r * Math.sin(theta));
drawSeed(x, y, canvas);
}
}
void setPercent(int percent) {
this.percent = percent;
}
/**
* Draw a small circle representing a seed centered at (x,y)
*
* @param x Center of the seed head
* @param y Center of the seed head
* @param canvas Canvas
*/
private void drawSeed(int x, int y, Canvas canvas) {
int sr = SEED_RADIUS;
canvas.drawArc(new RectF(x - sr, y - sr, x + sr, y + sr), 0, 360, false, sPaint);
}
}
Разметка
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<SeekBar
android:id="@+id/seekBar"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_gravity="center_horizontal" />
<ru.alexanderklimov.testapplication.SunflowerView
android:id="@+id/sunflowerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Активность.
package ru.alexanderklimov.testapplication;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
public class MainActivity extends ActionBarActivity implements
SeekBar.OnSeekBarChangeListener {
private SunflowerView mSunflowerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSunflowerView = (SunflowerView) findViewById(R.id.sunflowerView);
SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(this);
seekBar.setMax(100);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mSunflowerView.setPercent(progress);
// force redraw
mSunflowerView.postInvalidate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}