Android: Multiple Views on a Activity - android

Here is my main:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.mainView);
TextView text= (TextView) findViewById(R.id.text);
text.setText("This is a Test!");
firstCircle first = new firstCircle(this);
secondCircle second = new secondCircle(this);
layout.addView(first);
layout.addView(second);
}
Here is my firstCircleClass:
public class firstCircle extends SurfaceView implements SurfaceHolder.Callback {
private firstThread _firstThread;
private secondThread _secondThread;
private SurfaceHolder surfaceHolder;
public firstCircle (Context context, AttributeSet attrs){
super(context,attrs);
getHolder().addCallback(this);
setFocusable(true);
_firstThread= new firstThread(getHolder(),this);
}
public firstCircle (Context context){
super(context);
getHolder().addCallback(this);
setFocusable(true);
_firstThread= new firstThread(getHolder(),this);
}
#Override
public void onDraw(Canvas c){
String tag="My Activity";
Paint paint = new Paint();
paint.setColor(Color.BLUE);
c.drawCircle(100,100,100,paint);
}
#Override
public void surfaceCreated(SurfaceHolder holder){
_firstThread.setRunning(true);
_firstThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
_firstThread.setRunning(false);
while (retry){
try{
_firstThread.join();
retry = false;
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
I have a secondCircle class that is the exact same as above with the name changed and the color of the circle being Red.
Here is my firstThread class:
public class firstThread extends Thread {
private SurfaceHolder _surfaceHolder;
private firstClass _firstClass;
private boolean _run = false;
public firstThread (SurfaceHolder surfaceHolder, firstClass first){
_surfaceHolder = surfaceHolder;
_firstClass= first;
}
public void setRunning (boolean run){
_run = run;
}
#Override
public void run(){
while(_run){
Canvas c=null;
try{
c = _surfaceHolder.lockCanvas(null);
synchronized(_surfaceHolder){
_firstThread.onDraw(c);
}
} finally {
}
if (c!=null){
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
I have a secondThread class that is the same as above with a different name and that calls secondCircle's onDraw().
When i run this program it only shows the blue circle and not the red circle. Why is this?

when you add the views, add them with layout parameters. Its possible the 1st view is filling the parent, leaving no space for the second view.
you could do something like
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layout.addView(first,p);
layout.addView(second,p);

Related

onfocuschanged never gets called for surfaceview (android)

In my android app i have activity containing a surfaceview. I want to start the surfaceview thread when the surfaceview/activity is visible to user. I have tried starting the thread in OnSurfaceCreated. That works but on some mobiles(samsung) The activity takes many seconds to become visible.The screen turns black when i resume activity. So i googled and found that when a view becomes visible onFocusChanged is called. I tried implementing OnFocusChanged in surfaceview but it is never called. below is my surfaceview class.
public class ImageSurface extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
private SurfaceHolder sHolder;
private ImageHolder imageHolder;
Bitmap mybit;
Bitmap orgiBitmap;// ;)
int message;
Context context;
private String valMagField;
public ImageSurface(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true);
clearFocus();
drawThread = new DrawThread(context);
}
public void setImageHolder(ImageHolder imageHolder){
this.imageHolder = imageHolder;
}
public void setBitmap(String filePath){
}
public void resume(){
drawThread.resumeThread();
}
#Override
public void onFocusChanged(boolean focus,int direction,Rect rect){
super.onFocusChanged(focus, direction, rect);
Log.d("in focus changed","onfocuschanged"+System.currentTimeMillis());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
drawThread.setSurfaceSize(width, height);
resume();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
long startTime, stopTime;
startTime = System.currentTimeMillis();
sHolder = holder;
drawThread.setRunning(true);
if(drawThread.getState()==Thread.State.NEW){
drawThread.start();
}
if(drawThread.getState()==Thread.State.TERMINATED){
drawThread = new DrawThread(context);
drawThread.setRunning(true);
drawThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
drawThread.pauseThread();
}
class DrawThread extends Thread{
int value=0;
private Boolean drun;
int valSize =30;
Context context;
private int sHeight , sWidth;
int lastmessage;
boolean threadPaused= false;
public DrawThread(Context context){
drun = false;
this.context = context;
}
public void pauseThread(){
synchronized(this){
threadPaused = true;
this.notify();
}
}
public void resumeThread(){
synchronized(this){
threadPaused = false;
this.notify();
}
}
public void setRunning(Boolean run){
drun = run;
}
public boolean isRunning(){
return drun;
}
public void setSurfaceSize(int width , int height){
sWidth = width;
sHeight = height;
}
#Override
public void run(){
while(drun){
Canvas c = null;
//Log.d("yes","thread is running");
try{
synchronized(this){
if(threadPaused)
try {
this.wait();
} catch (InterruptedException e) {
Log.d("in wait of surface view thread","error"+e.toString());
}
}
c = sHolder.lockCanvas(null);
synchronized(sHolder){
updateCanvas(c);
}
}finally {
if(c!=null){
sHolder.unlockCanvasAndPost(c);
}
}
}
}
private void updateCanvas(Canvas canvas){
try{
if(imageHolder.dispBit!= null){
int x=(sWidth-imageHolder.dispBit.getWidth())/2,y=(sHeight-imageHolder.dispBit.getHeight())/2;
imageHolder.applyEffects();
if(canvas!=null)
canvas.drawBitmap(imageHolder.dispBit, x,y,null);
}
else if(imageHolder!=null)
imageHolder.setDisplaySize(sWidth, sHeight);
}catch(Exception e){
e.printStackTrace();
}
}
}
}

SurfaceView and xml

I have program where i use my SurfaceView class. But i want to add ad in my game.To do it i must add xml and use it (i never use xml file and know few about it). Help me pls whith it.
Main Activity on create:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThisActivity=this;
new Game(this);
setContentView(Game.game);
}
Game:
public class S_Game extends SurfaceView implements CallBack{
public S_Game(Context context){
super(context);
getHolder().addCallback(this);
game=this;
sinh0=false;
sinh1=false;
sinh2=true;
String abas=" "+"";
spacekey=abas.hashCode();
paint=new Paint();
paint.setColor(0xffff0000);
paint.setTextSize(20);
pickx=new AtomicInteger[3];
picky=new AtomicInteger[3];
ifpick0=new AtomicBoolean[3];
for(int i=0;i<3;i++){
pickx[i]=new AtomicInteger();
picky[i]=new AtomicInteger();
ifpick0[i]=new AtomicBoolean();
}
pickt=new AtomicInteger();
NewTimer();
}
public void NewTimer(){
upd=new S_Updater(this);
timer=new Timer();
timer.schedule(upd,250,40);
}
public void Init(){
if(getHeight()>getWidth()){
S_Graff.thisindgraff=0;
}else{
S_Graff.thisindgraff=1;
}
DisplayMetrics metrics = new DisplayMetrics();
MainActivity.ThisActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
xdpi=SK(metrics.xdpi);
ydpi=SK(metrics.ydpi);
xdpi=SK(metrics.densityDpi);
float sm=xdpi/3;
float sms=(55/sm);
dpi=sms;
wind=new S_Window(0,0,760,1430);
Board.psize=KonK(18);
Board.DY/=sms;
if(dpi<=0.55){
dpi=0.55f;
}
String s="|";
Board.LINE=s.hashCode();
}
public void Update(Canvas cnv){
if(getHeight()>getWidth()){
maxx=smaxx;
maxy=smaxy;
kx=maxx/getWidth();
ky=maxy/getHeight();
kk=kx;
S_Graff.thisindgraff=0;
debug0=""+maxy+"/"+getHeight();
debug1=""+maxx+"/"+getWidth();
}else{
maxx=smaxy;
maxy=smaxx;
kx=maxx/getWidth();
ky=maxy/getHeight();
kk=ky;
S_Graff.thisindgraff=1;
}
if(binit){LInit();binit=false;}
for(int i=0;i<3;i++){
if(!ifpick0[i].get()){
float px=pickx[i].get();
px/=1000;
float py=picky[i].get();
py/=1000;
ifpick0[i].set(true);
S_Window.Pick(px,py,i);
}
}
S_Graff.OnRotAll();
cnv.drawColor(0xffffffff);
//I draw all S_Graffs in Update
S_Graff.Update(cnv);
Board.UpdateText(cnv);
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}
#Override
public void surfaceCreated(SurfaceHolder holder) {
//new Timer().schedule(upd,250,40);
/*Canvas c = getHolder().lockCanvas();
Update(c);
getHolder().unlockCanvasAndPost(c);*/
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
S_Updater:
public class S_Updater extends TimerTask{
public S_Game game;
public SurfaceHolder surfaceHolder;
static boolean isrun=true,ispause;
public S_Updater(S_Game g) {
game=g;
surfaceHolder=g.getHolder();
}
#Override
public void run() {
Canvas canvas=null;
try {
synchronized (surfaceHolder) {
if(surfaceHolder.getSurface().isValid()){
canvas=surfaceHolder.lockCanvas(null);
if(canvas!=null){
game.Update(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
finally {}
}
}

surface view not drawing anthing ... frame skipped message

public class CannonView extends SurfaceView implements SurfaceHolder.Callback {
CannonThread cannonThread;
private Paint blockerPaint;
public CannonView(Context context, AttributeSet attrs) {
super(context, attrs);
blockerPaint = new Paint();
blockerPaint.setStrokeWidth(10.0f);
getHolder().addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
cannonThread = new CannonThread(holder);
cannonThread.running(true);
cannonThread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
cannonThread.running(false);
while (retry) {
try {
cannonThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
private class CannonThread extends Thread {
boolean setRunning;
SurfaceHolder surfaceHolder;
public CannonThread(SurfaceHolder holder) {
setRunning = true;
surfaceHolder = holder;
}
public void running(boolean isRunning) {
setRunning = isRunning;
}
#Override
public void run() {
Canvas canvas = null;
while (setRunning) {
try {
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
canvas.drawLine(0, 0, 100, 100, blockerPaint);
}
} finally {
if (canvas != null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
Although above code is very simple
but it is not drawing anything on my activity ..
Logcat says i am doing too much work on main thread ..62 frame skipped ..
Please help
Well this isn't my style of coding, so I decided that you need to simplify things a bit. You used the android api guides but they suck.
Watch the following videos and you should be fine.
http://www.youtube.com/watch?v=wUmId0rwsBQ&list=SP2F07DBCDCC01493A&index=67
http://www.youtube.com/watch?v=0wy907WZFiA&list=SP2F07DBCDCC01493A
http://www.youtube.com/watch?v=ZMcYbf9Hhe4&list=SP2F07DBCDCC01493A
http://www.youtube.com/watch?v=yowNavIDzzE&list=SP2F07DBCDCC01493A

Buttons not working with Surface view

I am new to Android and I am trying to add start and reset buttons with a custom surface view. I am able to draw canvas with a circle which is moving with touch.
Now my problem is that when I click the start button, the circle must take its initial position (10,10).
My activity class
public class OpenGlActivity extends Activity implements OnClickListener {
GameView GameView;
FrameLayout Frame;
LinearLayout canvas;
Button btnStart, btnReset;
TutorialThread GameThread;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
GameView = new GameView(this);
btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
btnReset = (Button) findViewById(R.id.btnReset);
btnReset.setOnClickListener(this);
GameView.setOnTouchListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
Log.i("openGl", "play called");
GameView.setState();
// drawView.invalidate();
break;
case R.id.btnReset:
// GameView.play=true;
// GameView.reset();
Log.i("openGl", "RESETcalled");
// drawView.invalidate();
break;
}
}
}
Custom surfaceview class and thread class
class GameView extends SurfaceView implements SurfaceHolder.Callback {
String TAG = "GameView";
private TutorialThread _thread;
Paint paint = new Paint();
Paint red = new Paint();
Paint black = new Paint();
int x = 20;
int y = 20;
public GameView(Context context) {
super(context);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
// TODO Auto-generated constructor stub
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
red.setColor(Color.RED);
red.setAntiAlias(true);
black.setColor(Color.BLACK);
black.setAntiAlias(true);
setFocusable(true);
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
// TODO Auto-generated constructor stub
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
red.setColor(Color.RED);
red.setAntiAlias(true);
black.setColor(Color.BLACK);
black.setAntiAlias(true);
setFocusable(true);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
return true;
}
public void setState() {
Log.i(TAG, "in setState");
_thread.play();
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawCircle(x, y, 10, red);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
String TAG = "TutorialThread";
private SurfaceHolder _surfaceHolder;
private GameView _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, GameView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
public void play() {
synchronized (_surfaceHolder) {
_panel.x = 10;
_panel.y = 10;
Log.i(TAG, "in Play");
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.example.opengl.GameView
android:id="#+id/gameView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<Button
android:id="#+id/btnReset"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Reset" />
</LinearLayout>
</FrameLayout>

How to display the Canvas part of a view in android?

I am working on a code where we use canvas to detect the touch on the screen.As of now the canvas is been directly drawn.How to add it as part of a view which comprises of other elements in xml.Here is the code
public class Tutorial2D extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new Panel(this));
}
}
Here is the other part of it
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
private ViewThread mThread;
private ArrayList<Element> mElements = new ArrayList<Element>();
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
mThread = new ViewThread(this);
}
public void doDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
synchronized (mElements) {
for (Element element : mElements) {
element.doDraw(canvas);
}
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (!mThread.isAlive()) {
mThread = new ViewThread(this);
mThread.setRunning(true);
mThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread.isAlive()) {
mThread.setRunning(false);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (mElements) {
mElements.add(new Element(getResources(), (int) event.getX(), (int) event.getY()));
}
return super.onTouchEvent(event);
}
}
How to add this canvas to the main xml and been displayed over an image,any snippet on this or how should I change working on this code,anything will be greatful.Thanks
Try this constructor for the Panel class:
public Panel(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
mThread = new ViewThread(this);
}
You can use the custom view in xml layout with its package name. For example, in main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello" />
<your.package.name.Panel
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Then, in onCreate of your activity:
setContentView(R.layout.main);

Categories

Resources