Draw and animate a dashed line - android

I have a fullscreen activity that should look like this:
where the big white circle would have some text, I've already done it, but the problem is that I don't know how to do that dashed lines between the icons, also they want a little animation in the icons, so I assumed that each one should be a separate view, so far I've done this (it doesn't need to look exactly the same):
So, how could I draw that lines? Also if I could make that dashes to "run" acrross the lines would be awesome.
this is my xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rlt_welcome"
android:layout_weight="9"
android:background="#drawable/bg"
>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="2"
android:orientation="vertical"
android:padding="10dp"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:id="#+id/img_youtube"
android:src="#drawable/youtube_circle"
android:layout_marginTop="60dp"
android:layout_marginRight="60dp"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="wrap_content"
android:src="#drawable/tablet_circle"
android:layout_height="wrap_content"
android:layout_above="#+id/img_stats"
android:layout_marginRight="30dp"
android:layout_below="#+id/img_youtube"
/>
<ImageView
android:layout_width="wrap_content"
android:id="#+id/img_stats"
android:src="#drawable/stats_circle"
android:layout_height="wrap_content"
android:layout_marginRight="70dp"
android:layout_marginBottom="20dp"
android:layout_alignParentBottom="true"/>
<ImageView
android:id="#+id/img_iphone"
android:layout_width="wrap_content"
android:src="#drawable/iphone_circle"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
/>
<ImageView
android:layout_width="wrap_content"
android:src="#drawable/imac_circle"
android:layout_height="wrap_content"
android:layout_below="#+id/img_iphone"
android:layout_marginLeft="70dp"
android:layout_marginTop="-30dp"
/>
<ImageView
android:layout_width="wrap_content"
android:src="#drawable/webcam_circle"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="5"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_vertical"
android:padding="40dp"
android:textSize="25sp"
android:textColor="#color/text1"
android:layout_margin="20dp"
android:text="Bienvenido"
android:background="#drawable/flat_circle"
android:id="#+id/txt_welcome"
android:layout_centerInParent="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow_circle"
android:id="#+id/img_arrow"
android:layout_alignParentTop="true"
android:layout_marginRight="60dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/news_circle"
android:layout_below="#+id/img_arrow"
android:layout_marginTop="-90dp"
android:layout_marginRight="2dp"
android:layout_marginLeft="70dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/line_circle"
android:id="#+id/img_line"
android:layout_below="#+id/img_arrow"
android:layout_marginTop="-10dp"
android:layout_marginRight="70dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/money_circle"
android:layout_below="#+id/img_line"
android:layout_marginRight="6dp"
android:layout_marginTop="-70dp"
android:layout_marginLeft="70dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/mouse_circle"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginRight="80dp"
/>
</RelativeLayout>
</LinearLayout>

Please check this, may be this will help you
http://www.rengelbert.com/tutorial.php?id=182

How do I get this work, I made a new activity that holds a Canvas controller, and place the bitmaps on the canvas and draw the lines between them with this, I didn't use any external library:
Hope someone could reuse some code and not only been told to google it.
MainActivty.java
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeMainActivity = (RelativeLayout) findViewById(R.id.rlt_main);
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
final int heightS = dm.heightPixels;
final int widthS = dm.widthPixels;
Log.d("MainActvitiy", "widht:" + widthS);
myPanel = new Panel(getApplicationContext(),this,widthS, heightS);
relativeMainActivity.addView(myPanel);
RelativeLayout RR = new RelativeLayout(this);
RR.setGravity(Gravity.CENTER);
relativeMainActivity.addView(RR,400,150);
RR.setX(0);
LayoutInflater myInflater = (LayoutInflater) getApplicationContext().getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE);
}
Panel.java
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
public MainThread thread;
private Background background;
private CircleManager CM;
public int ScreenWidth;
public int Screenheigt;
private CircleIcon icon1;
private CircleIcon icon2;
private CircleIcon icon3;
//and so on
public MainActivity myMain;
public Panel(Context context, MainActivity _main, int width , int height) {
super(context);
getHolder().addCallback(this);
this.myMain = _main;
this.ScreenWidth=width;
this.Screenheigt=height;
thread = new MainThread(getHolder(),this);
background = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.bg), Screenheigt, this);
CM = new CircleManager( this,context,ScreenWidth);
CM.setScreen(ScreenWidth, Screenheigt);
SetIcons();
CM.setManager();
setFocusable(true);
}
void SetIcons()
{
icon1 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_iphone),39,40);
icon2 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_chat),280,40);
icon3 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_youtube),60,200);
//and so on
icon1.myConnections.add(2);
icon1.myConnections.add(3);
icon2.myConnections.add(15);
icon3.myConnections.add(4);
icon3.myConnections.add(5);
//and so on
CM.iconsList.add(icon1);
CM.iconsList.add(icon2);
CM.iconsList.add(icon3);
//and so on
}
void Draw(Canvas canvas){
if (canvas!=null)
{
background.draw(canvas);
CM.draw(canvas);
iconEvent.draw(canvas);
}
}
void Update(float dt)
{
CM.Update(dt);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
while (retry)
{
try
{
thread.join();
retry=false;
}
catch (InterruptedException e)
{
}
}
}
}
Background.java
public class Background {
Bitmap BackBitmap;
int x,y;
int ScreenHeight;
Panel root_panel;
public Background(Bitmap bitmap , int Screen_h, Panel _panel) {
this.BackBitmap = bitmap;
this.x=0;
this.y=0;
this.ScreenHeight=Screen_h;
root_panel =_panel;
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(BackBitmap,x,y, null);
}
}
CircleIcon.java
public class CircleIcon {
private Bitmap bitmap;
private int x;
private int y;
CircleManager circManager;
ArrayList<Integer> myConnections;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y=y;
}
public CircleIcon(Bitmap icon, int x, int y) {
bitmap=icon;
this.x=x;
this.y=y;
myConnections = new ArrayList<>();
}
public ArrayList<Integer> getMyConnections() {
return myConnections;
}
public void setMyConnections(ArrayList<Integer> myConnections) {
this.myConnections = myConnections;
}
public void setManager(CircleManager icManager) {
circManager = icManager;
}
public Bitmap getBitmap()
{
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, x, y, null);
}
public void update()
{
// x=+1; example
}
}
CircleManager.java
public class CircleManager {
Bitmap icons;
int screenWidth;
int hour;
int min;
Context myContext;
int ScreenWidht;
public Panel myPanel;
public ArrayList<CircleIcon> iconsList;
public CircleManager(Panel _Panel, Context context,int screenW) {
this.myPanel = _Panel;
this.screenWidth = screenW;
this.myContext = context;
iconsList = new ArrayList<CircleIcon>();
}
public void setScreen(int screenWidth, int screenHeight)
{
this.ScreenWidht=screenWidth;
}
public void draw(Canvas canvas)
{
drawLines(canvas);
for(CircleIcon myIcon: iconsList)
{
myIcon.draw(canvas);
}
}
public void Update(float dt)
{
//some animation updates
}
public void drawLines(Canvas canvas)
{
Paint mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
mPaint.setPathEffect(new DashPathEffect(new float[]{7, 5}, 0));
for (CircleIcon myIcon: iconsList)
{
for( int connectedIcon: myIcon.getMyConnections())
{
Path mPath;
mPath = new Path();
mPath.moveTo(myIcon.getX()+myIcon.getBitmap().getWidth()/2, myIcon.getY()+myIcon.getBitmap().getHeight()/2);
mPath.lineTo(iconsList.get(connectedIcon-1).getX()+myIcon.getBitmap().getWidth()/2, iconsList.get(connectedIcon-1).getY()+myIcon.getBitmap().getHeight()/2);
canvas.drawPath(mPath, mPaint);
}
}
}
public void setManager()
{
for(CircleIcon myIcon: iconsList)
{
myIcon.setManager(this);
}
}
}

Related

"Attempt to invoke virtual method 'void android.graphics.Canvas.drawColor(int)' on a null object reference " error in my android app [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
My English is not so good, but I will try..
I am having a problem with my android app (obesity measurement app).
In AVD (android virtual device), my app works well.
But, on my smartphone (Galaxy S7) my app causes an error.
Error massage is
" BMI calcu keeps stopping " .
('BMI calcu' is the name of App.)
What should I do?
Please give me a hand...
<<<< Layout file >>>>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="comp.whcomp.whteam.bmicalcu.MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="BMI calculator"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="height : " />
<EditText
android:id="#+id/heightEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="number|numberDecimal"
android:maxLength="5" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="cm" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="weight : " />
<EditText
android:id="#+id/weightEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="number|numberDecimal"
android:maxLength="5" />
<TextView
android:id="#+id/textView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="kg" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/textView5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="BMI : " />
<TextView
android:id="#+id/bmiTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName" />
<TextView
android:id="#+id/textView6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
<comp.whcomp.whteam.bmicalcu.BmiView
android:id="#+id/BmiView2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6"
android:orientation="horizontal"></LinearLayout>
</LinearLayout>
Main code is as following:
MainActivity.java
public class MainActivity extends Activity {
EditText mWeightEditText;
EditText mHeightEditText;
TextView mBmiTextView;
float floatWeight;
float floatHeight;
static float floatBmi = 0f;
String strBmi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mWeightEditText = (EditText)findViewById(R.id.weightEditText);
mHeightEditText = (EditText)findViewById(R.id.heightEditText);
mBmiTextView = (TextView)findViewById(R.id.bmiTextView);
mWeightEditText.addTextChangedListener(mWatcher);
mHeightEditText.addTextChangedListener(mWatcher);
} // end of onCreate()
TextWatcher mWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence,int i,int i1,int i2){}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2){
if((mWeightEditText.getText().toString().length()>0) &&
(mHeightEditText.getText().toString().length()>0)) {
if(mHeightEditText.getText().toString().equals("0")){
} else {
floatWeight=Float.parseFloat(mWeightEditText.getText().toString());
floatHeight=Float.parseFloat(mHeightEditText.getText().toString());
floatBmi=(floatWeight/(floatHeight/100f)) / (floatHeight/100f);
strBmi = String.format("%.1f", floatBmi);
mBmiTextView.setText(strBmi);
}
} else {
mBmiTextView.setText("");
floatBmi = 0f;
}
} // end of onTextchange()
#Override
public void afterTextChanged(Editable editable) {}
}; // end of TextWatcher
}
BmiView.java
public class BmiView extends SurfaceView implements SurfaceHolder.Callback {
Context mContext;
private BmiThread mThread;
int screenWidth;
int screenHeight;
int radius;
int xOfCenterOfCircle;
int yOfCenterOfCircle;
int tOfRectOfArc;
int bOfRectOfArc;
int lOfRectOfArc;
int rOfRectOfArc;
int xOfNeedleEnd = 0;
int yOfNeedleEnd = 0;
int intBmi;
RectF rect;
private Paint mPaintGreen;
private Paint mPaintBlack;
private Paint mPaintNeedle;
// constructor
public BmiView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
mContext = context;
mPaintGreen = new Paint();
mPaintBlack = new Paint();
mPaintNeedle = new Paint();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
screenWidth = w;
screenHeight = h;
if ( h > w/2 ) {
radius = w*4/10;
} else {
radius = h*4/5;
}
xOfCenterOfCircle = w/2;
yOfCenterOfCircle = h*4/5;
tOfRectOfArc = yOfCenterOfCircle - radius;
bOfRectOfArc = yOfCenterOfCircle + radius;
lOfRectOfArc = xOfCenterOfCircle - radius;
rOfRectOfArc = xOfCenterOfCircle + radius;
mPaintGreen.setColor(Color.GREEN);
mPaintBlack.setColor(Color.BLACK);
mPaintNeedle.setColor(Color.RED);
mPaintNeedle.setStrokeWidth(10);
rect = new RectF();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mThread = new BmiThread(surfaceHolder);
mThread.setRunning(true);
mThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder,int i,int i1,int i2){}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
boolean retry = true;
mThread.setRunning(false); // terminate mThread
while (retry) {
try {
mThread.join(); // wait for mThread to finish
retry = false;
}
catch (InterruptedException e) {}
}
}
class BmiThread extends Thread {
private SurfaceHolder surfaceHolder;
private boolean threadIsRunning = true; // running by default
public BmiThread(SurfaceHolder holder) {
surfaceHolder = holder;
}
public void setRunning (boolean running) {
threadIsRunning = running;
}
public void run() {
Canvas canvas = null;
while (threadIsRunning) {
try {
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
canvas.drawColor(Color.WHITE);
rect.set(lOfRectOfArc, tOfRectOfArc, rOfRectOfArc, bOfRectOfArc);
canvas.drawArc(rect, 180, 180, false, mPaintGreen);
intBmi = (int)MainActivity.floatBmi;
if(intBmi > 40) {
intBmi = 40;
}
double deg = 180*(intBmi/40d), rad;
rad = Math.toRadians(deg);
xOfNeedleEnd = xOfCenterOfCircle - (int)(( Math.cos(rad) )*radius);
yOfNeedleEnd = yOfCenterOfCircle - (int)(( Math.sin(rad) )*radius);
canvas.drawLine(xOfCenterOfCircle, yOfCenterOfCircle, xOfNeedleEnd,
yOfNeedleEnd, mPaintNeedle);
canvas.drawCircle(xOfCenterOfCircle, yOfCenterOfCircle, 10,
mPaintBlack);
}
} finally {
if (canvas != null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end of while()
} // end of run()
} // end of thread.
}
<<<< Logcat message >>>>
08-02 16:00:18.127 3086-3213/comp.whcomp.whteam.bmicalcu E/AndroidRuntime: FATAL EXCEPTION: Thread-7
Process: comp.whcomp.whteam.bmicalcu, PID: 3086
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.Canvas.drawColor(int)' on a null object reference
at comp.whcomp.whteam.bmicalcu.BmiView$BmiThread.run(BmiView.java:123)
Check that you are creating an instance before trying to set the colour. It is complaining because the object you're trying to set the colour for doesn't exist at the time you're trying to set it.
Hmm. For the first glance, your code seems correct. Maybe is because your BmiView has a height of 0dp? - see the layout

Passing value from activity to view class

I have an activity in which there are 3 checkboxes in different views. These checkboxes are to pick up a color.
In the DrawingView class, I have to draw on my canvas with the color that is checked. What I want is to pass an integer value from the activity to the view class and set the color of paint accordingly. itried using getter and setters, but I get black color. I suppose this is because the color is being set in the constructor itself, and it does not change when I check any box.
Please refer this for updates in the below code
Code:
MainActivity: the color/checkbox is selected here. And the drawing is to be done in the layout of this activity itself.
carImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
drawingView=new DrawingView(carImageView.getContext());
drawingView=new DrawingView(carImageView.getContext(),null);
drawingView.setColor(color);
return false;
}
});
scratchesCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b)
{
color=1;
chipsCb.setChecked(false);
dentsCb.setChecked(false);
}
}
});
chipsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b)
{
color=2;
scratchesCb.setChecked(false);
dentsCb.setChecked(false);
}
}
});
dentsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b)
{
color=3;
chipsCb.setChecked(false);
scratchesCb.setChecked(false);
}
}
});
}
View Class:
public DrawingView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
mPaint=new Paint();
if(color==1)
mPaint.setColor(Color.RED);
else if(color==2)
mPaint.setColor(Color.BLUE);
else if(color==3)
mPaint.setColor(Color.GREEN);
this.context=context;
mPath=new Path();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.MITER);
mPaint.setStrokeWidth(5f);
}
public void setColor(int color){
this.color=color;
}
public int getColor(){
return this.color;
}
Edit
I don't necessarily want to use the exact same code. All I want is to change paint color when a checkbox is selected to be able to draw on an image view. Any other approach is welcome.
In the MainActivity, you are creating a DrawingView that has no relationship to your image view that is displayed. So, when you change the color, you are not changing the color of the displayed image view but of the unconnected DrawingView. The image view never has a new color defined and always defaults to black.
Here is a video of a small working app based upon your most recently supplied code. Maybe all the colors shouldn't change when a new check box is clicked, but you will be able to address that issue separately.
Changes I have made to the Java code are commented as such. Changes were also made to the XML to allow your code to run in my environment, but those changes were not commented.
MainActivity.java (Updated)
public class MainActivity extends AppCompatActivity {
ImageView caricon;
int itemSelected = 0;
private DrawingView carImageView;
Bitmap bitmap;
ImageView backarrow;
TextView nextcheckinAB2;
Bitmap bmp;
public static int color;
CheckBox scratchesCb, chipsCb, dentsCb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
carImageView = (DrawingView) findViewById(R.id.carImageView);
scratchesCb = (CheckBox) findViewById(R.id.scratchesCheckBox);
chipsCb = (CheckBox) findViewById(R.id.ChipCheckbx);
dentsCb = (CheckBox) findViewById(R.id.DentsCheckBox);
// Change: Make sure to initialize the color
color = 1;
carImageView.setColor(color);
carImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// drawingView = new DrawingView(carImageView.getContext(),null);
carImageView.setColor(color);
return false;
}
});
scratchesCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
color = 1;
carImageView.clearCanvas();
carImageView.setColor(1); //
chipsCb.setChecked(false);
dentsCb.setChecked(false);
}
}
});
chipsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
color = 2;
carImageView.setColor(2);
scratchesCb.setChecked(false);
dentsCb.setChecked(false);
}
}
});
dentsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
color = 3;
// Change: Do like the other check boxes althogh not really needed.
carImageView.setColor(3);
chipsCb.setChecked(false);
scratchesCb.setChecked(false);
}
}
});
}
}
DrawingView.java (Updated)
public class DrawingView extends android.support.v7.widget.AppCompatImageView {
private Path mPath;
private Paint mPaint;
private float mX, mY;
private static final float TOLERANCE = 5;
int color;
Context context;
public DrawingView(Context context) {
super(context);
this.context = context;
init();
}
public DrawingView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
public void init() {
mPath = new Path();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.MITER);
mPaint.setStrokeWidth(5f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mPath, mPaint);
}
public void setColor(int color) {
if (color == 1) {
mPaint.setColor(Color.RED);
this.color = color;
invalidate();
} else if (color == 2) {
mPaint.setColor(Color.BLUE);
this.color = color;
invalidate();
} else if (color == 3) {
mPaint.setColor(Color.GREEN);
this.color = color;
invalidate();
}
}
public int getColor() {
return this.color;
}
private void onStartTouch(float x, float y) {
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void moveTouch(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOLERANCE || dy >= TOLERANCE) {
mPath.quadTo(mX, mY, (mX + x) / 2, (mY + y) / 2);
mX = x;
mY = y;
}
}
public void clearCanvas() {
mPath.reset();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
invalidate();
}
private void upTouch() {
mPath.lineTo(mX, mY);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
onStartTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
moveTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
upTouch();
invalidate();
break;
}
return true;
}
}
activity_main.xml (Updated)
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="horizontal"
android:weightSum="3">
<HorizontalScrollView
android:id="#+id/horizontalSrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="5dp"
android:weightSum="2">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="2dp"
android:layout_weight="0.5"
android:background="#android:color/holo_red_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_weight="1.5"
android:text="Scratches"
android:textColor="#000" />
</LinearLayout>
<CheckBox
android:id="#+id/scratchesCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:checked="true" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="5dp"
android:weightSum="2">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="2dp"
android:layout_weight="0.5"
android:background="#android:color/holo_blue_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_weight="1.5"
android:text="Chips"
android:textColor="#000" />
</LinearLayout>
<CheckBox
android:id="#+id/ChipCheckbx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="5dp"
android:weightSum="2">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="2dp"
android:layout_weight="0.5"
android:background="#android:color/holo_green_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_weight="1.5"
android:text="Dings/Dents"
android:textColor="#000" />
</LinearLayout>
<CheckBox
android:id="#+id/DentsCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="8.7">
<[your package name].DrawingView
android:id="#+id/carImageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#mipmap/ic_launcher"
android:layout_gravity="center_vertical" />
<!--<ImageView
android:id="#+id/carImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"/>-->
</LinearLayout>
</LinearLayout>
you need change function setColor.
1.change mPaint color.
2.add invalidate() for redraw view.
public void setColor(int color){
this.color=color;
mPaint.setColor(color);
invalidate();
}
You need to call invalidate() on the View to make it update.
Try this,
final DrawingView drawingView = new DrawingView(carImageView.getContext());
carImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
drawingView.setColor(color);
return false;
}
});
scratchesCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b)
{
color = 1;
drawingView.setColor(color);
chipsCb.setChecked(false);
dentsCb.setChecked(false);
}
}
});
chipsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b)
{
color = 2;
drawingView.setColor(color);
scratchesCb.setChecked(false);
dentsCb.setChecked(false);
}
}
});
dentsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b)
{
color = 3;
drawingView.setColor(color);
chipsCb.setChecked(false);
scratchesCb.setChecked(false);
}
}
});
DrawingView.java
public DrawingView(Context context) {
super(context);
this.context = context;
init();
}
public DrawingView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
this.context=context;
init();
}
private void init() {
mPath=new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.MITER);
mPaint.setStrokeWidth(5f);
setColor(color);
}
public void setColor(int color){
this.color=color;
if(color==1)
mPaint.setColor(Color.RED);
else if(color==2)
mPaint.setColor(Color.BLUE);
else if(color==3)
mPaint.setColor(Color.GREEN);
// Call invalidate
invalidate();
}
Define static data member in your DrawingView
static int color = 1; //default
Then, from your activity simply call
DrawingView.color = someValue;
Static Keyword before variable color will make sure there is only one variable reference for all objects of your DrawingView class.
"even if I pass a static value, say 3 in main activity in drawingview.setColor(int) it gives black. This means the setColor function in Drawingview isn't working. "
Does this mean it will call paint.setColor(3) ?
If yes, this will of course turn your color black. Try passing Color.GREEN instead

view.getTop() reutrns wrong result

I have this xml, with the layout surface(which doesnt cover the whole screen):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/FrameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="bottom"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="10dp"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="#+id/surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1" >
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_gravity="bottom" >
<ImageView
android:id="#+id/right"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignTop="#+id/down"
android:layout_toRightOf="#+id/down"
android:src="#drawable/right" />
<ImageView
android:id="#+id/left"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignTop="#+id/down"
android:layout_toLeftOf="#+id/down"
android:src="#drawable/left" />
<ImageView
android:id="#+id/up"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/right"
android:src="#drawable/up" />
<ImageView
android:id="#+id/down"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/up"
android:layout_centerHorizontal="true"
android:src="#drawable/down" />
</RelativeLayout>
</LinearLayout>
I took control of surface in the mainActivity and tried to draw a on it's borders a frame with width of 10px.
here the the mainActivity:
public class MainActivity extends Activity {
GameView gv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_view);
LinearLayout surface = new LinearLayout(this);
surface = (LinearLayout)findViewById(R.id.surface);
gv= new GameView(this,surface);
surface.addView(gv);
}
}
here is the GameView class:
public class GameView extends SurfaceView implements Runnable {
private boolean isRunning=false;
private final long FPS=12;
int PART_SIZE=6;
private SurfaceHolder holder;
Thread snakethread;
LinearLayout view;
public GameView(Context context,LinearLayout view) {
super(context);
this.view=view;
this.a=new Arena();
snakethread=new Thread(this);
holder= getHolder();
this.setBackgroundColor(Color.TRANSPARENT);
this.setZOrderOnTop(true);
getHolder().setFormat(PixelFormat.TRANSPARENT);
holder.addCallback(new SurfaceHolder.Callback(){
#Override
public void surfaceCreated(SurfaceHolder arg0) {
setRunning(true);
snakethread.start();
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,int arg3) {
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
setRunning(false);
while(true){
try {
snakethread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
public void run() {
long stepPerSecond=1000/FPS;
long startTime;
long sleepTime;
Canvas c = null;
try{
c=this.getHolder().lockCanvas();
synchronized (this.getHolder()) {
c.drawColor(Color.BLUE);
Paint p=new Paint();
p.setColor(Color.BLACK);
c.drawRect(view.getLeft(), view.getTop(), view.getLeft()+10, view.getBottom(),p);
c.drawRect(view.getLeft(), view.getTop(),view.getRight(),view.getTop()+10,p);
c.drawRect(view.getRight()-10, view.getTop(), view.getRight(),view.getBottom(),p);
c.drawRect(view.getLeft(), view.getBottom()-10, view.getRight(),view.getBottom(),p);
}
}
catch(Exception e){
}
finally{
if(c!=null){
this.getHolder().unlockCanvasAndPost(c);
}
}
}
The problem is that the whole frame is approximately 6px under the view's Top,under where is should be. i mean that the view.getTop() and view.getBottom() return a worng result, a result that is bigger in approximately 6px then what it should be (if the view's top coordinate is x, then it return x+6).
After Spend 2 Days I found the solution
int top = view.getTop();
int bottom = view.getBottom();
// use these line instead of upper code
int statusBarHeight = (int) Math.ceil(25 * context.getResources().getDisplayMetrics().density);
int top = (childTextView.getBottom()+childTextView.getHeight())-statusBarHeight ;
int bottom = (childTextView.getTop()+childTextView.getHeight())-statusBarHeight ;

Custom designed view disappeared while using ScrollView

I am using one custom designed CalendarView in Android. While I am using Scrollview in the layout, the custom designed CalendarView is not getting displayed in the screen.
what could cause the CalendarView to disappear?
My layout is:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/NextMonth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="#string/NextMonth" />
<Button
android:id="#+id/PreviousMonth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="#string/PreviousMonth" />
<TextView
android:id="#+id/MonthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Month" />
<TextView
android:id="#+id/SundayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="25dp"
android:text="#string/SundayText"
android:textSize="10sp" />
<TextView
android:id="#+id/MondayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="22dp"
android:layout_toRightOf="#+id/SundayText"
android:text="#string/MondayText"
android:textSize="10sp" />
<TextView
android:id="#+id/TuesdayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/MondayText"
android:text="#string/Tuesday"
android:textSize="10sp" />
<TextView
android:id="#+id/WednesdayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="22dp"
android:layout_toRightOf="#+id/TuesdayText"
android:text="#string/Wednesday"
android:textSize="10sp" />
<TextView
android:id="#+id/Thursday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/WednesdayText"
android:text="#string/ThurdayText"
android:textSize="10sp" />
<TextView
android:id="#+id/Friday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="22dp"
android:layout_toRightOf="#+id/Thursday"
android:text="#string/FridayText"
android:textSize="10sp" />
<TextView
android:id="#+id/Saturday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/PreviousMonth"
android:layout_marginLeft="27dp"
android:layout_toRightOf="#+id/Friday"
android:text="#string/SaturdayText"
android:textSize="10sp" />
<com.example.calendar_module.CalendarView
android:id="#+id/calendar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/NextMonth" />
</RelativeLayout>
</ScrollView>
My CalenderView Class file :
package com.example.calendar_module;
import java.util.Calendar;
import android.app.ActionBar.LayoutParams;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.MonthDisplayHelper;
import android.view.MotionEvent;
import android.widget.ImageView;
public class CalendarView extends ImageView {
private static int WEEK_TOP_MARGIN = 0;
private static int WEEK_LEFT_MARGIN = 05;
private static int CELL_WIDTH = 20;
private static int CELL_HEIGH = 20;
private static int CELL_MARGIN_TOP = 05;
private static int CELL_MARGIN_LEFT = 29;
private static float CELL_TEXT_SIZE;
private static final String TAG = "CalendarView";
private String[] mDayString = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
private Calendar mRightNow = null;
private Drawable mWeekTitle = null;
private Cell mToday = null;
private Cell[][] mCells = new Cell[6][7];
private Cell[] mDayCells = new Cell[7];
private OnCellTouchListener mOnCellTouchListener = null;
MonthDisplayHelper mHelper;
Drawable mDecoration = null;
public interface OnCellTouchListener {
public void onTouch(Cell cell);
}
public CalendarView(Context context) {
this(context, null);
}
public CalendarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CalendarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDecoration = context.getResources().getDrawable(R.drawable.typeb_calendar_today);
initCalendarView();
}
private void initCalendarView() {
mRightNow = Calendar.getInstance();
// prepare static vars
Resources res = getResources();
WEEK_TOP_MARGIN = (int) res.getDimension(R.dimen.week_top_margin);
WEEK_LEFT_MARGIN = (int) res.getDimension(R.dimen.week_left_margin);
CELL_WIDTH = (int) res.getDimension(R.dimen.cell_width);
CELL_HEIGH = (int) res.getDimension(R.dimen.cell_heigh);
CELL_MARGIN_TOP = (int) res.getDimension(R.dimen.cell_margin_top);
CELL_MARGIN_LEFT = (int) res.getDimension(R.dimen.cell_margin_left);
CELL_TEXT_SIZE = res.getDimension(R.dimen.cell_text_size);
// set background
// setImageResource(R.drawable.background);
mWeekTitle = res.getDrawable(R.drawable.calendar_week);
mHelper = new MonthDisplayHelper(mRightNow.get(Calendar.YEAR), mRightNow.get(Calendar.MONTH));
}
private void initCells() {
class _calendar {
public int day;
public boolean thisMonth;
public _calendar(int d, boolean b) {
day = d;
thisMonth = b;
}
public _calendar(int d) {
this(d, false);
}
};
_calendar tmp[][] = new _calendar[6][7];
for(int i=0; i<tmp.length; i++) {
int n[] = mHelper.getDigitsForRow(i);
for(int d=0; d<n.length; d++) {
if(mHelper.isWithinCurrentMonth(i,d))
tmp[i][d] = new _calendar(n[d], true);
else
tmp[i][d] = new _calendar(n[d]);
}
}
Calendar today = Calendar.getInstance();
int thisDay = 0;
mToday = null;
if(mHelper.getYear()==today.get(Calendar.YEAR) && mHelper.getMonth()==today.get(Calendar.MONTH)) {
thisDay = today.get(Calendar.DAY_OF_MONTH);
}
// // build cells
Rect Bound = new Rect(CELL_MARGIN_LEFT, CELL_MARGIN_TOP, CELL_WIDTH+CELL_MARGIN_LEFT, CELL_HEIGH+CELL_MARGIN_TOP);
// for( int i=0 ; i < 7 ; i++ )
// {
//
// mDayCells[i] = new Cell(mDayString[i],new Rect(Bound),CELL_TEXT_SIZE);
// Bound.offset(CELL_WIDTH, 0);
//
// }
//
// Bound.offset(0, CELL_HEIGH); // move to next row and first column
// Bound.left = CELL_MARGIN_LEFT;
// Bound.right = CELL_MARGIN_LEFT+CELL_WIDTH;
//
for(int week=0; week<mCells.length; week++) {
for(int day=0; day<mCells[week].length; day++)
{
if(tmp[week][day].thisMonth) {
if(day==0 || day==6 )
mCells[week][day] = new RedCell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE);
else
mCells[week][day] = new Cell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE);
} else {
mCells[week][day] = new GrayCell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE);
}
Bound.offset(CELL_WIDTH, 0); // move to next column
// get today
if(tmp[week][day].day==thisDay && tmp[week][day].thisMonth) {
mToday = mCells[week][day];
mDecoration.setBounds(mToday.getBound());
}
}
Bound.offset(0, CELL_HEIGH); // move to next row and first column
Bound.left = CELL_MARGIN_LEFT;
Bound.right = CELL_MARGIN_LEFT+CELL_WIDTH;
}
}
#Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
// Rect re = getDrawable().getBounds();
// WEEK_LEFT_MARGIN = CELL_MARGIN_LEFT = (right-left - re.width()) / 2;
// mWeekTitle.setBounds(WEEK_LEFT_MARGIN, WEEK_TOP_MARGIN, WEEK_LEFT_MARGIN+mWeekTitle.getMinimumWidth(), WEEK_TOP_MARGIN+mWeekTitle.getMinimumHeight());
initCells();
super.onLayout(changed, left, top, right, bottom);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CELL_WIDTH, CELL_HEIGH);
}
public void setTimeInMillis(long milliseconds) {
mRightNow.setTimeInMillis(milliseconds);
initCells();
this.invalidate();
}
public int getYear() {
return mHelper.getYear();
}
public int getMonth() {
return mHelper.getMonth();
}
public void nextMonth() {
mHelper.nextMonth();
initCells();
invalidate();
}
public void previousMonth() {
mHelper.previousMonth();
initCells();
invalidate();
}
public boolean firstDay(int day) {
return day==1;
}
public boolean lastDay(int day) {
return mHelper.getNumberOfDaysInMonth()==day;
}
public void goToday() {
Calendar cal = Calendar.getInstance();
mHelper = new MonthDisplayHelper(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH));
initCells();
invalidate();
}
public Calendar getDate() {
return mRightNow;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(mOnCellTouchListener!=null){
for(Cell[] week : mCells) {
for(Cell day : week) {
if(day.hitTest((int)event.getX(), (int)event.getY())) {
mOnCellTouchListener.onTouch(day);
}
}
}
}
return super.onTouchEvent(event);
}
public void setOnCellTouchListener(OnCellTouchListener p) {
mOnCellTouchListener = p;
}
#Override
protected void onDraw(Canvas canvas) {
// draw background
super.onDraw(canvas);
mWeekTitle.draw(canvas);
// draw cells
for(Cell[] week : mCells) {
for(Cell day : week) {
day.draw(canvas);
}
}
// draw today
if(mDecoration!=null && mToday!=null) {
mDecoration.draw(canvas);
}
}
public class GrayCell extends Cell {
public GrayCell(int dayOfMon, Rect rect, float s) {
super(dayOfMon, rect, s);
mPaint.setColor(Color.LTGRAY);
}
}
private class RedCell extends Cell {
public RedCell(int dayOfMon, Rect rect, float s) {
super(dayOfMon, rect, s);
mPaint.setColor(0xdddd0000);
}
}
}
I think, height of your custom view equals == 0. try to log it. If it is right just override onMeasure and set size for your view.
And esle : why in xml height == match_parent? Can you imagine how it looks in ScrollView?)
UPD: Ok, in your case height == 0. You must override onMeasure() method in your custom view like this :
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(WIDTH, HEIGHT);
}
Where width and height values in pixels.
Good luck!

Android SurfaceView empty

I am trying to make a simple 2D Android game. In this, game I'm trying to make some buttons to control the character, while the character is shown in a SurfaceView. Currently, the SurfaceView is rendering only a black screen.
This is my MainActivity, which extends Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
GameView gm = (GameView)findViewById(R.id.snake_surface);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.layout.main, menu);
return true;
}
The GameView class, which extends SurfaceView:
private HeroSprite hero;
public GameView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
gameLoopThread = new GameLoopThread(this);
getHolder().addCallback(new SurfaceHolder.Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
public void surfaceCreated(SurfaceHolder holder) {
createSprites();
createHero();
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
public void surfaceChanged(SurfaceHolder holder, int format,int width, int height) {
}
});
bmpBlood = BitmapFactory.decodeResource(context.getResources(), R.drawable.blood1);
}
private void createHero(){
hero=(createHeroSprite(R.drawable.aslan));
}
private HeroSprite createHeroSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new HeroSprite(this, bmp);
}
private void createSprites() {
sprites.add(createSprite(R.drawable.tavsan));
sprites.add(createSprite(R.drawable.fare));
sprites.add(createSprite(R.drawable.sansar));
sprites.add(createSprite(R.drawable.tavsan));
sprites.add(createSprite(R.drawable.fare));
sprites.add(createSprite(R.drawable.sansar));
sprites.add(createSprite(R.drawable.tavsan));
sprites.add(createSprite(R.drawable.fare));
sprites.add(createSprite(R.drawable.sansar));
sprites.add(createSprite(R.drawable.tavsan));
sprites.add(createSprite(R.drawable.tavsan));
}
private Sprite createSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new Sprite(this, bmp);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.GREEN);
for (int i = temps.size() - 1; i >= 0; i--) {
temps.get(i).onDraw(canvas);
}
for (Sprite sprite : sprites) {
sprite.onDraw(canvas);
}
hero.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (System.currentTimeMillis() - lastClick > 300) {
lastClick = System.currentTimeMillis();
float x = event.getX();
float y = event.getY();
synchronized (getHolder()) {
for (int i = sprites.size() - 1; i >= 0; i--) {
Sprite sprite = sprites.get(i);
if ((sprite).isCollition(x, y)) {
sprites.remove(sprite);
temps.add(new TempSprite(temps, this, x, y, bmpBlood));
break;
}
}
}
}
return true;
}
My GameLoopThread class, which extends Thread
static final long FPS = 10;
private GameView view;
private boolean running = false;
public GameLoopThread(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
#Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {
}
}
}
Here is my layout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="#+id/score"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:text="Score:"
android:textSize="20dp" />
<Button
android:id="#+id/btnThread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal" />
<TextView
android:id="#+id/max"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_marginLeft="100dp"
android:text="Max:"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.3" >
<SurfaceView
android:id="#+id/snake_surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.3" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1" >
<Button
android:id="#+id/butUp"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center"
android:text="UP" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/butLeft"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="LEFT" />
<Button
android:id="#+id/butRight"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="RIGHT" />
</RelativeLayout>
<Button
android:id="#+id/butDown"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center"
android:text="DOWN" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Your view in the layout is a SurfaceView, not a GameView. You need to change that:
<your.package.name.GameView
android:id="#+id/snake_surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.3" />
And replace your.package.name with the actual name of the package containing GameView.
Also, the line GameView gm = ... needs to go after setContentView.
And lastly, don't forget to call gm.invalidate() when you've modified the items that will be drawn!

Categories

Resources