I am unable to display both the setContentView(R.layout.main) and View together. I think I am not getting the concept right. Could anyone explain me where I am going wrong. Thank you. //please read the comment in code
I am trying to display a image on main.xml using BitmapFactory.
public class TryGraph extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);//I think this is where I need your help
setContentView(new myView(this));//I want this to be displayed in main.xml
}
private class myView extends View{
public myView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sinewave);
Bitmap resizedBitmap = Bitmap.createBitmap(myBitmap, 0, 0,
300, 143);
canvas.drawBitmap(resizedBitmap, 60, 50, null);
Paint myPaint = new Paint();
myPaint.setColor(Color.RED);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(5);
canvas.drawRect(250,255,260,250, myPaint);
}
}
}
THE XML FILE IS
When you call setContentView you are telling the device to load the entire layout that should be displayed to the user. In most cases this view will occupy the entire screen. Now this Layout file is considered the root and may contain child views, one of which should be your ImageView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/banner"
android:text="hello world"
>
<ImageView
android:id="#+id/myImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/sampleimage"
/>
<?LinearLayout>
This ImageView can now be accessed by code through the use of findViewById(R.id.myImageView) and you can then use the BitmapFactory to set your image. If the image is not going to be changed, you can just set it in the layout file android:src="#drawable/sampleimage"
Related
I'm new on Android, and I am having trouble with the following:
I have an image of an empty test-tube (png or bmp).
And I need to draw lines on top of it to make the illusion that its being filled in with liquid.
I really don't know how to proceed. I have read google's documentation about animations, but that didn't help much.
I'd appreciate if you guys could give me some suggestions of how it can be done, and point to some tutorials/documentation that can help me.
Thanks in advance.
UPDATE:
The tube is not retangular, the bottom is oval.
I think I need to make the liquid fall into the test tube, then paint line by line, starting from the bottom. And I have to check for the borders of the tube (right and lef black pixels).
Any ideas of how this can be done?
UPDATE 2:
Here is the tube image: http://i61.tinypic.com/2nw0eb9.png
You can use a SurfaceView to draw what ever you want:
Basicly, you lock the surface's canvas by
Canvas canvas = mSurfaceView.getHolder().lockCanvas();
Then, use the canvas's methods to draw on it. canvas.drawBitmap, canvas.drawLine etc..
When you're finished lock the canvas with mSurfaceView.getHolder().unlockCanvasAndPost(canvas); and you're done.
here's an example from a quick google search:
http://android-coding.blogspot.co.il/2011/05/drawing-on-surfaceview.html
Best way to do this would be with a custom View. Make a new class, that extends View, then in its onDraw method first draw the picture, then draw your animations. If you want to do it by hand, you can do something like this:
private class TestTubeView extends View {
private int top = 0;
private Paint myPaint;
public MyView(Context context) {
super(context);
myPaint = new Paint();
myPaint.setColor(getResources().getColor(R.color.blue));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//First draw your bitmap
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.my_testtube), 0, 0, myPaint); //might need to use a different paint
//Then your "animation" as a static image, that has its position set from a variable, in this case "y" and "x"
canvas.drawRect(0, top, getWidth(), getHeight(), myPaint);
}
//In this method update your variables, that define the positions of your animated lines / bubbles
public boolean updateAnimation() {
top++;
invalidate();
//So it stops animationg
return top > getHeight();
}
}
Then in your layout you put it in like a normal view:
<com.example.TestTubeView
android:id="#+id/my_testtube"
android:layout_width="20dp"
android:layout_height="200dp" />
And then you animate it with a self-repeating Runnable:
final MyView testTube = findViewById(R.id.my_testtube);
final Handler myHandler = new Handler();
myHandler.post(new Runnable() {
#Override
public void run() {
if(testTube.updateAnimation()){
myHandler.postDelayed(this, 200);
}
}
});
You'll have to play around with sizes / heights and things like that though. Another way of doing this is with an ObjectAnimatior
Tube Drawable: (this is for test purposes. you will use your tube image)
tube.xml (drawable folder)
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="5dp" android:color="#ffccffff" />
<solid android:color="#00000000" />
</shape>
tube_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/orangeJuiceLinearLayout"
android:layout_width="140dp"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:orientation="vertical"
android:background="#fff58225">
</LinearLayout>
<ImageView
android:id="#+id/tubeImageView"
android:layout_width="140dp"
android:layout_height="220dp"
android:layout_gravity="center"
android:background="#drawable/tube"
android:onClick="fillJuice"
android:clickable="true" />
</FrameLayout>
</LinearLayout>
TubeAcivity.java
public class TubeActivity extends Activity {
LinearLayout orangeLL;
ImageView tubeIV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tube_activity);
orangeLL = (LinearLayout)findViewById(R.id.orangeJuiceLinearLayout);
tubeIV = (ImageView)findViewById(R.id.tubeImageView);
}
public void fillJuice(View view) {
ValueAnimator va = ValueAnimator.ofInt(0, tubeIV.getMeasuredHeight());
va.setDuration(1500);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
orangeLL.getLayoutParams().height = value.intValue();
orangeLL.requestLayout();
}
});
va.start();
}
}
The following program draws a pie (partial circle, a sector) while I expect it draw entire (full round) circle. How to draw entire circle?
The code of custom view:
public class CentralCircleView extends View {
private Paint circlePaint = new Paint();
{
circlePaint.setColor(Color.RED);
circlePaint.setAntiAlias(true);
}
public CentralCircleView(Context context) {
super(context);
}
public CentralCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(0, 0, 100, circlePaint);
}
}
The code of activity:
public class TransformsActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CentralCircleView centralCircleView = (CentralCircleView) findViewById(R.id.centralCircleView);
centralCircleView.setTranslationX(200f);
centralCircleView.setTranslationY(200f);
centralCircleView.invalidate();
}
}
The code of layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.inthemoon.incubation.CentralCircleView
android:id="#+id/centralCircleView"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>
This is what it draws. Where is the rest of the circle?
Your View has its height set to wrap_content which means you need to implement the method onMeasure() to tell RelativeLayout how big the view wants to be.
To draw "outside the view" one should use clipRect() method. For example, in my case, I was to write onDraw() in the following way:
protected void onDraw(Canvas canvas) {
canvas.clipRect(new Rect(-100,-100,100,100), Region.Op.UNION);
canvas.drawCircle(0, 0, 100, circlePaint);
}
I have a XML file in my program like:
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#ef3"
android:id="#+id/img01"/>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#E8A2B4"
android:id="#+id/img02"/>
</LinearLayout>
Also, I have a canvas draw function in my activity.
public class ImgTestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
private class iniView extends View {
public iniView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//set background color
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawCircle(this.getWidth()/2, this.getHeight()/2, 30, paint);
}
}
}
I read some articles from Internet. Some people create there own view in activity and set the paint into it.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView myView=new MyView(this);
setContentView(myView);
}
But I want to set my paint into this two LinearLayout.
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#ef3"
android:id="#+id/img01"/>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#E8A2B4"
android:id="#+id/img02"/>
How can I do that? (I want to draw two same circles in the center of this two linear layout)
One solution would be to extract the initView (should be CamelCase btw) and then inject it into the xml with the full path name of the class of the View as the tag name. Let's see an example. The resultant class should look like this:
package your.package;
// imports
private class CircleView extends View {
public iniView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
// your painting stuff
}
}
And the the xml should be something like this:
<your.package.CircleView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#ef3"
android:id="#+id/img01"/>
<your.package.CircleView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#E8A2B4"
android:id="#+id/img02"/>
Although you may want to have a look at the available Drawable resources in Android: http://developer.android.com/guide/topics/resources/drawable-resource.html
There is a Shape Drawable type that may allow you to do what you want in a simpler way and separated from the business logic of the Activity.
Hope it helps
You can render your xml view using this:
View viewalias = (View) this.findViewById(R.layout.yourxml);, then draw on it as you like, for more details, see this.
try this :
...
import android.util.AttributeSet;
...
public iniView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
...
I have one image view (assigned one bitmap to it) and another bitmap (Transparent) for painting. How it is possible to scroll this bitmap and background bitmap at the same time to be painted at different places.
From what I understood you are trying to draw on top of a image. If thats the case, create a custom view and get the image using BitmapFactory. After you get a bitmap object, use its copy method and use that copy for the canvas of the view.
Now you can override the onDraw method of a custom view and draw anything on top of it.
This view can be added to the layout, and scrolling will happen to the view.
Edit: Sample Code
Ok this is some code that might help you. I dont have the time to go through all your code.
But I tried to understand your requirement.
I am showing the code for an activity, its xml and custom view
Activity.java
public class DrawDemo extends Activity {
private FrameLayout container;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.draw_demo_layout);
container = (FrameLayout)findViewById(R.id.sc);
container.addView(new DrawView(this));
}
public void drawHandler(View target){
container.addView(new DrawView(this));
}
public void clearHandler(View target){
if(container.getChildCount() != 1){
container.removeViewAt(container.getChildCount()-1);
}
}
}
draw_demo_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="0dip"
android:id="#+id/sc" android:scrollbars="horizontal"
android:layout_weight="1.0">
<ImageView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/chips"/>
</FrameLayout>
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Draw"
android:onClick="drawHandler"/>
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Clear"
android:onClick="clearHandler"/>
</LinearLayout>
DrawView.java
public class DrawView extends View {
public DrawView(Context context) {
super(context);
setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.FILL_PARENT
,LinearLayout.LayoutParams.FILL_PARENT));
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
p.setColor(Color.RED);
p.setStrokeWidth(5);
canvas.drawLine(50, 50, 100, 150, p);
canvas.drawLine(100, 150, 20, 50, p);
}
}
This activity has a framelayout which has a imageview as the base which holds the bitmap.
We add a custom draw view on top of it and do our drawings on it.When we want to clear the drawing we remove the drawview and add another one if we need to draw again.
This might not be the most efficient way. But should get you started.
I'm new to android graphic so hold on to your hats!
The screen is black whatever i do.
I draw a circle and i draw bitmap and noting shows.
Here is xml,code and a picture showing my screen.
Im thinking i have to set the size of the ImageView maybe that's why it's black??!
R.layout.main1
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.hasse.move.DrawView
android:id="#+id/mainView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#00FF00"
android:adjustViewBounds="true"
/>
<RelativeLayout
android:id="#+id/InnerRelativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<EditText
android:id="#+id/edittextaddtext"
android:layout_width="fill_parent"
android:layout_toLeftOf="#+id/btnsave"
android:layout_height="wrap_content"
android:text="wrap"
/>
<Button
android:id="#+id/btnsave"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
/>
</RelativeLayout>
</RelativeLayout>
DrawView class
public class DrawView extends ImageView {
private Context ctx;
public DrawView(Context context, AttributeSet atts) {
super(context, atts);
this.ctx = context;
}
#Override
protected void onDraw(Canvas canvas) {
String filePath = Environment.getExternalStorageDirectory().toString() + "/PTPPservice/163693fe-7c48-4568-a082-00047123b9f1.2.IMAG2200.jpg";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile(filePath,options);
canvas.drawBitmap(bitmap, 10,10, null);
canvas.drawCircle(10,10,10,null);
}
}
main Activity
public class Main extends Activity {
DrawView theImage;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// draw the view
setContentView(R.layout.main1);
theImage = (DrawView) findViewById(R.id.mainView);
//do stuff
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
// Toast.makeText(this, "onConfigurationChanged",Toast.LENGTH_LONG).show();
super.onConfigurationChanged(newConfig);
}
}
Image
Looking at your code, your unlikely to see the circle as your trying to draw it with a null paint object. To test your code make sure you use a Paint object with a colour that contrasts the background colour. Secondly, I would call the super object method e.g.
super.onDraw(canvas);
I'm not 100% sure about drawing the bitmap with a null Paint object.
Also, check the package name of your DrawView class (com.hasse.move.DrawView) in your layout file matches that of the actual DrawView class.