Canvas not updating in real device - android

I trying to make a draw line using canvas. It has 0 value when the Activity is loaded then I have a Button that has click listener to change the value and draw a line. It works in emulator well but when I run in my real device (android version 4.1) the canvas didn't change but I know that I hit the button because I put a toast inside the click listener. This is really weird.
Do anyone encounter the same problem before?
any thoughts will be highly appreciated.
Below is my Activity:
public class MainActivity extends Activity{
private Paint paintFree = new Paint();
private Paint paintLocal = new Paint();
private Paint paintRoaming = new Paint();
private int freeUsage = 0;
private int localUsage = 0;
private int roamingUsage = 0;
private int freeBarPoints;
private int localBarPoints;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
overridePendingTransition(0, 0);
line();
((Button) findViewById(R.id.btn1)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
freeUsage = 12;
localUsage = 1;
roamingUsage = 1;
line();
Log.i("Hit Btn1", "True");
Toast.makeText(v.getContext(), "Hit Btn1", Toast.LENGTH_SHORT).show();
}
});
}
class Draw extends View{
public Draw(Context context) {
super(context);
// TODO Auto-generated constructor stub
paintFree.setStrokeWidth(20f);
paintLocal.setStrokeWidth(20f);
paintRoaming.setStrokeWidth(20f);
if (freeUsage == 0){
paintFree.setColor(Color.GRAY);
} else {
paintFree.setColor(Color.rgb(70, 227, 78));
}
if (localUsage == 0){
paintLocal.setColor(Color.GRAY);
} else {
paintLocal.setColor(Color.rgb(238, 232, 102));
}
if (roamingUsage == 0){
paintRoaming.setColor(Color.GRAY);
} else {
paintRoaming.setColor(Color.rgb(101, 177, 231));
}
}
protected void onDraw(Canvas canvas) {
int maxBarLength = canvas.getWidth() * 4 / 5;
double totalBarPoints = freeUsage + localUsage + roamingUsage;
freeBarPoints = (int) Math.round(freeUsage * maxBarLength / totalBarPoints);
localBarPoints = (int) Math.round(localUsage * maxBarLength / totalBarPoints);
// need not compute the roaming bar points
int localStartX = 0 + Math.round(freeBarPoints);
int roamingStartX = (int) localStartX + Math.round(localBarPoints);
canvas.drawLine(0, 10, localStartX, 10, paintFree);
canvas.drawLine(localStartX, 10, roamingStartX, 10, paintLocal);
canvas.drawLine(roamingStartX, 10, maxBarLength, 10, paintRoaming);
}
}
public void line(){
Draw draw;
draw = new Draw(this);
((LinearLayout) findViewById(R.id.linear)).addView(draw);
}
}

You need to add an onMeasure implementation to your Draw class. Take a look at http://developer.android.com/training/custom-views/custom-drawing.html for more details.

Related

Android frames per second

Is it possible to get these values programmatically:
frames per second
how often the method onDraw() is called if the whole View is invalidated immediately.
1) Here is how I'm counting fps:
public class MyView extends View {
private int mFPS = 0; // the value to show
private int mFPSCounter = 0; // the value to count
private long mFPSTime = 0; // last update time
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (SystemClock.uptimeMillis() - mFPSTime > 1000) {
mFPSTime = SystemClock.uptimeMillis();
mFPS = mFPSCounter;
mFPSCounter = 0;
} else {
mFPSCounter++;
}
String s = "FPS: " + mFPS;
canvas.drawText(s, x, y, paint);
invalidate();
}
}
or just write your own object that would calculate this for you :)...
2) Try using
Log.d(tag, "onDraw() is called");
in your onDraw() method.

Android Animations and functions need to move to activity?

I am working on a small game with touch-motion, bluetooth, and menus. At the moment the code is implemented is in my custom View.
For example vectors of classes that store game-data, vectors for current data and later will there be some threads for animations and timers.
Yet there is no icons for "abilities", but I will implement them too.
Later will there be a process or a service with bluetooth which also calls methods which are at the moment in the custom view class.
I suppose this is a bad design - so I have no concrete idea how I can or should move my functions to for example the activity which holds the custom view and how to let the custom view and activity communicate with each other.
Maybe some of you have advice on what to do.
Here is the activity:
Gamecontroller_Activity:
public class Gamecontroller_Activity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Enter Function","Enter onCreate Gamecontroler_Activity");
setContentView(R.layout.activity_gamecontroller);
}
}
activity_gamecontroller.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.calma.Gamecontroller_View
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
And the big custom view class (shorted) Gamecontroller_View.java:
public class Gamecontroller_View extends View implements OnGestureListener{
//Touch
private PointF fingerpointer;
private int totalClickt;
private static final int SIZE = 60;
private Paint mPaint;
//Text Flashes
private Paint textPaint;
private Paint textPaintAction;
private String currentMsg;
private boolean currentMsgShow;
//Drawables (Pictures)
private int monsterscale;
private int monsterMinimumBorderX;
private int monsterMinimumBorderY;
private Bitmap bitmap1,bitmap2;
private HashMap<String, Bitmap> hashmapMonsterStandartBitmap;
Display Informations;
private DisplayMetrics displayMetrics;
private int xDisplayMaximum;
private int yDisplayMaximum;
//Monsters
private Vector<Monster> currentMonsters;
private int monsterCountGlobal;
//Player Stats
private Player playerMe;
//Enemy Player Stats
private Player playerEnemy;
public Gamecontroller_View(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public void initView(){
//display
displayMetrics = new DisplayMetrics();
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
float displayPixelFactor = displayMetrics.widthPixels/displayMetrics.densityDpi;
xDisplayMaximum = displayMetrics.widthPixels ;
yDisplayMaximum = displayMetrics.heightPixels - (3*getStatusBarSizes());
Log.i("Display","displaywidthpixels/displayMetrics: "+xDisplayMaximum);
//yDisplayMaximum
//Enemy Player
playerEnemy = new Player();
//Monsters
monsterscale =10;
monsterMinimumBorderX= Math.min(xDisplayMaximum,yDisplayMaximum)/monsterscale;
monsterMinimumBorderY= Math.max(xDisplayMaximum,yDisplayMaximum)/monsterscale;
hashmapMonsterStandartBitmap = new HashMap<String,Bitmap>();
currentMonsters = new Vector<Monster>();
monsterCountGlobal = 0;
Log.i("display","Monsterscale: "+monsterscale + " minMonsterBorder: "+monsterMinimumBorderX);
//init Touch detection and draw
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
mPaint.setMaskFilter(new BlurMaskFilter(15, Blur.OUTER));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
//init Text wich will be drawn
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(30);
textPaintAction = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaintAction.setTextSize(60);
currentMsg = "";
currentMsgShow = false;
//Futher init stuff
initPlayerMe();
initPlayerEnemy();
enemySpawn();
preloadImages();
showDebug();
}
public void initPlayerMe(){
//Player
playerMe = new Player();
playerMe.setlife(100);
playerMe.setMoney(0);
playerMe.setStrength(1);
}
public void initPlayerEnemy(){
//Player
playerEnemy = new Player();
playerEnemy.setlife(100);
playerEnemy.setMoney(0);
playerEnemy.setStrength(1);
}
public Vector<Dimension> findPlaceForMonsters(int n){
//First Collect allready existing Monster Coordinates
Vector <Dimension> currentPlaces = new Vector<Dimension>();
Vector <Dimension> newPlaces = new Vector<Dimension>();
for(int i = 0; i< currentMonsters.size();i++){
if (currentMonsters.elementAt(i) != null){
currentPlaces.add(currentMonsters.elementAt(i).getDimension());
}
}
for (int i=0; i < n ;i++){
newPlaces.add(new Dimension(getRandomNumberBetween(0, xDisplayMaximum-monsterMinimumBorderX),
getRandomNumberBetween(0, yDisplayMaximum-monsterMinimumBorderY)));
Log.i("randomPlaces","Point xy: " + newPlaces.lastElement().getX()+ " "+newPlaces.lastElement().getY());
}
Log.i("findPlfaceForMonsters",this.monsterMinimumBorderX+" "+this.monsterMinimumBorderY);
return newPlaces;
}
public void enemySpawn(){
int tempCount =0;
Vector<Dimension> newPlaces = findPlaceForMonsters(6);
for(int i=0; i < 2;i++){
currentMonsters.add(new MonsterMedium(monsterCountGlobal));
currentMonsters.lastElement().setDimension(new Dimension(newPlaces.elementAt(tempCount).getX(),newPlaces.elementAt(tempCount).getY(),monsterMinimumBorderX,monsterMinimumBorderY));
monsterCountGlobal++;
tempCount++;
}
for(int i=0; i < 2;i++){
currentMonsters.add(new MonsterSmall(monsterCountGlobal));
currentMonsters.lastElement().setDimension(new Dimension(newPlaces.elementAt(tempCount).getX(),newPlaces.elementAt(tempCount).getY(),monsterMinimumBorderX,monsterMinimumBorderY));
monsterCountGlobal++;
tempCount++;
}
for(int i=0; i < 2;i++){
currentMonsters.add(new MonsterHeavy(monsterCountGlobal));
currentMonsters.lastElement().setDimension(new Dimension(newPlaces.elementAt(tempCount).getX(),newPlaces.elementAt(tempCount).getY(),monsterMinimumBorderX,monsterMinimumBorderY));
monsterCountGlobal++;
tempCount++;
}
}
public void attackMonster(int id){
for (int i=currentMonsters.size()-1; i >= 0; i--){
if (currentMonsters.elementAt(i).getID() == id){
int restlife = currentMonsters.elementAt(i).setDamge(this.playerMe.getStrength());
lifeOfMonsterChanged(currentMonsters.elementAt(i).getID(),i,restlife);
break;
}
}
}
public void lifeOfMonsterChanged(int id,int index, int life){
if (life <= 0){
Log.i("MonsterTouchted", "Monster tot");
currentMonsters.removeElementAt(index);
}
else{
Log.i("MonsterTouchted", "Monster "+id+" restlife: "+life);
//effekte? (shake?) farbE?
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
Log.i("touch","event.getPointerID(): "+pointerId);
// get masked (not specific to a pointer) action
int maskedAction = event.getActionMasked();
switch (maskedAction) {
//Detection of a finger touch
case MotionEvent.ACTION_DOWN:
totalClickt = totalClickt+1;
//attackTheMonster(currentPlayer.attack());
fingerpointer = new PointF();
fingerpointer.x = event.getX(0);
fingerpointer.y = event.getY(0);
for (int i=currentMonsters.size()-1; i >= 0; i--){
if(currentMonsters.elementAt(i).getDimension().contains((int)fingerpointer.x, (int)fingerpointer.y)){
Log.i("MonsterTouchted","MonsterTouched: index: "+i);
attackMonster(currentMonsters.elementAt(i).getID());
break;
}
}
case MotionEvent.ACTION_POINTER_DOWN:
{
// Optional more than one finger
break;
}
case MotionEvent.ACTION_MOVE:
{ // a pointer was moved
if (fingerpointer != null) {
fingerpointer.x = event.getX(0);
fingerpointer.y = event.getY(0);
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: {
fingerpointer = null;
break;
}
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw all pointers
if (fingerpointer != null){
mPaint.setColor(colors[0]);
canvas.drawCircle(fingerpointer.x, fingerpointer.y, SIZE, mPaint);
}
// draw mosnters
for(int i=0; i < currentMonsters.size();i++){
if( currentMonsters.elementAt(i) != null){
canvas.drawBitmap(hashmapMonsterStandartBitmap.get(currentMonsters.elementAt(i).getImagePath()), currentMonsters.elementAt(i).getDimension().getX(), currentMonsters.elementAt(i).getDimension().getY(), mPaint); //bitmap, abstand left, abstand top, paint
} else{
Log.i("Failure","Draw monster nullpointer bei index: "+i);
}
}
//draw extra texts
if(currentMsgShow){
Log.i("onDraw","enter currenMsgShow");
if(displayMetrics != null){
int textsize = (int) textPaintAction.measureText(currentMsg);
int sidespacing = (displayMetrics.widthPixels - textsize)/2;
canvas.drawText(currentMsg, sidespacing, displayMetrics.heightPixels/5 , textPaintAction);
}
}
//Draw extratext
canvas.drawText( "Total Clickt: " + totalClickt, 10, 40 , textPaint);
}
}
Project:
Make those changes:
1) in your activity_gamecontroller.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.calma.Gamecontroller_View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/myGameController"/>
</RelativeLayout>
2) in your Gamecontroller_Activity:
public class Gamecontroller_Activity extends Activity {
Gamecontroller_View mGameControllerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Enter Function","Enter onCreate Gamecontroler_Activity");
setContentView(R.layout.activity_gamecontroller);
mGameControllerView = (Gamecontroller_View) findViewById(R.id.myGameController);
}
}
3) now you can call for example mGameControllerView.initPlayerMe(); from any method in your Gamecontroller_Activity .
This is an example:
public class Gamecontroller_Activity extends Activity {
Gamecontroller_View mGameControllerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Enter Function","Enter onCreate Gamecontroler_Activity");
setContentView(R.layout.activity_gamecontroller);
mGameControllerView = (Gamecontroller_View) findViewById(R.id.myGameController);
testMethod();
}
private void testMethod(){
mGameControllerView.enemySpawn();
}
}

Is this the right way to detect a touch on a rectangle in LibGdx ? Does not seem to be working for me

This is the code for my gamescreen where i want burst my ballon when its touched .
orientation is portrait.
but it does not seem to work for me.
public class GameScreen implements Screen {
final BB game;
private BitmapFont font;
private static final int no_of_frames = 2;
Texture ballonFrames;
TextureRegion[] burstFrames = new TextureRegion[no_of_frames];
Animation burstAnimation;
Array<Rectangle> ballons;
TextureRegion currentFrame;
long lastBallonTime;
int ballonBursted;
OrthographicCamera camera;
int ballonMissed;
Sound ballonBursting;
public GameScreen(final BB gam) {
this.game = gam;
ballonFrames = new Texture(Gdx.files.internal("ballon_burst.png"));
font = new BitmapFont(Gdx.files.internal("font.fnt"), false);
ballonBursting = Gdx.audio.newSound(Gdx.files
.internal("BallonBursting.wav"));
TextureRegion[][] tmp = TextureRegion.split(ballonFrames,
ballonFrames.getWidth() / 2, ballonFrames.getHeight());
burstFrames[0] = tmp[0][0];
burstFrames[1] = tmp[0][1];
burstAnimation = new Animation(3.0f, burstFrames);
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
ballons = new Array<Rectangle>();
spawnBallon();
}
private void spawnBallon() {
Rectangle ballon = new Rectangle();
ballon.x = MathUtils.random(0, 800 - 64); //
ballon.y = 0;
ballon.width = 40;
ballon.height = 80;
ballons.add(ballon);
lastBallonTime = TimeUtils.nanoTime();
}
private boolean ballonBursted(Rectangle ballon) {
Vector2 touch = new Vector2(Gdx.input.getX(), Gdx.input.getY());
if (ballon.contains(touch))
return true;
else
return false;
}
#Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor(0, 0, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
InputProcessor processor;
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
font.draw(game.batch, "Ballon Bursted :" + ballonBursted, 0, 700);
font.draw(game.batch, "Ballon Missed:" + ballonMissed, 275, 700);
for (Rectangle ballon : ballons) {
game.batch.draw(burstFrames[0], ballon.x, ballon.y);
}
if (TimeUtils.nanoTime() - lastBallonTime > 1000000000) {
spawnBallon(); // a ballon every second
}
Iterator<Rectangle> iter = ballons.iterator();
while (iter.hasNext()) {
Rectangle ballon = iter.next();
ballon.y = ballon.y + 100 * Gdx.graphics.getDeltaTime();
if (ballonBursted(ballon) == true) {
ballonBursted++;
game.batch.draw(burstFrames[1], ballon.x, ballon.y);
ballonBursting.play();
iter.remove();
}
else if (ballon.y + 64 > 800) {
iter.remove();
ballonMissed++;
}
}
if (ballonMissed > 5) {
game.setScreen(new ScoreScreen(game, ballonBursted));
}
game.batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
ballonFrames.dispose();
ballonBursting.dispose();
game.batch.dispose();
}
I am using animation class of libgdx to change my image of ballon to the one where its bursted .
I am fairly new to libgdx and unable to figure out what wrong am i doing here .
Should i create a table and layout my ballon elements as actor?
Try something like this:
private boolean ballonBursted(Rectangle ballon) {
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
if (ballon.contains(touchPos.x, touchPos.y))
return true;
else
return false;
}
please read this https://stackoverflow.com/a/18555705/2158970
If I understand it right you just want to know if the touchpoint is contained in the Rectangle ballon. Then you could use Rectangle#contains() method:
ballon.contains(Gdx.input.getX(), Gdx.input.getY());
see also the source code of Rectangle class

delaye canvas update using Timer Class

I created a view type-class in which onDraw() method i am drawing some boxes. The thing in which i am not getting succeed is that, i want to disappear these boxes after 3-5 second. For this i am using timer and timerTask. In TimerTask i am overriding the method run() which changes the color of Paint object to white. The background color is also white so it will give the effect that boxes are erased. Can you guys help me out??
public class PlayView extends View
{
private float width,height;
private int touchatX, touchatY;
private boolean isanyBox, clearCanvas;
private Point points[];
private Paint box;
Timer timer;
TimerTask task;
// Set the number of points to be generated so we print that number of boxes on the board
public void nPoints(int n)
{
points = new Point[n];
box = new Paint();
box.setColor(Color.BLUE);
}
public void init()
{
isanyBox = false;
clearCanvas = true;
timer = new Timer();
task = new TimerTask()
{
#Override
public void run()
{
box.setColor(Color.WHITE);
}
};
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
// TODO Auto-generated method stub
width = w/6f;
height = h/6f;
Log.d("playview", getWidth()+" "+getHeight());
super.onSizeChanged(w, h, oldw, oldh);
}
public PlayView(Context context)
{
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
init();
}
// Randomly generate the points and draw boxes on these points
public void generatePoints(int np)
{
Time sec = new Time();
Random random_Xpoints = new Random();
Random random_Ypoints = new Random();
random_Xpoints.setSeed(sec.second);
random_Ypoints.setSeed(sec.second);
nPoints(np); // set the number of points to be generated
for(int i=0; i<np; i++)
{
points[i] = new Point();
points[i].setX( ((random_Xpoints.nextInt(getWidth())/(int)width)*(int)width));
points[i].setY( ((random_Ypoints.nextInt(getHeight())/(int)height)*(int)height));
Log.d("Point "+1, points[i].getX()+" "+points[i].getY());
}
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
// TODO Auto-generated method stub
invalidate();
isanyBox = true;
touchatX = (int) ((int) (event.getX()/width)*width);
touchatY = (int) ((int) (event.getY()/height)*height);
Log.d("onTouchEvent", event.getX()+" "+event.getY()+" "+touchatX+" "+touchatY);
invalidate();
return super.onTouchEvent(event);
}
public void onDraw(Canvas canvas)
{
Paint lineColor = new Paint();
lineColor.setColor(Color.BLACK);
//Box property
Paint boxColor = new Paint();
boxColor.setColor(Color.BLUE);
//Draw horizontal lines
for(int i=0; i<6; i++)
{
canvas.drawLine(0, i*height, getWidth(), i*height, lineColor);
}
//Draw vertical lines
for(int j=0; j<6; j++)
{
canvas.drawLine(j*width, 0, j*width, getHeight(), lineColor);
}
if(isanyBox)
{
canvas.drawRect(touchatX+2, touchatY+2, touchatX+width-1, touchatY+height-2, boxColor);
}
generatePoints(5);
for(int j=0; j<5; j++)
{
canvas.drawRect(points[j].getX()+2, points[j].getY()+2, points[j].getX()+width-1, points[j].getY()+height-2, box);
Log.d("BoxColor", ""+box);
}
if(clearCanvas)
{
timer.schedule(task, 3000);
clearCanvas = false;
invalidate();
}
}
}
call invalidate(); after changing the color. This will force the system to call onDraw() again.
#Override
public void run()
{
box.setColor(Color.WHITE);
invalidate();
}
edit:
I've never liked timers and now I now why, that's why and also for some reason the Android team suggests people not to use them as it can be read here: http://developer.android.com/reference/java/util/Timer.html
because you're on a class that extends View, you should just call postDelayed();
if(clearCanvas)
{
clearCanvas = false;
postDelayed(new Runnable{
#Override
public void run(){
box.setColor(Color.WHITE);
invalidate();
}
}, 3000);
}

Setting size of a triangle (Android)

So, I have created an android activity that draws a triangle on the canvas. I also added 4 menus(Color, Enlarge, Shrink, and Reset) to the VM. The color works fine but I'm not quite sure how to resize a triangle in android once that menu button is pressed.The assignment says to just fix the top point of the triangle, and then change the coordinates of the bottom two points of the triangle. Can anyone point me in the right direction on how to do that in Android?
Here's my code, although the implementation of enlarge, shrink, and reset are set up to work with a circle(project I did before), not a triangle. Please note that the "Color" menu works so no need to do that.
public class MainActivity extends Activity
{
final Context context = this;
private Graphics graphic;
private Dialog radiusDialog; //Creates dialog box declaration
private SeekBar red;
private SeekBar green;
private SeekBar blue;
private Button radiusButton;
private TextView progress1;
private TextView progress2;
private TextView progress3;
private TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
graphic = new Graphics(this); //Create new instance of graphics view
setContentView(graphic); //Associates customized view with current screen
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) //This acts as a menu listener to override
{
switch(item.getItemId()) //returns menu item
{
case R.id.Color:
showDialog();
break;
case R.id.Shrink:
graphic.setRadius(graphic.getRadius() -1);
graphic.invalidate();
break;
case R.id.Enlarge:
graphic.setRadius(graphic.getRadius() +1);
graphic.invalidate();
break;
case R.id.Reset:
graphic.setColor(Color.CYAN);
graphic.setRadius(75);
graphic.invalidate();
break;
}
return super.onOptionsItemSelected(item);
}
void showDialog() //creates memory for dialog
{
radiusDialog = new Dialog(context);
radiusDialog.setContentView(R.layout.draw_layout); //binds layout file (radius) with current dialog
radiusDialog.setTitle("Select Color:");
red = (SeekBar)radiusDialog.findViewById(R.id.seekBar1);
green = (SeekBar)radiusDialog.findViewById(R.id.seekBar2);
blue = (SeekBar)radiusDialog.findViewById(R.id.seekBar3);
progress1 = (TextView)radiusDialog.findViewById(R.id.textView2);
progress2 = (TextView)radiusDialog.findViewById(R.id.textView4);
progress3 = (TextView)radiusDialog.findViewById(R.id.textView6);
mychange redC = new mychange();
red.setOnSeekBarChangeListener(redC);
mychange greenC = new mychange();
green.setOnSeekBarChangeListener(greenC);
tv = (TextView)radiusDialog.findViewById(R.id.textView7);
mychange c = new mychange();
blue.setOnSeekBarChangeListener(c);
radiusButton = (Button) radiusDialog.findViewById(R.id.button1);
radiusButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int color = Color.rgb(red.getProgress(), green.getProgress(), blue.getProgress());
radiusDialog.dismiss();
setContentView(R.layout.activity_main);
setContentView(graphic);
graphic.setColor(color);//Create new instance of graphics view
graphic.invalidate();
}
});
radiusDialog.show(); //shows dialog on screen
}
public class mychange implements OnSeekBarChangeListener{
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
int color = Color.rgb(red.getProgress(), green.getProgress(), blue.getProgress());
tv.setBackgroundColor(color);
progress1.setText(String.valueOf(red.getProgress()));
progress2.setText(String.valueOf(green.getProgress()));
progress3.setText(String.valueOf(blue.getProgress()));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
}
Graphics Class to draw triangle
public class Graphics extends View
{
private Paint paint;
private int radius;
private int color;
public void setColor(int color)
{
this.color = color;
}
public Graphics(Context context) //creates custom view (constructor)
{
super(context);
paint = new Paint(); //create instance of paint
color = Color.CYAN;
paint.setStyle(Paint.Style.FILL); //draw filled shape
radius = 75;
}
#Override
protected void onDraw(Canvas canvas) //override onDraw method
{
super.onDraw(canvas);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
Path path = new Path();
path.moveTo(230, 200);
path.lineTo(330, 300);
path.lineTo(130, 300);
path.close();
canvas.drawPath(path, paint);
}
void setRadius(int radius)
{
this.radius = radius;
invalidate(); //just like repaint method
}
public int getRadius()
{
return radius;
}
}
If the top coordinate remains fixed, you can change the height of the triangle to shrink/enlarge it.
Lets say the triangle is equilateral - all 3 sides have the same length. In this case:
So if the top vertex coordinates are (x, y), the bottom coordinates will be:
(x - side / 2, y + h)
And:
(x + side / 2, y + h)
So your path code should be written as:
float side = Math.sqrt(3) / 2 * height;
Path path = new Path();
path.moveTo(x, y);
path.lineTo(x - side / 2, y + height);
path.lineTo(x + side / 2, y + height);
path.close();

Categories

Resources