I have this Android program in which I want to display a Rectangle within the ImageView of the parent layout. The components are set on this hierarchy and following the layout listed below. The code to display the rectangle are also indicated below:
LinearLayout [Vertical]
Spinner
ImageView
<LinearLayout 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:orientation="vertical">
<Spinner
android:id="#+id/spinMap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#android:layout/simple_spinner_item" />
<ImageView
android:id="#+id/imageMap"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black" />
</LinearLayout>
CODE:
public class MainActivty extends Activity {
private Display display;
private Spinner spinMap;
private ImageView imageMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initailize();
}
private void initailize() {
display = getWindowManager().getDefaultDisplay();
spinMap = (Spinner) findViewById(R.id.spinMap);
imageMap = (ImageView) findViewById(R.id.imageMap);
imageMap.draw(drawMap());
}
private Canvas drawMap() {
Canvas canvas = new Canvas(Bitmap.createBitmap(display.getWidth(), display.getHeight(), Bitmap.Config.RGB_565));
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(10.0f, 10.0f, 100.0f, 100.0f, paint);
return canvas;
}
}
The problem is that when I run the application, the Rectangle don't get display. How can I display the Rectangle?
I think this can help you Android - Canvas drawLine inside ImageView
You should create bitmap with a rectangle and then feed it to ImageView
Related
I want to draw dynamically a circle on top of a drawable. So i created this class:
public class CustomTextViewDrawable extends LayerDrawable {
private Paint mPaint;
private View mParent;
public CustomTextViewDrawable(View parent, Drawable[] layers) {
super(layers);
mParent = parent;
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
float radius = 5;
// Top-left corner
float centerX = 0;
float centerY = 0;
// Draw circle
mPaint.setColor(Color.RED);
mPaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawCircle(centerX, centerY, radius, mPaint);
}
#Override
public boolean isStateful() {
return false;
}
}
And my usage is the following:
// Get the drawable set in XML file ...
Drawable[] layers = new Drawable[] { imageView.getDrawable() };
Drawable d = new CustomTextViewDrawable(imageView, layers);
// ... and replace it
imageView.setImageDrawable(d);
What i wanted to get is 1/4 of a circle with center in top-left corner, but what i get is the following (with "show layout bounds" options enabled in my device):
Can someone tell me why the point (0, 0) is there? Shouldn't it be placed on top-left corner?
Edit
Here is the XML layout file:
<?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="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp" >
<!-- Some views here ... -->
<ImageButton
android:id="#+id/questions_answers"
android:layout_width="wrap_content"
android:src="#drawable/ic_action_help"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#id/..."
android:contentDescription="#string/..." />
</RelativeLayout>
<!-- Some other views here ... -->
</LinearLayout>
Try to draw that point in your ImageView or set to your imageView android:scaleType="fitStart". Maybe your imageView creates some padding by default which depends on scaleType.
I have a android.graphics.Path variable which I want to convert into an ImageView in my activity.
What I do right now and does NOT work (but it does run without error, it just displays a blank activity) is:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Path p = ... // some bezier curves
PathShape pathShape = new PathShape(path, (float)20.0, (float)20.0);
ShapeDrawable shapeDrawable = new ShapeDrawable(pathShape);
ImageView testImage = (ImageView) findViewById(R.id.testImage);
testImage.setImageDrawable(shapeDrawable);
}
}
The corresponding activity_main.xml is:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.tg.MindGames.set.MainActivity">
<ImageView
android:id="#+id/testImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
What did I do wrong and what is considered best practice to put Path into an ImageView?
Additional Information: I want to use the Paths to draw the images of cards in a simple card game. Several cards and additional text fields should be displayed on the activity at the same time, cards should be able to have an onClickListener.
The size of 20.0 x 20.0 is arbitrary and should be altered later when I use the ImageViews in a GridView.
so here you have a red triangle drawn on the view's background:
View v = new View(this);
Path path = new Path();
path.moveTo(0, 1);
path.lineTo(0.5f, 0);
path.lineTo(1, 1);
ShapeDrawable sd = new ShapeDrawable(new PathShape(path, 1, 1));
sd.getPaint().setColor(Color.RED);
v.setBackgroundDrawable(sd);
setContentView(v);
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();
}
}
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.