I have a sub-class of TextView and want to draw a horizontal line by making its height to be 1px. It is ok but i also want to make it center vertically by setting the top margin as half of the height.
However it turns out to be failed.
Any solution to it?
thank you
LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);
int h = getHeight();
lp.setMargins(0, h/2, 0, 0);
You can do it in your xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!.\nA second line test."/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"
android:layout_centerVertical="true"/>
</RelativeLayout>
Regards.
If you come here with some screenshots what you want to do , i can help you easily. But i can suggest you to use FrameLayout :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center"
android:background="#123456" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Horizontal Line" />
</FrameLayout>
There is one guide for FrameLayout here : Frame Layout
And the screenshot :
Without XML you could override onDraw(Canvas canvas) and draw the line in your subclassed TextView like so:
public final class TextViewEx extends TextView
{
private final Paint mPaint = new Paint();
protected final void onDraw(Canvas canvas)
{
super.onDraw(canvas);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(1);
mPaint.setColor(Color.GRAY);
float y = getHeight() / 2f;
canvas.drawLine(0, y, getWidth(), y, mPaint);
}
}
Related
I have multiple instances of a custom view where I'm trying to draw custom shapes using the center values from the view. The problem is that I've been unsuccessful when trying to get the center and drawing shapes on it, here is the result from the code below, you can see that the black squares are not properly centered in each one of the 4 squares:
class MyCustomView
constructor(context: Context,
attrs: AttributeSet? = null
) : View(context, attrs) {
private var center = PointF(0f, 0f)
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
center.set(w / 2f, h / 2f)
}
override fun onDraw(canvas: Canvas) {
val squareDimension = 100F
val halfDimension = squareDimension / 2
if (center.x == 0F || center.y == 0F) {
center = PointF(width / 2F, height / 2F)
}
val paint = Paint()
paint.color = Color.rgb(
0,
0,
0)
canvas.drawRect(
center.x - halfDimension,
center.y - halfDimension,
center.x + halfDimension,
center.y + halfDimension,
paint)
}
}
Android my layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="#+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/second"
app:layout_constraintBottom_toTopOf="#id/third"
android:background="#color/colorPrimary">
<MyCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/second"
android:background="#color/colorAccent">
<MyCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/third"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/fourth"
app:layout_constraintTop_toBottomOf="#id/first"
android:background="#color/colorAccent">
<MyCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/fourth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/third"
app:layout_constraintTop_toBottomOf="#id/second"
android:background="#color/colorPrimary"
>
<MyCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
How can I draw the shape properly in the center of each view?
If you look at your views, MyCustomView and its parent are set to wrap_content. It is also the LinearLayouts whose bounds you see in the screen. If you inspect your views, it's likely that MyCustomViews are not actually where you expect.
Your options:
Make LinearLayout widths and heights 0dp (though from the constraints this isn't required) and make MyCustomView widths and heights match_parent.
Remove LinearLayouts altogether and replace them with MyCustomView. The parent is currently redundant, though you may have a use for it later on.
In terms of your class, things look good, though I would have a single pointf only (val), create the paint globally and not on each draw, and avoid mutating the point during onDraw. You can optionally compute a RectF during onSizeChanged and avoid any further computation during onDraw
I have been looking SO how to make an Image button circular and inside the circle, an image will be shown. But I could not find any helpful sources. I have only 24 hours and my client will check it.
My aim is to create Image Button(black colored circle, see the picture below and an image can be displayed inside it). See image below:
Here is my XML part...the ImageButton is between two comment lines
<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:background="#drawable/backg"
android:orientation="vertical"
android:weightSum="10"
tools:context="sudhirpradhan.example.com.clientpptapp.mainIconFragment">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="0dp"
android:layout_weight="5" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="4.5">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<!--here is my imageButton need to be look like a circle and within that circle ,a picture will be shown .............. -->
<ImageButton
android:id="#+id/imageButton"
android:layout_width="0dp"
android:padding="10dp"
android:scaleType="fitCenter"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="3"
android:background="#drawable/roundbutton"
android:src="#drawable/frontbutton" />
<!-- ..........................................................-->
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="0dp"
android:layout_weight="0.5" />
</LinearLayout>
here is #drawable/roundbutton xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:startColor="#50d050"
android:endColor="#008000"
android:angle="270"/>
<stroke android:width="5px"
android:color="#000000"/>
</shape>
How can I implement that..any suggestion and thank you.
NEW EDITION
As per your comments I got a better idea of what you needed so I'll provide here (re-edited) the solution I have for you.
First I extended an ImageView like this:
public class CircleImageView extends AppCompatImageView {
private int borderColor;
private float borderWidth;
public CircleImageView(Context context) {
super(context);
}
public CircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(attrs);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttributes(attrs);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
if(b == null || b.isRecycled())
return;
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
int imgRadius = w - 2 * (int)this.borderWidth;
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(this.borderColor);
canvas.drawCircle(this.getWidth() / 2,
this.getHeight() / 2,
this.getWidth() / 2, paint);
Bitmap roundBitmap = getRoundedCroppedBitmap(bitmap, imgRadius);
canvas.drawBitmap(roundBitmap, this.borderWidth, this.borderWidth, null);
}
public static Bitmap getRoundedCroppedBitmap(Bitmap bitmap, int radius) {
Bitmap finalBitmap;
if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
false);
else
finalBitmap = bitmap;
Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
finalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
finalBitmap.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(
finalBitmap.getWidth() / 2,
finalBitmap.getHeight() / 2,
finalBitmap.getWidth() / 2,
paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(finalBitmap, rect, rect, paint);
return output;
}
private void parseAttributes(AttributeSet attrs){
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.CircleImageView);
this.borderColor = ta.getColor(R.styleable.CircleImageView_border_color, 0xffffff); // default color white
this.borderWidth = ta.getDimension(R.styleable.CircleImageView_border_width, 1.0f);
}
}
Then we need to set some styleable attributes for borderColor and borderWidth, place it in res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleImageView">
<attr name="border_color" format="color" />
<attr name="border_width" format="dimension" />
</declare-styleable>
</resources>
Then you can just include it in your layout - it will be like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="0dp"
android:layout_weight="5" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="4.5">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<!--here is my imageButton need to be look like a circle and within that circle ,a picture will be shown .............. -->
<com.mucodes.roundbuttonexample.CircleImageView
android:layout_width="200dp"
android:layout_height="200dp"
app:border_color="#ffff0000"
app:border_width="7dp"
android:src="#drawable/random"/>
<!-- ..........................................................-->
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="0dp"
android:layout_weight="0.5" />
</LinearLayout>
You can then use the method setOnClickListener to make the CircleImageView act like a button when clicked.
Here is a video of the result: example of using
Hope now this is what you need.
Sorry, can not comment due to a reputation.
Try to take a look at fancy buttons library.
Here you can set a radius to your button, background color, image and so on.
If you can not use third-party libraries - check library's source code, its pretty simple.
I would like to do this on my android chat
but I can not get my picture fit my bubble.
-I have a LinearLayout, and his background is a bubble 9patch
-within this, I have a imageview, insert the image here
but not how to make this fit the background like we see on screen.
this is how my image is
could give me an idea of how I can do this?
thank.
UPDATE : 28/04/2013
this is my layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rtlImganen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="25dp"
android:gravity="center_vertical" >
<LinearLayout
android:id="#+id/lnyGenImagenMio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="#drawable/bocadilloazulmio"
android:gravity="right"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imgImagenMio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:maxHeight="#dimen/maximagen"
android:maxWidth="#dimen/maximagen"
android:scaleType="centerCrop" />
<ImageView
android:id="#+id/imgPlayMio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/play" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" >
<ImageView
android:id="#+id/imgImagenEnvioRecibidoMio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:src="#drawable/enviadorecibido" />
<TextView
android:id="#+id/txtFechaImagenVideoMio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:textColor="#0000FF"
android:textSize="8sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
yet I still havenĀ“t the solution
this can only be done with a custom view. I had the same problem. Look for Custom ImageView and Paths and clipping Bitmaps. I wrote this snippet to clip a speech bubble shape out of a given bitmap:
public static Bitmap clipit(Bitmap bitmapimg,int direct) {
//1 = direction right
//0 = direction left
Bitmap output = Bitmap.createBitmap(bitmapimg.getWidth(),
bitmapimg.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmapimg.getWidth(),
bitmapimg.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
if(direct == 0) {
canvas.drawRect(0, 0, bitmapimg.getWidth()-15, bitmapimg.getHeight(), paint);
Path path = new Path();
path.moveTo(bitmapimg.getWidth()-15, 10);
path.lineTo(bitmapimg.getWidth(), 20);
path.lineTo(bitmapimg.getWidth()-15, 30);
path.lineTo(bitmapimg.getWidth()-15, 10);
canvas.drawPath(path,paint);
}
if(direct == 1) {
canvas.drawRect(15, 0, bitmapimg.getWidth(), bitmapimg.getHeight(), paint);
Path path = new Path();
path.moveTo(15, 10);
path.lineTo(0, 20);
path.lineTo(15, 30);
path.lineTo(15, 10);
canvas.drawPath(path,paint);
}
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmapimg, rect, rect, paint);
return output;
}
does this solve your problem?
I wrote the following view:
public class EllipseView extends View {
private final Paint paint = new Paint();
public EllipseView(Context context) {
super(context);
paint.setColor(Color.RED);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawOval(new RectF(0, 0, getWidth(), getHeight()), paint);
}
}
How to add it to layout in XML? The following does not work (debugger does not connect):
<?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">
<View class="com.incubation.EllipseView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="200dp"
android:layout_marginTop="200dp"
/>
</RelativeLayout>
ADDON
There were also a problem with communicating with Eclipse and Device, which required restart to fix
Have you tried:
<com.incubation.EllipseView
android...
/>
try
<com.incubation.EllipseView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="200dp"
android:layout_marginTop="200dp"
/>
I have this xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/photo0"
android:id="#+id/imagBackground">
<TextView android:layout_width="20dip" android:layout_height="20dip"
android:layout_marginLeft="250dip" android:layout_marginTop="15dip" android:background="#FFFFFF"
android:id="#+id/index" android:text="0" android:textColor="#000000">
</TextView>
<ImageView android:layout_marginTop="280dip"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#drawable/anim_ctrl_panel" android:id="#+id/change">
</ImageView>
</LinearLayout>
and over this I must draw some rectangular by code. How to do this ?
I tried this :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (LinearLayout) findViewById(R.id.imagBackground);
changeImage = (ImageView) findViewById(R.id.change);
index = (TextView) findViewById(R.id.index);
draw();
}
private void draw() {
System.out.println("desenam");
int width = 50;
int height = 100;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.RED);
canvas.drawRect(25, 50, 75, 150, paint);
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(bitmap);
layout.addView(imageView);
setContentView(layout);
}
but the rectangulars are on the bottom on screen. How to set the location where to put them?
My guess is, the reason why it's in the bottom of the page is because of the LinearLayout: in the end you will have 3 children: TextView, ImageView and ImageView, all below each other.
A few possible solutions:
Add a FrameLayout inside the LinearLayout and add the ImageViews inside it, so the hierarchy would be:
LinearLayout
TextView
FrameLayout
ImageView
ImageView
Use a RelativeLayout instead of the LinearLayout and align all the edges of the second ImageView with the first one
Create a custom ImageView class, for example "com.foo.bar.MyImageView", which of course extends ImageView. Override onDraw:
public void onDraw(Canvas canvas) {
super.onDraw(canvas); // This will render the original image
// ... and here you can have the code to render the rectangle
}
In the xml you replace
<ImageView ...
with
<com.foo.bar.MyImageView ...
I would go for the last solution, since from a performance point of view it's the best.
try this code:
Point left=new Point(x, y);
paint.setColor(Color.parseColor("#00CCFF"));
paint.setStyle(Style.FILL);
canvas.drawCircle(left.x, left.y, 9, paint);
So you have to create a Point using pixels and then draw a rectangle around it otherwise it doesn't know where to draw
Why dont you do this in the layout file itself:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/photo0"
android:id="#+id/imagBackground">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#android:color/darker_gray">
<LinearLayout android:layout_width="fill_parent"
android:layout_margin="5dip"
android:layout_height="fill_parent" android:background="#android:color/black">
<TextView android:layout_width="20dip" android:layout_height="20dip"
android:layout_marginLeft="250dip" android:layout_marginTop="15dip" android:background="#FFFFFF"
android:id="#+id/index" android:text="0" android:textColor="#000000">
</TextView>
<ImageView android:layout_marginTop="280dip"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#drawable/anim_ctrl_panel" android:id="#+id/change">
</ImageView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Try to change your LinearLayout to this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:gravity="top" android:layout_gravity="top"
android:layout_height="fill_parent" android:background="#drawable/photo0"
android:id="#+id/imagBackground">
...