From android.graphics.Path to ImageView - android

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);

Related

Add image on another image in android

In my application, I want to add an image on another image and also when user zoom on image at that time it should also move, Just like google map.
Please have a look at below image and i want to set flag dynamically
Please advice better way to complete this task.
Use relative layout as background and place the images as the component of relative layout, use the relative layout params to adjust the images locations on the screen.you can apply zoom on the relative layout itself
Solution (XML):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/t" />
<item android:drawable="#drawable/tt" />
</layer-list>
Solution (dynamic):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/activity_main"
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="maxdorid.ir.MainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="#mipmap/ic_launcher"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/imageView" />
</RelativeLayout>
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = r.getDrawable(R.drawable.ic_alarm_off_black_24dp);
layers[1] = r.getDrawable(R.drawable.ic_apps_black_24dp);
LayerDrawable layerDrawable = new LayerDrawable(layers);
ImageView imageView= (ImageView) findViewById(R.id.imageView);
imageView.setImageDrawable(layerDrawable);
}
}
If you use more than one image:
private Bitmap overlay(Bitmap bmp1, Bitmap bmp2,int x,int y) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, x,y, null);
return bmOverlay;
}

How to make line and circle with button and Text view in the same Activity

How can I make a line with Button in the same Activity?
After I made a Button in XML file, I tried to make a line.
But when I tried to make line, I could not use
setContentView(R.layout.activity_main);
I could use this:
ViewMenu vm = new ViewMenu(this);
vm.setBackgroundColor(Color.BLACK);
setContentView(vm);
How can I make line with Button in the same Activity?
Could anyone add an example code??
add code
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: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=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button" />
</RelativeLayout>
Methode onCreate() in MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
ViewMenu vm = new ViewMenu(this);
vm.setBackgroundColor(Color.BLACK);
setContentView(vm);
}
ViewMenu class
public class ViewMenu extends View {
Paint paint = new Paint();
public ViewMenu(Context context) {
super(context);
paint.setColor(Color.WHITE);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawLine(0, 0, 1000, 1000, paint);
canvas.drawLine(500, 1000, 700, 10, paint);
}
}
Add your custom view to the layout's xml file
You can use an custom view to draw the line such as LineView.
In your XML put the code like below to achieve the layout you want. So you can set the line whenever you want(At specific position like at above, below, left or right of any component).
<com.android.drawable.LineView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/firstButton"
android:layout_toLeftOf="#id/secondButton"
android:layout_below="#id/leftButton"
android:layout_above="#id/rightButton"
/>

Drawing on top of an image to create an animation

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();
}
}

Android ImageView drawing objects

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

SeekBar drawable not drawn after being reused by Adapter

I need to paint an overlay image onto a SeekBar in my ListView rows. This isn't too hard to do and the code in this question accomplishes that by painting the row number in a bitmap and placing it as the progress drawable.
The problem that I am having is that this only works one time. When the view is recycled to be used for another row, the drawable disappears.
The first 10 views (positions 0 through 9) worked. Everything after that fails. There is no error or exception. Android just stops drawing that layer. If I scroll down and then back up, none of them work (as they have all been recycled).
How do I get Android to always draw this overlayed image? I imagine there is some sort of caching or invalidation that I need to perform, but I just don't know what it is yet.
public class ViewTest extends ListActivity {
// replace the progress drawable with my custom drawable
public void setSeekBarOverlay(SeekBar seekBar, String overlayText) {
Bitmap bitmap = Bitmap.createBitmap(100, 12, Bitmap.Config.ARGB_4444);
new Canvas(bitmap).drawText(overlayText, 10, 12, new Paint());
Drawable d = new BitmapDrawable(bitmap);
((LayerDrawable) seekBar.getProgressDrawable()).setDrawableByLayerId(android.R.id.progress, d);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setListAdapter(new ListAdapter() {
// return the view. Recycle them if possible.
public View getView(int pos, View v, ViewGroup vg) {
if (v == null) {
v = View.inflate(ViewTest.this, R.layout.seekbar, null);
}
String s = String.valueOf(pos);
((TextView) v.findViewById(android.R.id.text1)).setText(s);
setSeekBarOverlay((SeekBar) v.findViewById(R.id.seekbar), s);
return v;
}
... cut ...
});
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
seekbar.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="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight">
<TextView
android:id="#android:id/text1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content" />
<SeekBar
android:id="#+id/seekbar"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
</LinearLayout>
This is a tough one that I don't think will get much traffic, so I'm going to answer it myself since I found the solution.
Another SO question/answer, Android ProgressBar.setProgressDrawable only works once?, got me halfway there but the solution didn't work for me. In the other question, the code was trying to replace the entire progressDrawable (setProgressDrawable()). I'm not doing that here as I'm just updating a layer in the existing progressDrawable. After some playing around, with similar approaches, I found something that worked. You have to get the bounds of the drawable that is being updated (in this case, one of the layers) and set the bounds later.
Seems like a bug in the platform, but this workaround seems to make it work. Hope this helps someone else someday.
public void setSeekBarOverlay(SeekBar seekBar, String overlayText) {
LayerDrawable layerDrawable = (LayerDrawable) seekBar.getProgressDrawable();
Drawable overlayDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress);
Rect bounds = overlayDrawable.getBounds();
Bitmap bitmap = Bitmap.createBitmap(100, 12, Bitmap.Config.ARGB_4444);
new Canvas(bitmap).drawText(overlayText, 10, 12, new Paint());
overlayDrawable = new BitmapDrawable(bitmap);
overlayDrawable.setBounds(bounds);
layerDrawable.setDrawableByLayerId(android.R.id.progress, overlayDrawable);
}

Categories

Resources