This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
When I run my android app, it crashes and says that Android app has stopped. It also gives this error message:
java.lang.NullPointerException: Attempt to invoke virtual method 'com.esimerkki.doodl2.DoodleView com.esimerkki.doodl2.FirstFragment.getDoodleView()' on a null object reference
What is wrong with this? Is the reference really null? How could I make this work? I thought these original settings in doodleView have start values?
Here is the code of doodleView class:
package com.esimerkki.doodl2;
import android.content.Context;
import android.view.View;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.Toast;
import androidx.print.PrintHelper;
import java.util.HashMap;
import java.util.Map;
public class DoodleView extends View {
public DoodleView(Context context, Paint paintScreen, Paint paintLine) {
super( context );
this.paintScreen = paintScreen;
this.paintLine = paintLine;
}
private static final float TOUCH_TOLERANCE = 10;
private Bitmap bitmap; // drawing area
private Canvas bitmapCanvas; //
private final Paint paintScreen; //
private final Paint paintLine; //
private final Map<Integer, Path> pathMap = new HashMap<>();
private final Map<Integer, Point> previousPointMap = new HashMap<>();
public DoodleView(Context context, AttributeSet attrs) {
super(context, attrs); // kutsutaan yliluokanalustajaa
paintScreen = new Paint(); // bittikartan näyttämiseen ruudulla
paintLine = new Paint();
paintLine.setAntiAlias(true);
paintLine.setColor(Color.BLACK);
paintLine.setStyle(Paint.Style.STROKE);
paintLine.setStrokeWidth(5);
paintLine.setStrokeCap(Paint.Cap.ROUND);
#Override
public void onSizeChanged(int w, int h, int OldW, int oldH) {
bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
bitmap.eraseColor(Color.WHITE);
}
public void clear() {
pathMap.clear();
previousPointMap.clear();
bitmap.eraseColor(Color.WHITE);
invalidate();
}
public void setDrawingColor(int color) {
paintLine.setColor(color);
}
public int getDrawingColor() {
return paintLine.getColor();
}
public void setLineWidth(int width) {
paintLine.setStrokeWidth(width);
}
public int getLineWidth() {
return (int) paintLine.getStrokeWidth();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
for (Integer key : pathMap.keySet())
canvas.drawPath(pathMap.get(key), paintLine); // piirretään viiva
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked(); // tapahtumatyyppi
int actionIndex = event.getActionIndex(); // osoitin
if (action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_POINTER_DOWN) {
touchStarted(event.getX(actionIndex), event.getY(actionIndex),
event.getPointerId(actionIndex));
}
else if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_POINTER_UP) {
touchEnded(event.getPointerId(actionIndex));
}
else {
touchMoved(event);
}
invalidate();
return true;
}
private void touchStarted(float x, float y, int lineID) {
Path path; // tallennetaan tietyn id:n polku
Point point; // tallennetaan polun viimeinen piste
if (pathMap.containsKey(lineID)) {
path = pathMap.get(lineID);
path.reset();
point = previousPointMap.get(lineID);
}
else {
path = new Path();
pathMap.put(lineID, path);
point = new Point();
previousPointMap.put(lineID, point);
}
path.moveTo(x, y);
point.x = (int) x;
point.y = (int) y;
}
private void touchMoved(MotionEvent event) {
for (int i = 0; i < event.getPointerCount(); i++) {
// luetaan pointtein id ja indeksi
int pointerID = event.getPointerId(i);
int pointerIndex = event.findPointerIndex(pointerID);
if (pathMap.containsKey(pointerID)) {
float newX = event.getX(pointerIndex);
float newY = event.getY(pointerIndex);
Path path = pathMap.get(pointerID);
Point point = previousPointMap.get(pointerID);
// lasketaan kuinka kauas liikuttu
float deltaX = Math.abs(newX - point.x);
float deltaY = Math.abs(newY - point.y);
if (deltaX >= TOUCH_TOLERANCE || deltaY >= TOUCH_TOLERANCE) {
path.quadTo(point.x, point.y, (newX + point.x) / 2,
(newY + point.y) / 2);
point.x = (int) newX;
point.y = (int) newY;
}
}
}
}
private void touchEnded(int lineID) {
Path path = pathMap.get(lineID);
bitmapCanvas.drawPath(path, paintLine);
path.reset(); // tyhjennetään polku
}
public void saveImage() {
final String name = "Doodlz" + System.currentTimeMillis() + ".jpg";
String location = MediaStore.Images.Media.insertImage(
getContext().getContentResolver(), bitmap, name,
"Doodlz Drawing"
);
if (location != null) {
Toast message = Toast.makeText(getContext(),
R.string.message_saved,
Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
message.getYOffset() / 2);
message.show();
}
else {
Toast message = Toast.makeText(getContext(),
R.string.message_error_saving, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
message.getYOffset() / 2);
message.show();
}
}
public void printImage() {
if (PrintHelper.systemSupportsPrint()) {
PrintHelper printHelper = new PrintHelper(getContext());
printHelper.setScaleMode(printHelper.SCALE_MODE_FIT);
printHelper.printBitmap("Doodlz Imate", bitmap);
}
else {
Toast message = Toast.makeText(getContext(),
R.string.message_error_printing, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
message.getYOffset() / 2);
message.show();
}
}
}
And here is the code of a LineWidthFragment class:
package com.esimerkki.doodl2;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
//import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import androidx.fragment.app.DialogFragment;
public class LineWidthFragment extends DialogFragment {
private ImageView widthImageView;
#Override
public Dialog onCreateDialog(Bundle bundle) {
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
View lineWidthDialogView =
getActivity().getLayoutInflater().inflate(
R.layout.fragment_line_width, null);
builder.setView(lineWidthDialogView); // lisätään GUI dialogiin
builder.setTitle(R.string.title_line_width_dialog);
widthImageView = (ImageView) lineWidthDialogView.findViewById(
R.id.widthImageView);
final DoodleView doodleView = getDoodleFragment().getDoodleView();
final SeekBar widthSeekBar = (SeekBar)
lineWidthDialogView.findViewById(R.id.widthSeekBar);
widthSeekBar.setOnSeekBarChangeListener(lineWidthChanged);
widthSeekBar.setProgress(doodleView.getLineWidth());
builder.setPositiveButton(R.string.button_set_line_width,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
doodleView.setLineWidth(widthSeekBar.getProgress());
}
}
);
return builder.create();
}
private FirstFragment getDoodleFragment() {
return (FirstFragment) getChildFragmentManager().findFragmentById(
R.id.doodleFragment);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
FirstFragment fragment = getDoodleFragment();
if (fragment != null)
fragment.setDialogOnScreen(true);
}
#Override
public void onDetach() {
super.onDetach();
FirstFragment fragment = getDoodleFragment();
if (fragment != null)
fragment.setDialogOnScreen(false);
}
private final OnSeekBarChangeListener lineWidthChanged =
new OnSeekBarChangeListener() {
final Bitmap bitmap = Bitmap.createBitmap(
400, 100, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap); // piirtää bittikarttaan
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Paint p = new Paint();
p.setColor(
getDoodleFragment().getDoodleView().getDrawingColor());
p.setStrokeCap(Paint.Cap.ROUND);
p.setStrokeWidth(progress);
bitmap.eraseColor(
getResources().getColor(android.R.color.transparent,
getContext().getTheme()));
canvas.drawLine(30, 50, 370, 50, p);
widthImageView.setImageBitmap(bitmap);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) { // tarvitaan
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) { // tarvitaan
}
};
}
Your error says the following:
null object reference
This means that 1 object gives the value 0.
Your code looks fine but if you rewrite the code once again you may solve the mistake.
It is caused by a pitty error in your code.
When rewriting it. You can find that error.
Even if this was a bug with some plugin or anything else.
Also after you rewrote it, if you get the same error then you need to look onto a reference.
I am working on a android launcher that shows the 1st 4 app icons in a grid view however I'm trying to display the folder as a square shape it's showing up as a circle shape...
heres my code:
package appname.launcher.util;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.view.View;
import Appname.launcher.activity.Home;
public class GroupIconDrawable extends Drawable{
private int outlinepad;
Bitmap[] icons;
public int iconSize;
Paint paint;
Paint paint2;
Paint paint4;
private int iconSizeDiv2;
private int padding;
private float scaleFactor = 1;
private boolean needAnimate,needAnimatScale;
public View v;
private float sx = 1;
private float sy = 1 ;
public GroupIconDrawable(Bitmap[] icons,int size){
init(icons,size);
}
private void init(Bitmap[] icons,int size){
this.icons = icons;
this.iconSize = size;
iconSizeDiv2 = Math.round(iconSize / 2f);
padding = iconSize /25;
this.paint = new Paint();
paint.setColor(Color.WHITE);
paint.setAlpha(200);
paint.setAntiAlias(true);
this.paint4 = new Paint();
paint4.setColor(Color.WHITE);
paint4.setAntiAlias(true);
paint4.setFlags(Paint.ANTI_ALIAS_FLAG);
paint4.setStyle(Paint.Style.STROKE);
outlinepad = Tools.convertDpToPixel(2, Home.desktop.getContext());
paint4.setStrokeWidth(outlinepad);
this.paint2 = new Paint();
paint2.setAntiAlias(true);
paint2.setFilterBitmap(true);
}
public GroupIconDrawable(Bitmap[] icons,int size,View v){
init(icons,size);
this.v =v;
}
public void popUp(){
sy = 1;
sx = 1;
needAnimate = true;
needAnimatScale = true;
invalidateSelf();
}
public void popBack(){
needAnimate = false;
needAnimatScale = false;
invalidateSelf();
}
#Override
public void draw(Canvas canvas) {
canvas.save();
if (needAnimatScale){
scaleFactor = Tools.clampFloat(scaleFactor-0.09f,0.5f,1f);
}else {
scaleFactor = Tools.clampFloat(scaleFactor+0.09f,0.5f,1f);
}
if (v == null)
canvas.scale(scaleFactor,scaleFactor,iconSize/2,iconSize/2);
else
canvas.scale(scaleFactor,scaleFactor,iconSize/2,v.getHeight() / 2);
if (v!= null)
canvas.translate(0,v.getHeight()/2-iconSize/2);
Path clipp = new Path();
clipp.addCircle(iconSize / 2,iconSize / 2,iconSize / 2-outlinepad, Path.Direction.CW);
canvas.clipPath(clipp, Region.Op.REPLACE);
canvas.drawBitmap(icons[0],null,new Rect(padding,padding, iconSizeDiv2-padding, iconSizeDiv2-padding),paint2);
canvas.drawBitmap(icons[1],null,new Rect(iconSizeDiv2+padding,padding,iconSize-padding, iconSizeDiv2-padding),paint2);
canvas.drawBitmap(icons[2],null,new Rect(padding, iconSizeDiv2+padding, iconSizeDiv2-padding,iconSize-padding),paint2);
canvas.drawBitmap(icons[3],null,new Rect(iconSizeDiv2+padding, iconSizeDiv2+padding,iconSize-padding,iconSize-padding),paint2);
canvas.clipRect(0,0,iconSize,iconSize, Region.Op.REPLACE);
canvas.restore();
if (needAnimate){
paint2.setAlpha(Tools.clampInt(paint2.getAlpha()-25,0,255));
invalidateSelf();
}else if (paint2.getAlpha() != 255){
paint2.setAlpha(Tools.clampInt(paint2.getAlpha()+25,0,255));
invalidateSelf();
}
}
#Override
public void setAlpha(int i) {}
#Override
public void setColorFilter(ColorFilter colorFilter) {}
#Override
public int getOpacity() {return 0;}
}
I think its because of the > clipp.addCircle(iconSize / 2,iconSize /
2,iconSize / 2-outlinepad,> Path.Direction.CW); code but i'm not sure
how would I make it a square instead of a circle?
change your clipp Path usage from addCircle to be addRect(float left, float top, float right, float bottom, Path.Direction dir)
I have two activities: a menu, and a game. I have them both set up as surface views, and when I click the "start" button on the menu activity, it starts the game activity. Then I want it to save the score and return to the menu activity when the player crashes. Both activities have separate threads that start with the activity, so when I tried to re-launch the menu activity from the game, I was getting an exception that the thread was already started. So to avoid this, I had the game activity finish the menu activity when it started so that relaunching the menu activity would also restart the thread. Now I'm getting an exception that the canvas is already locked. Do I need to unlock the canvas before finishing the activity? And is there a better way for me to handle switching between activities?
MainActivity:
package com.mikey.******;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
public static Activity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this;
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new GamePanel(this));
}
}
GamePanel Layout:
package com.mikey.*****;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.Random;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private static SharedPreferences prefs;
public static int width;
public static int height;
public static int screenX, screenY;
private Canvas c;
private MainThread thread;
private Background bg;
private Scoreboard sb;
public int moveSpeed = 10;
private Player player;
private ArrayList<Smokepuff> smoke;
private Plunger plunger;
private Plunger plunger1;
private long smokeStart;
private long smokeTime;
public int score = 0;
public boolean isPlaying;
private Bitmap bgImg;
private Bitmap b;
private int scaleFactor = 2;
private long timer;
private long timeStart;
private Paint paint;
private ArrayList<Coin> coin;
private long coinTime;
private int coinDelay;
private Bitmap coinImg;
public boolean playable;
public int distance;
private int plungerDelay;
private int plungerReset;
private long plungerTime;
private int coinSet;
private Menu endMenu;
public GamePanel(Context context){
super(context);
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenX=size.x;
screenY=size.y;
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
setFocusable(true);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(40);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
int count = 0;
while(retry&&count<1000){
try{thread.setRunning(false);
thread.join();
retry=false;
}catch(InterruptedException e){}
count++;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder){
thread.setRunning(true);
thread.start();
//moveSpeed = -20;
bgImg = BitmapFactory.decodeResource(getResources(), R.drawable.bg2);
width = bgImg.getWidth();
height = bgImg.getHeight();
bg = new Background(bgImg);
sb = new Scoreboard(getContext());
plunger = new Plunger(BitmapFactory.decodeResource(getResources(), R.drawable.plunger));
plunger1 = new Plunger(BitmapFactory.decodeResource(getResources(),R.drawable.plunger));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.potty));
smoke = new ArrayList<Smokepuff>();
coin = new ArrayList<Coin>();
//Random r = new Random();
coinImg = BitmapFactory.decodeResource(getResources(),R.drawable.coin2);
coin.add(new Coin(coinImg));
coinDelay = 5;
playable = true;
}
#Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction()==MotionEvent.ACTION_DOWN){
if(!isPlaying&&playable){
isPlaying=true;
smokeStart = System.nanoTime();
timeStart = System.nanoTime();
plungerReset = distance;
plungerDelay = 100;
coinSet = distance;
}
player.setAccelerate(true);
player.setUp(true);
return true;
}
else if(event.getAction()==MotionEvent.ACTION_UP){
player.setAccelerate(false);
player.setUp(false);
return true;
}
return super.onTouchEvent(event);
}
public void update(){
if(isPlaying) {
timer = (System.nanoTime() - timeStart) / 1000000;
distance+=(timer*moveSpeed)/1000;
if (timer > 50) {
if(player.getAccelerate()&&!player.maxAlt) {
moveSpeed += 1;
}else if(!player.getAccelerate()&&!player.maxAlt){
if(moveSpeed>0){
if(distance<200){
moveSpeed-=.05;
}else {
moveSpeed -= .18;
}
}
}
timeStart = System.nanoTime();
}
//moveSpeed += score;
smokeTime = (System.nanoTime()-smokeStart)/1000000;
if(smokeTime>100){
smoke.add(new Smokepuff(player.getX(),player.getY()+5));
smokeStart=System.nanoTime();
}
if(distance>300&&plungerDelay+plungerReset<distance){
plunger.setX(screenX);
plunger1.setX(screenX+500);
Random q = new Random();
plungerDelay = q.nextInt(150)+100;
plungerReset = distance;
}
if(distance-coinSet>coinDelay) {
Random z = new Random();
int num = z.nextInt(3) + 1;
for (int i = 0; i < num; i++) {
coin.add(new Coin(coinImg));
}
Random r = new Random();
coinDelay = r.nextInt(50) + 1;
coinSet=distance;
}
plunger.update(moveSpeed);
plunger1.update(moveSpeed);
int dy = player.update();
bg.update(moveSpeed, dy);
for(int i=0;i<coin.size();i++){
coin.get(i).update(moveSpeed);
if(coin.get(i).getX()<-10){
coin.remove(i);
}else if (collision(coin.get(i), player)) {
coin.remove(i);
score+=10;
}
}
if(collision(player,plunger)){
plunger.setX(player.getX() + player.getWidth() - 1);
plunger.setY(player.getY()+player.height/2);
if(!plunger.attached){
plungerTime = System.nanoTime();
plunger.attached = true;
}
if(moveSpeed>10){
moveSpeed--;
}
}
if(plunger.getX()<-100){
plunger.reset();
}
if(collision(player,plunger1)){
plunger1.setX(player.getX() + player.getWidth()-1);
plunger1.setY(player.getY()+player.height/2);
if(!plunger1.attached) {
plungerTime = System.nanoTime();
plunger1.attached=true;
}
if(moveSpeed>10){
moveSpeed--;
}
}
if(plunger1.getX()<-100){
plunger1.reset();
}
if((System.nanoTime()-plungerTime)/1000000>750){
if(collision(plunger,player)){
plunger.reset();
plunger.attached = false;
}
if(collision(plunger1,player)){
plunger1.reset();
plunger1.attached = false;
}
}
for(int i=0;i<smoke.size();i++){
smoke.get(i).update(moveSpeed);
if(smoke.get(i).getX()<-10||smoke.get(i).getY()<0){
smoke.remove(i);
}
}
sb.update(score, distance);
if(2*player.getY()>screenY-300){
SharedPreferences.Editor editor = prefs.edit();
if(!prefs.contains("highscore")) {
editor.putInt("highscore", score);
//return;
}else if(prefs.getInt("highscore",0)<score){
editor.putInt("highscore",score);
}
editor.commit();
isPlaying=false;
playable=false;
endGame();
//NavUtils.navigateUpFromSameTask(MainActivity.activity);
Intent intent = new Intent(getContext(),Menu.class);
getContext().startActivity(intent);
}
}
}
public boolean collision(GameObject a, GameObject b){
if(Rect.intersects(a.getRect(),b.getRect())){
return true;
}
return false;
}
#Override
public void draw(Canvas canvas){
final float scaleFactorX = (float) 2;
final float scaleFactorY = (float) 2;
if(canvas!=null){
c = canvas;
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
for(Coin c:coin){
c.draw(canvas);
}
plunger.draw(canvas);
plunger1.draw(canvas);
for(Smokepuff sp:smoke){
sp.draw(canvas);
}
player.draw(canvas);
if((isPlaying&&playable)||(!isPlaying&&!playable)) {
sb.draw(canvas);
}
canvas.restoreToCount(savedState);
canvas.drawText(Integer.toString(moveSpeed), screenX-100,40,paint);
}
//bg.draw(canvas);
}
public void endGame(){
SharedPreferences.Editor editor = prefs.edit();
if(!prefs.contains("highscore")) {
editor.putInt("highscore", score);
return;
}else if(prefs.getInt("highscore",0)<score){
editor.putInt("highscore",score);
}
editor.commit();
Intent intent = new Intent(getContext(),Menu.class);
getContext().startActivity(intent);
}
}
Menu Activity:
package com.mikey.*****;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
public class Menu extends Activity{
//private ImageButton upgrade;
private int screenY;
private int screenX;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
screenY = getWindow().getDecorView().getHeight();
screenX = getWindow().getDecorView().getWidth();
setContentView(new MenuLayout(this));
/*upgrade = (ImageButton) findViewById(R.id.upgrade);
upgrade.setX(-150);
upgrade.setY(1080-130);
upgrade.setScaleX(4);
upgrade.setScaleY(4);*/
}
#Override
protected void onPause(){
super.onPause();
finish();
}
}
MenuLayout:
package com.mikey.*****;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.preference.PreferenceManager;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.Random;
public class MenuLayout extends SurfaceView implements SurfaceHolder.Callback {
private static SharedPreferences prefs;
private MenuThread thread;
private boolean played;
private int screenX, screenY;
private Bitmap upgrade;
private Bitmap map;
private Bitmap bg;
private Bitmap launch;
private Bitmap potty;
private Bitmap cloudA;
private Bitmap cloudB;
private ArrayList<Cloud> cloud;
private UpgradeBtn upgradeBtn;
private MapBtn mapBtn;
private LaunchBtn launchBtn;
//private Paint bg;
private Paint feature;
private Paint border;
private Paint featureRad;
private Paint stick;
private Paint text;
private Paint shadow;
private int x;
private int y;
private boolean upg;
private boolean showmap;
private boolean start;
public MenuLayout(Context context){
super(context);
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
getHolder().addCallback(this);
thread = new MenuThread(getHolder(),this);
setFocusable(true);
screenX=size.x;
screenY=size.y;
upgrade = BitmapFactory.decodeResource(getResources(),R.drawable.blueprint);
map = BitmapFactory.decodeResource(getResources(),R.drawable.map);
launch = BitmapFactory.decodeResource(getResources(),R.drawable.launch);
bg = BitmapFactory.decodeResource(getResources(),R.drawable.menu_bg);
potty = BitmapFactory.decodeResource(getResources(),R.drawable.potty1);
cloudA = BitmapFactory.decodeResource(getResources(),R.drawable.cloud1);
cloudB = BitmapFactory.decodeResource(getResources(),R.drawable.cloud2);
upgradeBtn = new UpgradeBtn(upgrade,screenY);
mapBtn = new MapBtn(map);
launchBtn = new LaunchBtn(launch,screenX,screenY);
cloud = new ArrayList<>();
for(int i =0;i<4;i++){
addCloud();
}
start = true;
//bg = new Paint();
//bg.setColor(Color.WHITE);
shadow = new Paint();
shadow.setAntiAlias(true);
shadow.setColor(Color.WHITE);
shadow.setTextSize(45.0f);
shadow.setStrokeWidth(2.0f);
shadow.setStyle(Paint.Style.STROKE);
shadow.setShadowLayer(10.0f, 20.0f, -20.0f, Color.BLACK);
Shader shader = new LinearGradient(0, 0, 0, 90, Color.LTGRAY, Color.DKGRAY, Shader.TileMode.CLAMP);
feature = new Paint();
feature.setShader(shader);
border = new Paint();
border.setColor(Color.BLACK);
border.setStyle(Paint.Style.STROKE);
border.setStrokeWidth(8);
Shader shader1 = new RadialGradient(screenX-60,60,150,Color.LTGRAY,Color.DKGRAY, Shader.TileMode.MIRROR);
featureRad = new Paint();
featureRad.setShader(shader1);
stick = new Paint();
stick.setColor(Color.BLACK);
stick.setStrokeWidth(20);
text = new Paint();
text.setColor(Color.WHITE);
text.setTextSize(50);
}
public void addCloud(){
Bitmap img;
Random r = new Random();
Random p = new Random();
Random q = new Random();
int s = r.nextInt(10);
if(s>5){
Matrix m = new Matrix();
float h = r.nextFloat()+1;
m.setRectToRect(new RectF(0, 0, cloudA.getWidth(), cloudA.getHeight()),
new RectF(0, 0, cloudA.getWidth()*h, cloudA.getHeight()*h), Matrix.ScaleToFit.CENTER);
img = Bitmap.createBitmap(cloudA, 0, 0, cloudA.getWidth(), cloudA.getHeight(), m, true);
}else{
img = cloudB;
}
if(start){
x = -img.getWidth();
}
else{
x = p.nextInt(screenX);
}
cloud.add(new Cloud(img,x,p.nextInt(screenY-750)+100,q.nextInt(8)+1,screenX));
}
public Bitmap highlightImage(Bitmap src, int color,boolean x, boolean y) {
int xMod;
int yMod;
if(x){
xMod = 4;
}else{
xMod = -1;
}
if(y){
yMod = 2;
}
else{
yMod = -1;
}
// create new bitmap, which will be painted and becomes result image
Bitmap bmOut = Bitmap.createBitmap(src.getWidth()*5/4+30, src.getHeight()*5/4+30, Bitmap.Config.ARGB_8888);
// setup canvas for painting
Canvas canvas = new Canvas(bmOut);
canvas.scale(1.25f,1.25f);
// setup default color
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
// create a blur paint for capturing alpha
Paint ptBlur = new Paint();
ptBlur.setMaskFilter(new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL));
int[] offsetXY = new int[2];
// capture alpha into a bitmap
Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY);
// create a color paint
Paint ptAlphaColor = new Paint();
ptAlphaColor.setColor(color);
// paint color for captured alpha region (bitmap)
canvas.drawBitmap(bmAlpha, xMod*offsetXY[0]/2, yMod*offsetXY[1], ptAlphaColor);
// free memory
bmAlpha.recycle();
// paint the image source
canvas.drawBitmap(src, 0, 0, null);
// return out final image
return bmOut;
}
public void launchUpgrade(){
upg = true;
upgradeBtn.setImg(upgrade);
}
public void launchMap(){
showmap = true;
mapBtn.setImg(map);
}
public void launchProfile(){
}
public void startGame(){
launchBtn.setImg(launch);
Intent myIntent = new Intent(getContext(), MainActivity.class);
//myIntent.putExtra("key", value); //Optional parameters
getContext().startActivity(myIntent);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if(!thread.getRunning()) {
thread.setRunning(true);
thread.start();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
int count = 0;
if(thread.getRunning()) {
thread.interrupt();
}
/*while(retry&&count<1000){
try{thread.setRunning(false);
thread.join();
retry=false;
}catch(InterruptedException e){}
count++;
}*/
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x =(int) event.getX();
y =(int) event.getY();
if (x < 710 && y > 780) {
upgradeBtn.setImg(highlightImage(upgrade,Color.BLUE,false,true));
}else{
upgradeBtn.setImg(upgrade);
}
if (x < 520 && y < 275) {
mapBtn.setImg(highlightImage(map,Color.YELLOW,true,false));
}else{
mapBtn.setImg(map);
}
if(x>1500&&y>700){
launchBtn.setImg(highlightImage(launch,Color.RED,true,true));
}else{
launchBtn.setImg(launch);
}
if(event.getAction()==MotionEvent.ACTION_UP) {
if (x < 710 && y > 780) {
launchUpgrade();
return true;
}
if (x < 520 && y < 275) {
launchMap();
return true;
}
if(x>1700&&y<235){
launchProfile();
return true;
}
if(x>1500&&y>700){
startGame();
}
}
return true;
}
public void update(){
for(int i=0;i<cloud.size();i++){
cloud.get(i).update();
if(cloud.get(i).getX()>screenX){
cloud.remove(i);
addCloud();
}
}
}
#Override
public void draw(Canvas canvas){
if(canvas!=null) {
canvas.drawBitmap(bg,-3,0,null);
for(int i=0;i<cloud.size();i++){
cloud.get(i).draw(canvas);
}
canvas.drawBitmap(potty, screenX / 2 - 190, screenY / 2 - 190, null);
//canvas.drawBitmap(upgrade, -235, screenY - upgrade.getHeight() + 300, null);
canvas.drawRoundRect(screenX - 550, 5, screenX - 150, 105, 15, 15, feature);
canvas.drawRoundRect(screenX - 550, 5, screenX - 150, 105, 25, 25, border);
canvas.drawCircle(screenX - 60, 60, 150, featureRad);
canvas.drawCircle(screenX - 60, 60, 150, border);
canvas.drawCircle(screenX / 2 + 230, screenY / 2 + 110, 50, stick);
canvas.drawLine(screenX / 2 + 220, screenY / 2 + 110, screenX / 2 + 185, screenY / 2 + 340, stick);
canvas.drawLine(screenX / 2 + 185, screenY / 2 + 340, screenX / 2 + 270, screenY/2+440,stick);
canvas.drawLine(screenX/2+270,screenY/2+440,screenX/2+270,screenY,stick);
canvas.drawLine(screenX/2+270,screenY/2+440,screenX/2+340,screenY,stick);
canvas.drawLine(((screenX / 2 + 220)+(screenX / 2 + 185))/2,screenY/2+230,screenX/2+210,
screenY/2+250,stick);
canvas.drawLine(screenX/2+185,screenY/2+250,screenX/2+245,screenY/2+235,stick);
canvas.drawLine(screenX / 2 + 235, screenY / 2 + 245, ((screenX / 2 + 220) + (screenX / 2 + 185)) / 2,
screenY / 2 + 230, stick);
canvas.drawText(Integer.toString(prefs.getInt("highscore", 0)), 1000, 50, text);
upgradeBtn.draw(canvas);
mapBtn.draw(canvas);
launchBtn.draw(canvas);
canvas.drawText(Integer.toString(x)+","+Integer.toString(y),50,50,text);
/*if(upg){
canvas.drawText("UPGRADE",540,400,text);
canvas.drawBitmap(highlightImage(upgrade), -235, screenY - upgrade.getHeight() + 300,null);
}*/
if(showmap){
canvas.drawText("MAP",540,500,text);
}
}
}
}
I'm sure there is a lot more wrong with my code than just the issue I'm having because I'm very new to this, so if you have any general suggestions to clean up my code, I'd love to hear those as well.
I made straight lines with the canvas.drawPath command. But now I want that the color is selectable. So you click on a button and afterwards, the path is in this color, but the previous paths remain in their colors.. The thin with the button comes later, the colour is random at the moment...
I did it, i changed the code from here! Change path color without changing previous paths
Main Activity
package com.example.drawproject;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawArea da = new DrawArea(this);
setContentView(da);
}
}
Draw Activity
import android.content.Context;
import android.graphics.*;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class DrawArea extends View {
private List<Stroke> _allStrokes; //all strokes that need to be drawn
private SparseArray<Stroke> _activeStrokes; //use to retrieve the currently drawn strokes
private Random _rdmColor = new Random();
int count = 1;
public DrawArea(Context context) {
super(context);
_allStrokes = new ArrayList<Stroke>();
_activeStrokes = new SparseArray<Stroke>();
setFocusable(true);
setFocusableInTouchMode(true);
}
public void onDraw(Canvas canvas) {
if (_allStrokes != null) {
for (Stroke stroke: _allStrokes) {
if (stroke != null) {
Path path = stroke.getPath();
Paint painter = stroke.getPaint();
if ((path != null) && (painter != null)) {
if(count%2 != 0){
canvas.drawPath(path, painter);
}
}
}
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
final int pointerCount = event.getPointerCount();
switch (action) {
case MotionEvent.ACTION_DOWN: {
count++;
if(count%2 != 1)
{pointDown((int)event.getX(), (int)event.getY(), event.getPointerId(0));
break;
}
if (count%2 != 0){
for (int pc = 0; pc < pointerCount; pc++) {
pointDown((int)event.getX(pc), (int)event.getY(pc), event.getPointerId(pc));
}
}
}
case MotionEvent.ACTION_MOVE: {
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
invalidate();
return true;
}
private void pointDown(int x, int y, int id) {
if(count%2 !=1){
//create a paint with random color
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
paint.setColor(_rdmColor.nextInt());
//create the Stroke
Point pt = new Point(x, y);
Stroke stroke = new Stroke(paint);
stroke.addPoint(pt);
_activeStrokes.put(id, stroke);
_allStrokes.add(stroke);
}
if (count%2 != 0){
//retrieve the stroke and add new point to its path
Stroke stroke = _activeStrokes.get(id);
if (stroke != null) {
Point pt = new Point(x, y);
stroke.addPoint(pt);
}
}
}
}
Lines
package com.example.drawproject;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
public class Stroke {
private Path _path;
private Paint _paint;
public Stroke (Paint paint) {
_paint = paint;
}
public Path getPath() {
return _path;
}
public Paint getPaint() {
return _paint;
}
public void addPoint(Point pt) {
if (_path == null) {
_path = new Path();
_path.moveTo(pt.x, pt.y);
} else {
_path.lineTo(pt.x, pt.y);
}
}
}
For each path declare separate paint object and change paint object of the path that you want to change.
canvas.drawPath(path1, paint1);
canvas.drawPath(path2, paint2);
canvas.drawPath(path3, paint3);
canvas.drawPath(path4, paint4);
The main idea:
public class temp extends View{
private Map<Path,Paint> MyMap = new HashMap<Path,Paint>();
public ViewFeld(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
private void init() {
for (int i = 0; i < number of pathes ; i++) {
Path path = new Path();
paint = new Paint();
paint.setColor(Color.MAGENTA);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);
MyMap.put(path, paint);
}
}
protected void onDraw(Canvas canvas) {
for (Path p : MyMap.keySet()) {
canvas.drawPath(p, MyMap.get(p));
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Paint p = MyMap.get(path you want to change the color);
// change the color of p
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// nothing to do
break;
default:
return false;
}
// Schedules a repaint.
invalidate();
return true;
}