Android layout shape without using background image? - android

How can i make a layout look like following snap in the case i don't want to use background image.

Create a nine patch image of a single image. Following link is helpful to you for generate nine patch image.
https://romannurik.github.io/AndroidAssetStudio/nine-patches.html

You can create an ImageView like that triangle and put it in the place you need.
Have a look how you can create triangle using xml: Android triangle (arrow) defined as an XML shape
Or even you can create a TextView:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="▼"/>
and put it in the place.
Unicode for the triangle: link

Use below code in Relative Layout. Hope it helps you.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableRight="#drawable/triangleImage"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"/>

You can also draw custom view:
public class MyBackground extends View{
private Path path = new Path();
private Paint paint = new Paint();
public MyBackground(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyBackground(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
public MyBackground(Context context) {
this(context, null);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.GRAY);
int triangleSide = getWidth() / 10; // triangle is 1/10-th of side
int offsetFromRightSide = triangleSide;
int startX = getWidth() - triangleSide - offsetFromRightSide;
path.reset();
path.moveTo(startX, 0);
path.lineTo(startX + triangleSide/2, triangleSide/2);
path.lineTo(startX + triangleSide, 0);
canvas.drawPath(path, paint);
}
}
and use it like this
<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:background="#drawable/background"
tools:context=".MainActivity">
<your.package.name.MyBackground
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Or there is one more "code way". Create custom background Drawable
public class Background extends Drawable {
private Path path = new Path();
private Paint paint = new Paint();
public Background(){
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
#Override
public void draw(Canvas canvas) {
int triangleSide = getBounds().width() / 10; // triangle is 1/10-th of side
int offsetFromRightSide = triangleSide;
int startX = getBounds().width() - triangleSide - offsetFromRightSide;
path.reset();
path.moveTo(startX, 0);
path.lineTo(startX + triangleSide/2, triangleSide/2);
path.lineTo(startX + triangleSide, 0);
canvas.drawColor(Color.GRAY);
canvas.drawPath(path, paint);
}
#Override public void setAlpha(int alpha) {}
#Override public void setColorFilter(ColorFilter cf) {}
#Override public int getOpacity() {return 0;}
}
And use it like this:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.root);
layout.setBackgroundDrawable(new Background());

Related

How to add a imageView in the centre of a customView?

I have a custom view that is a circle. Here is the code for my CircleView:
public class CircleView extends View {
private static final int START_ANGLE_POINT = 90;
private final Paint paint;
private final RectF rect;
private float angle;
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
final int strokeWidth = 40;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(strokeWidth);
//Circle color
paint.setColor(Color.RED);
rect = new RectF(strokeWidth, strokeWidth, 1000 + strokeWidth, 1000 + strokeWidth);
//Initial angle is zero
angle = 0;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint);
}
public float getAngle() {
return angle;
}
public void setAngle(float angle) {
this.angle = angle;
} }
and here is how I declare it in the xml layout of an activity:
<com.my_package.ui.recording.CircleView
android:id="#+id/circleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
All standard stuff. This is how my custom image looks like
Now, I want to place an imageView in the centre on the circleView? Does any one know how can I achieve that?
This is ideally what I would like to end up with:
Thank you in advance.
If you aren't set on using an ImageView and really just want to draw the bitmap in the center then have a look at canvas' drawBitmap method. This will allow you to draw it however/wherever you want.

objectanimator with custom view

I want to have a simple animation on my custom view.
I used the objectanimator but the custom view did not move.
When I try this with another object (like a textview) it works.
Below is my code. z1 is the custom view that I'd like to move.
public class FinalActivity extends Activity {
MyViewX z1;
TextView t1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
z1 = (MyViewX) findViewById(R.id.xview);
t1 = (TextView) findViewById(R.id.textView1);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if(hasFocus){
ObjectAnimator animation = ObjectAnimator.ofFloat(z1, "translationX", 100f);
animation.setDuration(5000);
animation.start();
}
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5sp"
tools:context=".FrmActivity" >
<com.test.game.myviewx
android:id="#+id/xview"
android:layout_width="200dp"
android:layout_height="200dp"
/>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="72dp"
android:layout_marginTop="173dp"
android:text="TextView" />
</RelativeLayout>
public class MyViewX extends View
{
public MyViewX(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyViewX(Context context, AttributeSet attributeset) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.base1);
int x=80;
int y=80;
int radius=40;
Paint paint=new Paint();
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#CD5C5C"));
canvas.drawCircle(x,x, radius, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
}
the code does not crash and seems to run but the circle and the bitmap in the custom view does not move.
what am I missing ?
I see one issue when you create constructor of your myviewx
please edit it
public class myviewx extends View {
public myviewx(Context context) {
super(context);
}
public myviewx(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public myviewx(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.base1);
int x = 80;
int y = 80;
int radius = 40;
Paint paint = new Paint();
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#CD5C5C"));
canvas.drawCircle(x, x, radius, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
}

Android - Google Maps inside CircleView

I wanted to show map inside a circle view where circle's outside area filled with a color. I referred a post Draw transparent circle filled outside. But now the problem is touch events. Map can be touched through outside circle view while I need map can be touched (zoom or move) only form inside Circle view (where the map is visible).
What I tried,
setEnabled=false
clickable=false
but still map is touched from outside circle view.
Is that possible to achieve that map can be touched from inside circle view.
public class RadiusOverlayView extends LinearLayout {
private Bitmap windowFrame;
public RadiusOverlayView(Context context) {
super(context);
}
public RadiusOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RadiusOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public RadiusOverlayView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (windowFrame == null) {
createWindowFrame(); // Lazy creation of the window frame, this is needed as we don't know the width & height of the screen until draw time
}
canvas.drawBitmap(windowFrame, 0, 0, null);
}
#Override
public boolean isEnabled() {
return false;
}
#Override
public boolean isClickable() {
return false;
}
protected void createWindowFrame() {
windowFrame = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); // Create a new image we will draw over the map
Canvas osCanvas = new Canvas(windowFrame); // Create a canvas to draw onto the new image
RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); // Anti alias allows for smooth corners
paint.setColor(Color.CYAN); // This is the color of your activity background
osCanvas.drawRect(outerRectangle, paint);
//paint.setColor(Color.TRANSPARENT); // An obvious color to help debugging
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); // A out B http://en.wikipedia.org/wiki/File:Alpha_compositing.svg
float centerX = getWidth() / 2;
float centerY = getHeight() / 2;
float radius = Math.min(getWidth(), getHeight()) / 2 - 50;
osCanvas.drawCircle(centerX, centerY, radius, paint);
}
#Override
public boolean isInEditMode() {
return true;
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
windowFrame = null; // If the layout changes null our frame so it can be recreated with the new width and height
}
}
XML layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--loading map in container-->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<mypackage.RadiusOverlayView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
/>
</RelativeLayout>
Result:
Any help will be appreciated.
You could set a View.OnTouchListener to your RadiusOverlayView and calculate whether the RadiusOverlayView needs to manage the touch events or not.
In this example I calculate this by testing if the RadiusOverlayView color touched is != 0 (maybe you want to improve this):
final RadiusOverlayView radiusOverlayView = (RadiusOverlayView) findViewById(R.id.radiusView);
radiusOverlayView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
view.setDrawingCacheEnabled(true);
Bitmap bmp = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return bmp.getPixel((int) motionEvent.getX(), (int) motionEvent.getY()) != 0;
}
});

android custom view redraw

I am trying to redraw the custom view in onCreate() method
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
circleView = (CircleView)findViewById(R.id.circleView);
circleView.setCircle(100, 100, 25);
circleView.wrapView();
}
and custom view is :
public class CircleView extends View
{
private Paint paint = null;
private int x = 50;
private int y = 50;
private int radius = 50;
public CircleView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public CircleView(Context context)
{
super(context);
init();
}
private void init()
{
paint = new Paint();
}
public void setCircle(int x, int y, int radius)
{
this.x = x;
this.y = y;
this.radius = radius;
init();
this.invalidate();
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
paint.setColor(Color.WHITE);
canvas.drawCircle(x, y, radius, paint);
Log.e("", "radius : " + radius);
}
public void setColor(int color)
{
paint.setColor(color);
}
public void wrapView()
{
this.setLayoutParams(new RelativeLayout.LayoutParams(radius*2, radius*2));
this.invalidate();
}
}
and xml is:
<?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"
android:id="#+id/layoutMain"
>
<com.pep1439.view.CircleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/circleView" />
</RelativeLayout>
i just want to resize the circle, but failed. Help me to draw circle with any radius. How to do this. Its working fine if i use default values. It draws the circle when i remove the line circleView.setCircle(100, 100, 25);. I want to adjust circle at run time.
thanks.
You set x and y to 100 and radius to 25. Then you resize your view to radius*2, which is 50, so in the end you're drawing a circle of radius 25 at position 100,100 on a view that is only 50x50 in size. In other words: You draw your circle outside the area of your view.

Draw text on ImageView doesn't work

I have extended class from ImageView and want some text to be drawn on it. This doesn't work, do you know why? Thank you.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int imgWidth = getMeasuredWidth();
int imgHeight = getMeasuredHeight();
float txtWidth = mTextPaint.measureText("your text");
int x = Math.round(imgWidth/2 - txtWidth/2);
int y = imgHeight/2 - 6; // 6 is half of the text size
canvas.drawText("your text", x, y, mTextPaint);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
mTextPaint = new Paint();
mTextPaint.setColor(android.R.color.black);
mTextPaint.setTextSize(12);
mTextPaint.setTextAlign(Paint.Align.LEFT);}
I ran your code, and immediately got a Lint error. In init() you are setting your mTextPaint to android.R.color.black. Because it's a static value, I could immediately see that the actual int value of that variable is 0x0106000c, which is almost completely transparent. You should use getResources().getColor(android.R.color.black) or plain ol' Color.BLACK.
Note that a textSize of 12 is very, very small. This code shows 12 (albeit very small).
public class MyImageView extends ImageView {
public MyImageView(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
init();
}
public MyImageView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
public MyImageView(Context context) {
super(context);
init();
}
Paint mTextPaint;
private void init() {
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(12);
mTextPaint.setTextAlign(Paint.Align.LEFT);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int imgWidth = getMeasuredWidth();
int imgHeight = getMeasuredHeight();
float txtWidth = mTextPaint.measureText("your text");
int x = Math.round(imgWidth/2 - txtWidth/2);
int y = imgHeight/2 - 6;
canvas.drawText("12", x, y, mTextPaint);
}
}
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">
<com.example.mytest.MyImageView
android:layout_width="100dp"
android:layout_height="100dp"/>
</RelativeLayout>
Copy/paste, if problem persist, start logging. Again, this code works, I see 12 on my screen.
You should be able to accomplish the desire effect without creating your own class. Just set the background of a TextView with an image drawable. See my example with a text in a speech bubble.
<TextView
android:id="#+id/textOverImage"
android:background="#drawable/speech_bubble"
android:text="#string/hello_world"
android:gravity="center"
android:layout_width="..."
android:layout_height="..."
/>

Categories

Resources