I'm trying to draw fractal on a SurfaceView within asynctask but I'm not sure how to perform it properly. My idea was to create surfaceview (in the main activity) which would contain progress bar, while separate thread would calculate which pixels will be drawn and store this on some kind of "buffer" (I use canvas for this). After that on the surfaceview result should be drawn (which should destroy spinning wheel of progress bar).
I've written this code:
MainActivity.java
public class MainActivity extends Activity {
private Complex constant;
private int bg_color, fg_color;
private static final int nMax = 30, rMax = 2;
private class JuliaThread extends AsyncTask<Complex, Void, Canvas> {
private double re, im, w, h;
private Complex sequence;
private int i;
private Canvas canv;
private Paint p;
private View m;
#Override
protected void onPreExecute() {
super.onPreExecute();
m = (View) findViewById(R.id.sv);
w = m.getWidth();
h = m.getHeight();
canv = new Canvas();
p = new Paint();
}
#Override
protected Canvas doInBackground(Complex... c) {
for (double y=0; y<h; y++) {
for (double x=0; x<w; x++) {
re = (x/w)*3.0-1.5;
im = -(y/h)*3.0-1.5;
sequence = new Complex(re, im);
for (i=1; i<=nMax; i++) {
sequence = sequence.square();
sequence.add(c[0]);
if (sequence.abs() > rMax) break;
}
if (i == nMax) p.setColor(fg_color);
else p.setColor(bg_color);
canv.drawLine((float)x, (float)y, (float)x, (float)y, p);
}
}
return canv;
}
#Override
protected void onPostExecute(Canvas result) {
super.onPostExecute(result);
m.draw(result);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
constant = new Complex(-0.391, -0.587);
bg_color = Color.rgb(0, 0, 0);
fg_color = Color.rgb(255, 255, 255);
new JuliaThread().execute(constant);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:id="#+id/mainview" >
<SurfaceView
android:id="#+id/sv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</SurfaceView>
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/sv"
android:layout_centerHorizontal="true"
android:layout_marginTop="138dp" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/progressBar1"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:text="#string/loading"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Unfortunately, this approach doesn't work. Could you explain me, what am I doing wrong and how to do this properly?
You first need to obtain a SurfaceHolder from SurfaceView (by implementing SurfaceHolder.Callback). Then do something like:
final Canvas c = mSurfaceHolder.lockCanvas();
//---draw stuff--
mSurfaceHolder.unlockCanvasAndPost(c);
Related
How it looks
I want to check intersection between ImageView to ImageView2 as LinearLayout slides towards ImageView2.
I used Rect but it is not working, ImageView2 Just passed throught it without getting intersect.
Please help me!!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<ImageView
android:id="#+id/tile"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/tile" />
<LinearLayout
android:id="#+id/l1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageView
android:id="#+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
<ImageView
android:id="#+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
</LinearLayout>
#SuppressLint("NewApi")
public class MainActivity extends Activity {
Rect tileRect = new Rect();
Rect b1Rect = new Rect();
Rect b2Rect = new Rect();
ImageView tile,b1,b2;
RelativeLayout layout;
LinearLayout l1;
final Handler h = new Handler();
Boolean tileRight=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
move();
}
private void init() {
// TODO Auto-generated method stub
b1 = (ImageView)findViewById(R.id.b1);
b2 = (ImageView)findViewById(R.id.b2);
tile = (ImageView)findViewById(R.id.tile);
layout = (RelativeLayout)findViewById(R.id.layout);
l1 = (LinearLayout)findViewById(R.id.l1);
tile.setX(320);
tile.setY(800);
l1.setVisibility(View.VISIBLE);
}
public void move()
{
final int delay = 45;
h.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(tileRight==true)
tileRight=false;
else
tileRight=true;
return true;
}
return false;
}
});
if(tileRight==true)
{
if(tile.getX()>600f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()+speedTile);
}
}
else{
if(tile.getX()<40f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()-speedTile);
}
}
tile.getHitRect(tileRect);
b1.getHitRect(b1Rect);
b2.getHitRect(b2Rect);
if(Rect.intersects(tileRect, b1Rect) || Rect.intersects(tileRect, b2Rect))
{
gameOver();
}
l1.setY(l1.getY()+10f);
h.postDelayed(this, delay);
}
},delay);
}
private void gameOver() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android's View has getLocationOnScreen() method that shows absolute position of your view.
https://developer.android.com/reference/android/view/View.html#getLocationOnScreen(int[])
The issue occurs because view.getHitRect() is used before the layouts are inflated.
Any of the view's position or measurement APIs like getWidth(), getTop(), getRight() etc. will return 0 (getHitRect() initializes the Rect with (0,0,0,0)) in onCreate() or onResume() before the views are inflated.
In your case, it appears that the Handler's delay period executes the intersection logic earlier than view inflation.
You could post from the view and the run() method will execute after the view inflates and then obtain the view's measurement parameters or a Rect .
Here is an example:
public class MyTestActivity extends AppCompatActivity{
int mNumberOfViewsInitialized = 0;
ImageView mImageViewRight, mImageViewLeft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_image_activity);
mImageViewLeft = (ImageView) findViewById(R.id.image_view_left);
mImageViewRight = (ImageView) findViewById(R.id.image_view_right);
// calling method here will log that the views do not intersect
// which happens because they haven't been inflated yet.
// doViewsOverlap();
mImageViewLeft.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
mImageViewRight.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
}
private void intersectionLogic(){
/* the constant could be something else, depending
on the number of views you'd like to test intersection for*/
if(mNumberOfViewsInitialized == 2){
doViewsOverlap(mImageViewLeft,mImageViewRight);
}
}
private void doViewsOverlap(final View firstView, final View secondView){
Rect leftRect = new Rect();
firstView.getHitRect(leftRect);
Rect rightRect = new Rect();
secondView.getHitRect(rightRect);
if(Rect.intersects(leftRect,rightRect) || Rect.intersects(rightRect,leftRect))
Log.v("intersects","views intersect");
else
Log.v("intersects","views do not intersect");
}
}
I used a layout which does not animate / move the images, but the same issue should occur when the images are moved as well
<ImageView
android:id="#+id/image_view_left"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:background="#android:color/holo_blue_dark"
android:src = "#mipmap/ic_launcher"/>
<ImageView
android:id="#+id/image_view_right"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentRight="true"
android:background="#android:color/holo_green_dark"
android:gravity="end"
android:src="#mipmap/ic_launcher"/>
Images contained in a RelativeLayout.
Here is a screenshot of the UI:
This problem is related to this: If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Hope this helps.
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);
}
}
}
this is my first question! I have an activity (MainActivity) and a View (PanZoomView) which can be zoomable. The Layout is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.canvastest.PanZoomView
android:id="#+id/zoomview"
android:layout_width="300dp"
android:layout_height="300dp" />
<TextView
android:id="#+id/tv_mPosX"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<TextView
android:id="#+id/tv_mPosY"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</LinearLayout>
I want to set the tv_mPosX/Y strings according to zoom factor (mScaleFactor) that is computed in the view:
public class PanZoomView extends View {
protected Drawable mSampleImage;
protected Context mContext;
protected float mPosX;
protected float mPosY;
//
public float mScaleFactor = 1.f;
...
Where/How I can handle this?
Thanks to all,
Riccardo
mScaleFactor Ok guys, I found the solution.
1) I implemented in the View object a getter
2) This is my final activity, with a Thread which updates the UI
public class MainActivity extends Activity {
private Handler frame = new Handler();
private static final int FRAME_RATE = 40; // 1000ms/40ms = 25 frames per second
private PanZoomView w;
private TextView t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
w = (PanZoomView) findViewById(R.id.zoomview);
t = (TextView) findViewById(R.id.tv_mPosX);
frame.post(frameUpdate);
}
private Runnable frameUpdate = new Runnable() {
#Override
public void run() {
t.setText("mScaleFactor =" + w.get_mScaleFactor());
frame.postDelayed(frameUpdate, FRAME_RATE);
}
};
}
I add 2 fragments in tab host.In second fragment i can do some drawing. When i switch between these two fragments, my drawing in second fragment is removed.I don't know why??
This is second fragment.
public class DrawingFragment extends BaseFragment implements android.view.View.OnClickListener {
private Context context = null;
private Bitmap backGroundBitmap = null;
private DrawingViewHolder viewHolder = null;
/**
*
*/
#Override
public void onAttach(Activity arg0) {
super.onAttach(arg0);
this.context=arg0;
}
public DrawingFragment() {
}
public DrawingFragment(Bitmap bitmap) {
this.backGroundBitmap = bitmap;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.drawing_dialog, container,false);
viewHolder = new DrawingViewHolder();
viewHolder.initUiContents(view);
return view;
}
/**
*
* #author Qandil
*
*/
private class DrawingViewHolder{
private Button btnDoneDrawing = null;
private Button btnEraserDrawing = null;
private Button btnPencilDrawing = null;
private Button btnDeleteDrawing = null;
private LinearLayout llDrawingMain = null;
private DrawView drawingView = null;
private void initUiContents(View view){
btnDoneDrawing = (Button) view.findViewById(R.id.btn_drawing_done);
btnEraserDrawing = (Button) view.findViewById(R.id.btn_drawing_eraser);
btnPencilDrawing = (Button) view.findViewById(R.id.btn_drawing_pencil);
btnDeleteDrawing = (Button) view.findViewById(R.id.btn_drawing_delete);
llDrawingMain = (LinearLayout) view.findViewById(R.id.ll_drawing_dialog_main);
drawingView = (DrawView)view.findViewById(R.id.custom_dv2);
btnDoneDrawing.setOnClickListener(DrawingFragment.this);
btnEraserDrawing.setOnClickListener(DrawingFragment.this);
btnPencilDrawing.setOnClickListener(DrawingFragment.this);
btnDeleteDrawing.setOnClickListener(DrawingFragment.this);
Drawable dr = new BitmapDrawable(backGroundBitmap);
llDrawingMain.setBackgroundDrawable(dr);
}
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_drawing_done:
((CaseActivity) getActivity()).popFragments();
break;
case R.id.btn_drawing_delete:
((CaseActivity) getActivity()).popFragments();
break;
default:
break;
}
}
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onDestroyView()
*/
#Override
public void onDestroyView() {
super.onDestroyView();
}
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onDetach()
*/
#Override
public void onDetach() {
super.onDetach();
}
}
drawing_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_drawing_dialog_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/ll_drawing_dialog"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/img_draw_photo_bg"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/img_top_bar" >
<TextView
android:id="#+id/tv_draw_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="#string/tv_draw_picture"
android:textColor="#ffffff"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
<LinearLayout
android:id="#+id/ll_header_drawing_dialog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/img_top_bar"
android:gravity="center" >
<Button
android:id="#+id/btn_drawing_done"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/img_drawing_done" />
<Button
android:id="#+id/btn_drawing_eraser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:background="#drawable/img_drawing_eraser" />
<Button
android:id="#+id/btn_drawing_pencil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:background="#drawable/img_drawing_pencil" />
<Button
android:id="#+id/btn_drawing_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:background="#drawable/img_drawing_dlt" />
</LinearLayout>
<RelativeLayout
android:id="#+id/rlt_drawing_component"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<view
android:id="#+id/custom_dv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="com.avhl.view.activity.DrawView"
android:background="#00000000" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
DrawView.java
public class DrawView extends View{
private Bitmap cache;
private Queue<PointF> points;
private PointF from;
private Context context;
private Paint paint ;
public DrawView(Context context,AttributeSet attr) {
super(context,attr);
this.context=context;
points = new ConcurrentLinkedQueue<PointF>();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(8);
paint.setColor(Color.GRAY);
paint.setDither(true); // set the dither to true
paint.setStyle(Paint.Style.FILL_AND_STROKE); // set to STOKE
paint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want
paint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too
setFocusable(true);
setFocusableInTouchMode(true);
}
/***
* on touch event
*/
#Override
public boolean onTouchEvent(MotionEvent evt) {
setPressed(true);
int pointerIndex = ((evt.getAction() & MotionEvent.ACTION_POINTER_ID_MASK)
>> MotionEvent.ACTION_POINTER_ID_SHIFT);
int pointerId = evt.getPointerId(pointerIndex);
if(pointerId==0){
switch (evt.getAction()) {
case MotionEvent.ACTION_DOWN:
from = new PointF(evt.getX(), evt.getY());
break;
case MotionEvent.ACTION_MOVE:
points.add(new PointF(evt.getX(), evt.getY()));
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
default:
from = null;
}
}else{
return false;
}
return true;
}
/**
*
* #param systemCanvas
*/
#Override
public void onDraw(Canvas systemCanvas) {
int w = getWidth();
int h = getHeight();
if (w == 0 || h == 0)
return;
if (cache == null)
cache = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
// Draw on the cache
Canvas canvas = new Canvas(cache);
drawPoints(points, canvas, paint);
// Draw the cache with the system canvas
systemCanvas.drawBitmap(cache, 0, 0, paint);
}
/*
* for drawing line or dot
*/
private void drawPoints(Queue<PointF> points, Canvas canvas, Paint paint) {
if (from == null)
return;
PointF to;
while ((to = points.poll()) != null) {
canvas.drawLine(from.x, from.y, to.x, to.y, paint);
from = to;
}
}
}
In MianActivity i simply replace DrawingFragment tab with my first fragment by calling ft.replace() in on tab changed.
You can try calling Fragment.setRetainInstance(true) in the onCreate of your Fragment. This ensure the same fragment instance will be reused instead of creating a new one.
Without some code to show what you are doing, it is difficult to be more helpful
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!