I'm working on Android app with custom camera module. Main purpose of custom camera module is in adding overlay to camera - it should be something like outer transparent border (see first attached pic). It's actually blurred in the attached picture, but I need at least transparent effect as blur is not trivial to implement on Android.
The main point here is to ensure that "clear" visible area is corresponding to A4 format, so height divided by width should be √2 (main purpose of the app is in taking photos of A4 sheets).
I've figured how to achieve "inverted" effect - see second picture. But I can't get my head around on how could setup the view for the desired effect - first picture. Could someone share their thoughts on the problem? Here is the code:
camera.xml:
<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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4">
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:id="#+id/overlay"
android:layout_width="316dp"
android:layout_height="446dp"
android:layout_centerInParent="true"
android:background="#drawable/overlay"
android:duplicateParentState="false" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:background="#android:color/black">
<Button
android:id="#+id/button_capture"
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/capture_button"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<Button
android:id="#+id/button_close"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerVertical="true"
android:layout_marginEnd="50dp"
android:layout_marginRight="50dp"
android:layout_toLeftOf="#+id/button_capture"
android:background="#drawable/close" />
</RelativeLayout>
</LinearLayout>
overlay.xml:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="#+id/listview_background_shape">
<solid android:color="#88ffffff" />
I've found an article about just like what I needed. With little effort I could adjust the code there to get desired effect: https://blog.budiharso.info/2016/01/09/Create-hole-in-android-view/
To avoid tricky vector masks, it's enough to define the id/overlay as layout with 4 semitransparent rectangles, sharing the same drawable you use now: top, bottom, left, and right. You can determine the dimensions of each rectangle at runtime, but if you like intellectual challenges, you can define them as a ConstraintLayout.
Related
I want to make a view in which one image view, say iv_up should be placed above the another image view, say iv_down.
The iv_up should be slighty transparent. One more thing, the iv_down happens to be an QR Code.
Is there any way to implement this?
Below is the code that I have written so far:
<?xml version="1.0" encoding="utf-8"?>
<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:gravity="center">
<ImageView
android:id="#+id/iv_down"
android:layout_width="419dp"
android:layout_height="419dp"
android:layout_centerInParent="true"
android:contentDescription="QR CODE"
tools:srcCompat="#tools:sample/avatars"/>
<ImageView
android:id="#+id/iv_up"
android:layout_width="419dp"
android:layout_height="419dp"
android:layout_centerInParent="true"
android:contentDescription="QR CODE"
tools:srcCompat="#tools:sample/avatars"/>
</RelativeLayout>
So take a look at this sample XML I have created:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_down"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:contentDescription="QR CODE"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#tools:sample/avatars" />
<ImageView
android:id="#+id/iv_up"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:layout_marginStart="50dp"
android:layout_marginTop="50dp"
android:contentDescription="QR CODE"
app:layout_constraintStart_toStartOf="#id/iv_down"
app:layout_constraintTop_toTopOf="#id/iv_down"
tools:srcCompat="#tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
This will create a UI where the iv_up appears on top of the iv_down. Using the ConstraintLayout you can position views relative to one another with ease - it is the "better version" of the RelativeLayout. So here we set the iv_down to be in the top left corner of the view, and iv_up to be 50dp from the top and start of the iv_down view. Since the views are ordered as such in the XML, the iv_up will always sit on top of the iv_down due to its Z positioning. You can change this by setting specific values for the android:translationZ attribute.
Simply setting the android:alpha="0.5" attribute on the iv_up view, will cause the view to be 50% transparent. You can play with this float value from 0-1 to get the desired look for the transparency. Changing the margins on iv_up will also change how far the view moves from the top left corner i.e. how much of the views overlap!
I'm trying to make a rounded shaped surfaceview. I've searched a lot but i couldn't find a good solution. what i'm doing right now is that, I've put the SurfaceView into a FrameLayout, then another View on top of it, either with a PNG mask, or a shape xml drawable. here it is
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#000"
android:orientation="vertical"
android:visibility="visible" >
<FrameLayout
android:id="#+id/videorecordview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight=".2" >
<SurfaceView
android:id="#+id/surfaceView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#drawable/rounded"
android:orientation="vertical" >
</LinearLayout>
</RelativeLayout>
But this is not a good solution and it is also not working perfectly. I want to customize surfaceview to a rounded shape. any help would be much appreciated. Thank you :)
A little hack. Put your surface view inside card view.
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_normal"
app:cardCornerRadius="10dp"
app:cardPreventCornerOverlap="false">
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/margin_normal" />
</android.support.v7.widget.CardView>
Don't forget to add this to your gradle file to use CardView
compile 'com.android.support:cardview-v7:25.0.1'
Also this two line inside card view
app:cardCornerRadius="10dp"
app:cardPreventCornerOverlap="false"
Cheers happy coding
You can't change the shape of the SurfaceView's Surface.
A SurfaceView has two parts, the Surface and the View. The View part works like any other View. By default, it just acts as a transparent "hole", creating a window in the layout. All Views are rendered by the app onto a single layer.
The Surface part is a separate layer that sits behind the View layer (unless you explicitly change the Surface's Z order), so you only see it where it "shows through" transparent areas of the View layer. You can draw on the View layer to mask portions of the Surface, but you can't change the shape of the Surface layer itself. Layers are rectangular.
In many situations a TextureView can be used in place of a SurfaceView. TextureView offers greater flexibility because it's rendered by the app onto the View layer, but can be less efficient than SurfaceView.
More information can be found in the Android graphics architecture doc.
To achieve what you ask, it is very easy to do it.
You only need to use the next XML:
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp">
<SurfaceView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</androidx.cardview.widget.CardView>
And to use this CardView, add this dependency on your build.gradle app:
implementation 'androidx.cardview:cardview:1.0.0'
try this
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient
android:startColor="#FFFF0000"
android:endColor="#80FF00FF"
android:angle="270"/>
</shape>
<SurfaceView
android:background="#drawable/circle"
android:id="#+id/surfaceView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Image of what I want to do
I want to align the center of the smaller red box to the left-edge of the black box. The red box has it's width and height set to wrap_content and there is a text-view inside. The black box takes up half the screen width. It's in a linear-layout with a spacer on the left and right, the spacers have .25 weight while the black-box has .5 weight.
I'd prefer to do this in XML without the use of margins. The red-box may contain 2 characters or 20, the contents come from the server.
There's only "toLeftOf" and "alignLeft". What I want to do is essentially "align center of box to left edge of another box".
Here is a simple implementation of what you want using only XML.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="100dp"
android:layout_height="50dp"
android:id="#+id/imageView"
android:background="#000000"
android:layout_marginLeft="50dp" />
<ImageView
android:layout_width="50dp"
android:layout_height="25dp"
android:id="#+id/imageView2"
android:background="#ff0000"
android:layout_marginTop="-40dp"
android:layout_marginLeft="25dp" />
You can try this xml for your purpose. But what you want center of black box with dynamic content, but it's not recommended, the reason is, if Content too long or too short, it will not look good in UI, because You want to maintain width of red box dynamically as well as center of left edge also. So black box size also you need to change everytime. That is not good. Please try my solution and you can always modify this layout as per your thought process.
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/view_1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:background="#000000" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/view_1"
android:layout_centerVertical="true"
android:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="Hi"
android:textColor="#ffffff" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
Hope it will help you !
Please help I already do like the view like screenshot 2 but having a problem to achieve like screenshot 1.Is it possible to do?
View with rotation with feel the screen.
Thanks in advance.
<?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"
android:background="#color/accent_material_dark"
android:orientation="vertical">
<View
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:background="#FFFFFF" />
<View
android:id="#+id/body"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_below="#id/header"
android:rotation="165"
android:background="#color/accent_material_dark" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/header"
android:layout_alignParentRight="true"
android:src="#drawable/ic_action_search"
android:layout_marginBottom="-32dp"
android:layout_marginRight="20dp">
</android.support.design.widget.FloatingActionButton>
</RelativeLayout>
I should say that what you're trying to accomplish would be best achieved with a background drawable with the shape you want, rather than trying to rotate views to look like this. It's simply a lot of work and views to achieve something that a basic knowledge in microsoft paint would achieve as well.
That being said, to get your desired result, you just need to apply the pivot points of the view you're rotating to the top left corner (0, 0), and rotate only 15 degrees in the opposite direction"
<View
android:id="#+id/body"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_below="#id/header"
android:transformPivotX="0dp"
android:transformPivotY="0dp"
android:rotation="-15"
android:background="#color/accent_material_dark" />
You might also need to make the view a bit longer, since the rotation will mean the view doesn't extend to the edge of the screen (due to pythagorean's theorem). You could do this by applying a large dp value for the view's width, or by setting the view's scaleX property to 1.5, or something similar.
I would like to design a frame using 4 ImageView for each of the top, bottom, left and right side of that frame, as shown in the following example:
Seems simple, but I am really having a hard time doing it. I tried using a FrameLayout along with layout_alignParentLeft|Right|Top|Bottomlike the following:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_masque"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFF"
>
<ImageView
android:id="#+id/camera_top_masque"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_top_masque_photo"
android:layout_alignParentTop="true"
/>
<ImageView
android:id="#+id/camera_left_masque"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/ic_left_masque_photo"
android:layout_alignParentLeft="true"
/>
<ImageView
android:id="#+id/camera_right_masque"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/ic_right_masque_photo"
android:layout_alignParentRight="true"
/>
<ImageView
android:id="#+id/camera_bottom_masque"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_bottom_masque_photo"
android:layout_alignParentBottom="true"
/>
</FrameLayout>
It works well for the top and left sides, but not for the others (like it places the right and bottom sides on the top side...).
I also tried using a RelativeLayout like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_masque"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFF"
>
<ImageView
android:id="#+id/camera_top_masque"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_top_masque_photo"
android:layout_alignParentTop="true"
/>
<ImageView
android:id="#+id/camera_left_masque"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="-2dp"
android:src="#drawable/ic_left_masque_photo"
android:layout_below="#id/camera_top_masque"
/>
<ImageView
android:id="#+id/camera_right_masque"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/ic_right_masque_photo"
android:layout_marginRight="-2dp"
android:layout_below="#id/camera_top_masque"
android:layout_alignParentRight="true"
/>
<ImageView
android:id="#+id/camera_bottom_masque"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_bottom_masque_photo"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
But same thing, does not work as expected.
Any idea what is wrong with my layouts? How could I accomplish this?
Note: Images sizes are: 640*114px (top, bottom) and 34*572 (left, right).
Thanks!
I usually use linearlayout for things like this and control the fill using layout_weight parameters. You will probably find a lot of similar questions here.
Simply create a vertical linear layout and in the middle section create a horizontal linear layout.
This is made a lot simpler if you use the WYSIWYG layout designer in Eclipse ADT ... .see tools.android.com for details
There are a lot of tutorials available for Android layouts which are a more useful resource as Stack Overflow tends to deal with the programming issues rather than layouts.
I will answer my own question in order to highlight the mistakes I have made. Turns out, I was almost there, I only had to add an alignParentTop at both the right and left ImageViews and an alignParentLeftat the bottom ImageView.
I don't understand the logic behind this, though! (if someone could explain...)
If the frame are built by the same images. You can try a 9-patch drawable or a shape with borders and transparent center.