Create masked square programmatically - android

I developed an iOS app and now working on the Android version.
I want to create the overlay view above the camera view (SurfaceView). The part which i cant replicate currently is the masked square overlay in the middle of the screen. I tried the android.support.percent.PercentFrameLayout but it doesn't work as what i want.
For iOS version, I simply create 8 rectangular UIViews to form that shape. Then layout them by setting their CGRect.
But for Android, I know I can create them runtime using code. But the part I dont know is how to layout them.
Would like to have some advises, like which way should i go?(XML, or programmatically render).
Thanks a lot!
]
Layout file
<FrameLayout 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"
tools:context="com.nerfire.hk.flexibill.ScanMain">
<!-- TODO: Update blank fragment layout -->
<SurfaceView
android:id="#+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!--<android.support.percent.PercentFrameLayout-->
<!--android:orientation="vertical"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent">-->
<!--<View-->
<!--android:layout_width="match_parent"-->
<!--app:layout_heightPercent="68%"-->
<!--/>-->
<!--</android.support.percent.PercentFrameLayout>-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="10dp"
android:text="Scan and Pay!"/>
</FrameLayout>

Right inside the onCreateView (using Fragment)
Here are the code, without refining the code, putting them in a for-loop
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
FrameLayout viewLayout = (FrameLayout) view.findViewById(R.id.scan_main_frame_layout);
int overlayColor = Color.argb(127, 255, 255, 255);
int lineWidth = 20;
int lineLength = (int)(metrics.widthPixels*0.2);
float originX = (float) (metrics.widthPixels*0.25);
float endPointX = (float) (metrics.widthPixels*0.75);
float screenCentreY = (float)(metrics.heightPixels*0.5);
FrameLayout.LayoutParams horizontalLineFrame = new FrameLayout.LayoutParams(lineLength, lineWidth);
FrameLayout.LayoutParams verticalLineFrame = new FrameLayout.LayoutParams(lineWidth, lineLength-lineWidth);
View view1 = new View(getContext());
view1.setX(originX);
view1.setY(screenCentreY-originX);
view1.setBackgroundColor(overlayColor);
view1.setLayoutParams(horizontalLineFrame);
viewLayout.addView(view1);
View view2 = new View(getContext());
view2.setX(endPointX-lineLength);
view2.setY(screenCentreY-originX);
view2.setBackgroundColor(overlayColor);
view2.setLayoutParams(horizontalLineFrame);
viewLayout.addView(view2);
View view3 = new View(getContext());
view3.setX(originX);
view3.setY(screenCentreY+originX-lineWidth);
view3.setBackgroundColor(overlayColor);
view3.setLayoutParams(horizontalLineFrame);
viewLayout.addView(view3);
View view4 = new View(getContext());
view4.setX(endPointX-lineLength);
view4.setY(screenCentreY+originX-lineWidth);
view4.setBackgroundColor(overlayColor);
view4.setLayoutParams(horizontalLineFrame);
viewLayout.addView(view4);
View view5 = new View(getContext());
view5.setX(originX);
view5.setY(screenCentreY-originX+lineWidth);
view5.setBackgroundColor(overlayColor);
view5.setLayoutParams(verticalLineFrame);
viewLayout.addView(view5);
View view6 = new View(getContext());
view6.setX(endPointX-lineWidth);
view6.setY(screenCentreY-originX+lineWidth);
view6.setBackgroundColor(overlayColor);
view6.setLayoutParams(verticalLineFrame);
viewLayout.addView(view6);
View view7 = new View(getContext());
view7.setX(originX);
view7.setY(screenCentreY+originX-lineLength);
view7.setBackgroundColor(overlayColor);
view7.setLayoutParams(verticalLineFrame);
viewLayout.addView(view7);
View view8 = new View(getContext());
view8.setX(endPointX-lineWidth);
view8.setY(screenCentreY+originX-lineLength);
view8.setBackgroundColor(overlayColor);
view8.setLayoutParams(verticalLineFrame);
viewLayout.addView(view8);
Screenshot
ps: thanks for those who randomly left down votes without comment, without suggesting any solution or reading the question. Thanks mate:) nice android community.

Try this solution.
<?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"
tools:context="com.app.mynewproject.MainActivity">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/surfaceView" />
<ImageView
android:layout_height="250dp"
app:srcCompat="#android:drawable/ic_menu_mylocation"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/imageView"
android:layout_width="250dp" />
<TextView
android:text="SCAN AND PAY!"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:textSize="25sp"
android:textColor="#android:color/white"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:id="#+id/textView" />
</RelativeLayout>
This is working as required.

You can simply put a TextView whose property set to "android:layout_alignParentBottom="true" containg text Scan And Pay! in RelativeLayout which is also parent layout for SurfaceView.
<?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">
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:textColor="#android:color/white"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="SCAN AND PAY!"
android:layout_height="wrap_content" />
</RelativeLayout>
Or Use FrameLayout if no other views relative to other are present:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:textColor="#android:color/white"
android:layout_width="wrap_content"
android:layout_gravity="bottom |center_horizontal"
android:text="SCAN AND PAY!"
android:layout_height="wrap_content" />
</FrameLayout>

FrameLayout is pretty basic container so if you need some more advanced features like positioning you should root FrameLayout with RelativeLayout, then in place of your (commented out) android.support.percent.PercentFrameLayout element put ordinary ImageView showing your masking sqare. To center that ImageView ensure you got these set for it:
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
that should suffice.

Related

Android. Animation on gravity change

I have a FrameLayout within another one. It is aligned to the center.
No I want to align it to top by changing it gravity, but I also want to animate this change.
I already found this answer here https://stackoverflow.com/a/33192335/408780, but LayoutTransition.CHANGING using there needs API 16.
Our app's however minSdk is 14. Any suggestions how to animate gravity change?
Thank you in advance
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/bg"
android:scaleType="centerCrop"/>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:animateLayoutChanges="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/container_bg"/>
<EditText
android:layout_gravity="center_vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
</FrameLayout>
</FrameLayout>
Add
compile 'com.android.support:transition:25.2.0'
to your app dependencies.
Then, add this line before change gravity (TransitionManager from android.support.transition package)
TransitionManager.beginDelayedTransition(parentOfAnimatedView);
For example
mContainer.setOnClickListener(v -> {
TransitionManager.beginDelayedTransition((ViewGroup) mContainer.getParent());
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mContainer.getLayoutParams();
layoutParams.gravity = Gravity.TOP;
mContainer.setLayoutParams(layoutParams);
});

Increase the height of recyclerview dynamically on item add

Display pic
In my app, i want to increase the height of recycler view dynamically. As i add new item under complaints, the height of recycler view should increase. Is there a way to do it? Please help me with this. Thanks in advance.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/complaint_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_line"
android:padding="#dimen/layout_margin"
android:text="Complaints"
android:textColor="#color/textColorFullBlack" />
<LinearLayout
android:id="#+id/complaints_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="#dimen/layout_margin"
android:layout_weight="1">
<android.support.v7.widget.RecyclerView
android:id="#+id/complaint_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/layout_margin"
android:divider="#color/toolBarBackground"
android:groupIndicator="#android:color/transparent" />
</LinearLayout>
<TextView
android:id="#+id/instructions_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_line"
android:padding="#dimen/layout_margin"
android:text="Instructions"
android:textColor="#color/textColorFullBlack" />
<FrameLayout
android:id="#+id/instructions_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="#dimen/layout_margin"
android:layout_weight="1">
<android.support.v7.widget.RecyclerView
android:id="#+id/instructions_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/layout_margin"
android:divider="#color/toolBarBackground"
android:groupIndicator="#android:color/transparent" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/colorPrimary"
android:orientation="horizontal">
<in.palmpower.videocon.uicommon.widget.EditText
android:id="#+id/search_text_field"
style="#style/FormEditText"
android:layout_width="0dp"
android:layout_gravity="center_vertical"
android:layout_margin="#dimen/one_dp"
android:layout_weight="1"
android:background="#android:color/white"
android:inputType="textFilter"
android:padding="#dimen/search_edit_text_padding"
android:privateImeOptions="nm" />
<Button
android:id="#+id/add_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackground"
android:contentDescription="#string/edittext_hint_search"
android:padding="#dimen/button_padding"
android:text="#string/add_button_string"
android:textColor="#color/textColorWhite" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Got stuck on same issue, i was using RecyclerView with wrap_content inside LinearLayout, i change LinearLayout to RelativeLayout and it set RecyclerView Height Based On Children.
This will work for you
RecyclerView mRecyclerView
= (RecyclerView) findViewById(R.id.complaint_recycler_view);
int originalItemSize = iteList.size();
ViewGroup.LayoutParams params = mRecyclerView.getLayoutParams();
if (itemList.size() > originalItemSize ){
params.height = params.height + 100;
originalItemSize = itemList.size();
mRecyclerView.setLayoutParams(params);
}
i suggest you to put teh recyclerview in any other layout (Relative layout is preferable). Then change recyclerview's height/width as match parent to that layout and set teh parent layout's height/width as wrap content. it works for me
WRAP_CONTENT will not work if you want recyclerView to take part of screen.
If you want other content to be there below recyclerView, you can put recyclerView inside LinearLayout and use the following code to change the height dynamically.
I assume you are using a list(complaint_list) for storing complaints.Adjust the complaint_height accordingly
ViewGroup.LayoutParams params = mRecyclerView.getLayoutParams();
int complaint_height=400;
if (complaints_list.size() > 2) {
params.height = ((complaint_list.size() - 1) * 100) + complaint_height;
} else {
params.height = complaint_height+100;
}
mRecyclerView.setLayoutParams(params);

Advertisement to appear above and below the main layout in ListView

I want to display a picture advertisement at the bottom of the display area. I've tried using bottom but it didn't work. Can you help me?
MainActivity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar"
></include>
<LinearLayout
android:id="#+id/adLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"></LinearLayout>
<ListView
android:id="#+id/ilcelerListview"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
Picture link : For Example
I can give your two tip to do that.
You can use RelativeLayout instead of LinearLayout at MainActivity.
For that, you can easy to add a view which you want to add to bottom.
Or
ViewGroup rootView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
LayoutParams params = new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
//you can use params to set in the bottom or other positions
//view is yours
rootView.addView(view, params);

Android: Custom FlowLayout

I want to make this kind of menu of tags in android. Fill layout dynamically and align to center.
How can I do that?
Edited using library recommended by #Dory
<FlowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:f="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
f:debugDraw="false"
f:weightDefault="0"
f:layoutDirection="ltr"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="6dip"
android:paddingTop="6dip"
android:paddingRight="12dip"
android:paddingBottom="12dip"
android:background="#android:color/black"
android:id="#+id/l_flow"/>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="3dp"/>
Flowlayout in one xml file Button is in another xml file. I'm inflating Button then fLayout.addView(button);
what I get is this Padding top and bottom between views is higher than expected
finally I did it with help of this library. I have used only class FlowLayout and attr.xml My main.xml looks like this:
<com.example.FlowTest.FlowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="#android:color/white"/>
and my item layout looks like this:
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp"/>
And in my Activity's onCreate method:
LayoutInflater mInflater = LayoutInflater.from(this);
mFlowLayout = (FlowLayout) findViewById(R.id.flow);
String [] names = {"goods", "shops", "cars", "washing machine","blablabla","clothes","books"};
for(int i = 0; i<names.length;i++){
Button b = (Button)mInflater.inflate(R.layout.item_flow,mFlowLayout, false);
b.setText(names[i]);
mFlowLayout.addView(b);
}
Take a look
here, you can use this library
Edit:
There is attributes provided in the where you can set horizontal and verticalspacing of the Flow Layout. See below sample xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:f="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FlowLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
f:horizontalSpacing="5dp"
f:verticalSpacing="5dp" />
</RelativeLayout>
Happy coding :)

Adding buttons below GraphView, all inside a Fragment

I have been trying to add Button's below a GraphView, and all these elements are part of a Fragment. Tried many approaches but none of them worked properly.
This is the layout file for the Fragment (fragment_graph.xml).
<FrameLayout 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"
tools:context="com.nma.util.sdcardtrac.GraphFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/graph_fragment_layout"
android:orientation="vertical"
/>
</FrameLayout>
And this is the Java code dynamically adding a graph and button, placed in the Fragment's onViewCreated (View view, Bundle savedInstanceState).
storageGraph = new LineGraphView(getActivity(), graphLabel);
storageGraph.addSeries(graphSeries); // More config calls follow
...
LinearLayout view = (LinearLayout)getView().findViewById(R.id.graph_fragment_layout);
Button button = new Button(getActivity());
button.setText("Test");
view.addView(storageGraph);
view.addView(button);
The Button is not visible though I have set orientation to vertical for the LinearLayout containing it.
EDIT - solved!
I found that nesting the graph under its own LinearLayout and the buttons under another LinearLayout, and both of these wrapped in a LinearLayout fixed the problem! The LinearLayout containing the graph must be weighted (I chose a weight of 0.8).
Layout file looks like:
<FrameLayout 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"
tools:context="com.nma.util.sdcardtrac.GraphFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/graph_fragment_wrap"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:id="#+id/graph_fragment_layout"
android:orientation="vertical" />
<LinearLayout
android:id="#+id/graph_buttons"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_navigation_previous_item"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_navigation_next_item"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
I've just tried it and it works. Perhaps your graph is taking all the available space, so added button is below the screen? Try to wrap your LinearLayout into a ScrollView and see if there is a button in the bottom.

Categories

Resources