Basically i have an Activity that contains a CameraPreview and i put a RelativeLayout with shape drawable as its background to show rectangle on the middle of the screen.
I wanted to crop the boxed area and i managed to do it by cropping the bitmap like so
val height = dpToPx(300)
val width = dpToPx(187)
var y = srcBmp.height / 2 - (height / 2)
var x = srcBmp.width / 2 - (width / 2)
dstBmp = Bitmap.createBitmap(
srcBmp,
x,
y,
width,
height
)
It worked in most devices, but i don't know why some devices are not respecting the resolution of the DP that i defined, some pictures are bigger than the BOX in some devices.
this is how i convert dp to px
fun dpToPx(dp: Int): Int {
val density = this.resources
.displayMetrics
.density
return Math.round(dp.toFloat() * density)
}
this is my activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
tools:context=".MainActivity">
<com.camerakit.CameraKitView
android:layout_centerInParent="true"
android:id="#+id/camera_view_box1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:keepScreenOn="true"
app:camera_facing="back"
app:camera_focus="continuous"
app:camera_permissions="camera"/>
<RelativeLayout
android:layout_centerInParent="true"
android:background="#drawable/transparent_bg"
android:layout_width="300dp"
android:layout_height="187dp"/>
<RelativeLayout
android:focusable="true"
android:clickable="true"
android:id="#+id/take_picture_box"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp"
android:layout_alignParentBottom="true"
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/circle_bg"/>
</RelativeLayout>
What did i do wrong, and how can i fix it?
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 a GridView, and setting the number of columns and the overal width of the grid layout. Need items with 66dp x 66dp size. But somehow items are squared, but smaller the 66x66. What am I forget?
int zz = .. // number of columns comes from outside
gridview.setNumColumns(zz);
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams)gridview.getLayoutParams();
linearParams.width=66*zz;
gridview.setLayoutParams(linearParams);
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:columnWidth="66dp"
android:gravity="center"
android:horizontalSpacing="0dp"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbars="horizontal"
android:stretchMode="none"
android:verticalSpacing="0dp">
</GridView>
item prototype
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="66dp" android:layout_height="66dp">
<ImageView
android:id="#+id/icon"
android:layout_width="66dp"
android:layout_height="66dp"
android:padding="0dp"
android:background="#android:color/holo_orange_light"/>
</RelativeLayout>
shreen shot
You can Use This..
int width = 66*zz;
view.setLayoutParams(new GridView.LayoutParams(GridView.width, YOUR_HEIGHT));
LinearLayout.LayoutParams require value in pixel not dp
int gridItemWithInDp = 66;
int gridItemWithInPx = (int) (gridItemWithInDp * Resources.getSystem().getDisplayMetrics().density);
linearParams.width=gridItemWithInPx *zz;
gridview.setLayoutParams(linearParams);
You should set the width of gridview in dp either from code or from declared into resource xml
from code:
final float density = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) ((66 * zz) * density + 0.5f);
or from xml
int pixels = getResources().getDimensionPixelSize(R.dimen.example_dimen);
gridview.setNumColumns(zz);
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams)gridview.getLayoutParams();
linearParams.width=pixels;
gridview.setLayoutParams(linearParams);
Set item prototype width and height MATCH_PARENT
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:background="#android:color/holo_orange_light"/>
</RelativeLayout>
I have a problem, I'm trying to resize a ImageView and its parent container but the problem is that the ImageView has ScaleType:"matrix", and I cant`t resize the image or its container
this is my code:
public void resize() {
LayoutParams contet = relativeLayout.getLayoutParams();
LayoutParams photo = image.getLayoutParams();
int widPhoto = image.getWidth();
int hePhoto = image.getHeight();
photo.width = ((widPhoto * 6) / 2);
photo.height = ((hePhoto * 6) / 2);
contenedor.width = widPhoto * 2;
contenedor.height = hePhoto * 2;
relativeLayout.setLayoutParams(contenedor);
image.setLayoutParams(photo );
}
and my xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/containerImg"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="matrix" />
</RelativeLayout>
setLayoutParams() does nothing but remove the property ScaleType if I resize everything correctly, but I cant´t remove that property. Any way to resize? they could put the property ScaleType: NONE? thank you very much and sorry for my bad English
To resize your ImageView, I suggest to use FrameLayout:
<FrameLayout
android:id="#+id/fm_id"
android:layout_width="img_width"
android:layout_height="img_height"
... ...
>
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:layout_gravity="center"
android:gravity="center"
/>
</FrameLayout>
then you just need to resize 'img_width' and 'img_height' in your codes
I got the solution, if you are using the Layout ScaleType: matrix
you need to use matrix.setScale (); for Resizing
I have 3 images and I would like to achieve to have something like my
It is supposed to take the full width of the screen, a height of 100dp (or whatever I will choose).
The images I have are square and big. I want them to have a height of 100dp, keep their aspect ratio (square) and be spaced equally
What I get with this code is 3 images that take 1/3 of the width, not squared with no space in between
I have tried various things (playing with scaleType, ...) but I am stuck (apart from setting the width to 100dp manually for each of them, which I conceptually don't like)
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/img1"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/img2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/img2"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/img3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/img3"/>
</LinearLayout>
</LinearLayout>
I'd do it with code:
int resx = getWindowManager().getDefaultDisplay().getWidth();
int spaceBetweenPics = (resx - 300) / 2; // Two spaces taking resolution - 3 images size
Bitmap [] pics = New Bitmap[3];
for (int i = 0; i < 3; i++) {
pics[i] = BitmapFactory.decodeResource(getResources(), R.drawable.img1 + i);
// With their names, they are contiguous in the drawables index
pics[i] = Bitmap.createScaledBitmap(pics[i], 100, 100, false);
}
In your onDraw method:
for (int i = 0; i < 3; i++)
canvas.drawBitmap(pics[i], (100 * i + spaceBetweenPics * i), 0, null);
I have 6 ImageButton in my activity, I set images through my code in them ( not using xml).
I want them to cover 75% of the button area. But where as some images cover less area, some are too big to fit into the imageButton. How to programatically resize and show them?
Below is the screen shot
below is the xml-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="match_parent"
android:orientation="vertical"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp" >
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<ImageButton
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/button_topleft"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
<ImageButton
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/button_topright"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
</LinearLayout>
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<ImageButton
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/button_repeat"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
<ImageButton
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/button_next"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
</LinearLayout>
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<ImageButton
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/button_bottomleft"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
<ImageButton
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:id="#+id/button_bottomright"
android:layout_marginBottom="5sp"
android:layout_marginLeft="2sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
</LinearLayout>
</LinearLayout>
and a snippet of
myClass.java:
public void addImageButtons()
{
iB_topleft = (ImageButton) findViewById(R.id.button_topleft);
iB_topright = (ImageButton) findViewById(R.id.button_topright);
iB_bottomleft = (ImageButton) findViewById(R.id.button_bottomleft);
iB_bottomright = (ImageButton) findViewById(R.id.button_bottomright);
iB_next = (ImageButton) findViewById(R.id.button_next);
iB_repeat = (ImageButton) findViewById(R.id.button_repeat);
}
public void setImageNextAndRepeat()
{
iB_topleft .setImageResource(R.drawable.aa);
iB_topright.setImageResource(R.drawable.bb);
iB_bottomleft.setImageResource(R.drawable.cc);
iB_bottomright.setImageResource(R.drawable.dd);
iB_next.setImageResource(R.drawable.next);
iB_repeat.setImageResource(R.drawable.repeat);
}
I want them to cover 75% of the button area.
Use android:padding="20dp" (adjust the padding as needed) to control how much the image takes up on the button.
but where as some images cover less area, some are too big to fit into the imageButton. How to programatically resize and show them?
Use a android:scaleType="fitCenter" to have Android scale the images, and android:adjustViewBounds="true" to have them adjust their bounds due to scaling.
All of these attributes can be set in code on each ImageButton at runtime. However, it is much easier to set and preview in xml in my opinion.
Also, do not use sp for anything other than text size, it is scaled depending on the text size preference the user sets, so your sp dimensions will be larger than your intended if the user has a "large" text setting. Use dp instead, as it is not scaled by the user's text size preference.
Here's a snippet of what each button should look like:
<ImageButton
android:id="#+id/button_topleft"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="5dp"
android:layout_marginTop="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="20dp"
android:scaleType="fitCenter" />
I'm using the following code in xml
android:adjustViewBounds="true"
android:scaleType="centerInside"
Try to use android:scaleType="fitXY" in i-Imagebutton xml
I'm using android:scaleType="fitCenter" with satisfaction.
Refer below link and try to find what you really want:
ImageView.ScaleType CENTER Center the image in the view, but perform
no scaling.
ImageView.ScaleType CENTER_CROP Scale the image uniformly (maintain
the image's aspect ratio) so that both dimensions (width and height)
of the image will be equal to or larger than the corresponding
dimension of the view (minus padding).
ImageView.ScaleType CENTER_INSIDE Scale the image uniformly (maintain
the image's aspect ratio) so that both dimensions (width and height)
of the image will be equal to or less than the corresponding dimension
of the view (minus padding).
ImageView.ScaleType FIT_CENTER Scale the image using CENTER.
ImageView.ScaleType FIT_END Scale the image using END.
ImageView.ScaleType FIT_START Scale the image using START.
ImageView.ScaleType FIT_XY Scale the image using FILL.
ImageView.ScaleType MATRIX Scale using the image matrix when drawing.
https://developer.android.com/reference/android/widget/ImageView.ScaleType.html
I recently found out by accident that since you have more control on a ImageView that you can set an onclicklistener for an image
here is a sample of a dynamically created image button
private int id;
private bitmap bmp;
LinearLayout.LayoutParams familyimagelayout = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT );
final ImageView familyimage = new ImageView(this);
familyimage.setBackground(null);
familyimage.setImageBitmap(bmp);
familyimage.setScaleType(ImageView.ScaleType.FIT_START);
familyimage.setAdjustViewBounds(true);
familyimage.setId(id);
familyimage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//what you want to do put here
}
});
You can make your ImageButton widget as I did. In my case, I needed a widget with a fixed icon size.
Let's start from custom attributes:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ImageButtonFixedIconSize">
<attr name="imageButton_icon" format="reference" />
<attr name="imageButton_iconWidth" format="dimension" />
<attr name="imageButton_iconHeight" format="dimension" />
</declare-styleable>
</resources>
Widget class is quite simple (the key point is padding calculations in onLayout method):
class ImageButtonFixedIconSize
#JvmOverloads
constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = android.R.attr.imageButtonStyle
) : ImageButton(context, attrs, defStyleAttr) {
private lateinit var icon: Drawable
#Px
private var iconWidth: Int = 0
#Px
private var iconHeight: Int = 0
init {
scaleType = ScaleType.FIT_XY
attrs?.let { retrieveAttributes(it) }
}
/**
*
*/
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
val width = right - left
val height = bottom - top
val horizontalPadding = if(width > iconWidth) (width - iconWidth) / 2 else 0
val verticalPadding = if(height > iconHeight) (height - iconHeight) / 2 else 0
setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
setImageDrawable(icon)
super.onLayout(changed, left, top, right, bottom)
}
/**
*
*/
private fun retrieveAttributes(attrs: AttributeSet) {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ImageButtonFixedIconSize)
icon = typedArray.getDrawable(R.styleable.ImageButtonFixedIconSize_imageButton_icon)!!
iconWidth = typedArray.getDimension(R.styleable.ImageButtonFixedIconSize_imageButton_iconWidth, 0f).toInt()
iconHeight = typedArray.getDimension(R.styleable.ImageButtonFixedIconSize_imageButton_iconHeight, 0f).toInt()
typedArray.recycle()
}
}
And at last you should use your widget like this:
<com.syleiman.gingermoney.ui.common.controls.ImageButtonFixedIconSize
android:layout_width="90dp"
android:layout_height="63dp"
app:imageButton_icon="#drawable/ic_backspace"
app:imageButton_iconWidth="20dp"
app:imageButton_iconHeight="15dp"
android:id="#+id/backspaceButton"
tools:ignore="ContentDescription"
/>
It worked well in my case. First, you download an image and rename it as iconimage, locates it in the drawable folder. You can change the size by setting android:layout_width or android:layout_height. Finally, we have
<ImageButton
android:id="#+id/answercall"
android:layout_width="120dp"
android:layout_height="80dp"
android:src="#drawable/iconimage"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:scaleType="fitCenter" />