Android. Animation on gravity change - android

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);
});

Related

Android: positioning of Floating Action Button unpredictable

Some of my floating action buttons don't remain where I want, and I cannot understand why.
The first is how they should be (and actually sometimes it works), the other two images show how they behave sometimes... and I cannot find a "pattern" in this behavior.
This is the layout (only one half):
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/lay_attivita_edit_ubicazioni"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="#dimen/list_padding_lateral"
android:paddingRight="#dimen/list_padding_lateral">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:id="#+id/container_attivita_edit_origini">
<TextView
style="#style/FieldLabel"
android:layout_marginTop="20dp"
android:text="#string/attivita_edit_origini" />
<ListView
style="#style/ListView"
android:id="#+id/list_attivita_edit_origini"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:background="#drawable/border_rectangle" />
</LinearLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
style="#style/FloatingActionButton.Small"
android:id="#+id/fab_attivita_edit_ubicazioni_edit_origini"
app:layout_anchor="#id/list_attivita_edit_origini"
app:layout_anchorGravity="top|right|end" />
</android.support.design.widget.CoordinatorLayout>
I tried also to se anchor and anchorGravity programmatically but the result is the same. It could happen because depending on some logic one of the two sections could not be visible, in case I make them invisible at the end of OnCreateView.
It doesn't depend on the visibility of the "anchor list" because the fab move even if I always leave both the lists visible.
I tried also to change programmatically anchor and anchorId of the fab at every change of visibility of them or of their lists, nothing.
CoordinatorLayout.LayoutParams editOrigineFabParams = (CoordinatorLayout.LayoutParams)editOrigineFab.LayoutParameters;
editOrigineFabParams.AnchorId = Resource.Id.list_attivita_edit_origini;
editOrigineFabParams.AnchorGravity = (int)(GravityFlags.Top | GravityFlags.Right | GravityFlags.End);
editOrigineFab.LayoutParameters = editOrigineFabParams;
With the same conditions/code sometimes they work and sometimes they don't. It looks like a bug in Android. I tried with Android 7.0 and 7.1, Xamarin.Android.Support.Compat.25.3.1.
Anyone who had a similar problem or who has an idea of what could be the reason?
Use FAB by james montemagno.
Add FAB by james montemagno from nuget to your project.
https://www.nuget.org/packages/Refractored.FloatingActionButton/
<Refractored.Fab.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="#drawable/ic_action_content_new"
app:app_colorNormal="#color/primary"
app:app_colorPressed="#color/primary_pressed"
app:app_colorRipple="#color/ripple" />
use layout_gravity for positioning .
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:src="#drawable/ic_edit"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp" / >

Create masked square programmatically

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.

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);

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.

Strange behaviour when trying to restrict a view in RelativeLayout

I am trying to add a dynamic Bounding box to my camera layout,I have the following xml code in which I am trying to keep the bounding box from reaching the ShutterButton,I find that the box goes underneath the ShutterButton,I think it is because overlapping of views is allowed in RelativeLayout...
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
android:layout_alignParentTop="true"
android:layout_above="#+id/btn_capture"
/>
<com.example.mycameraapp.RectangleView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/btn_capture"
android:id="#+id/bound_box"
/>
<com.example.mycameraapp.ShutterButton android:id="#id/btn_capture"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
I would like it to not work in the region where ShutterButton specifically is,such that the ShutterButton remains the top Z element followed by the RectangleView on top of the CameraPreview which is simply a SurfaceView
Your btn_capture was not created before you referenced it. Whenever you assign ids use #+id and whenever you refer ids use #id for avoiding errors
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.mycameraapp.ShutterButton android:id="#+id/btn_capture"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
android:layout_alignParentTop="true"
android:layout_above="#id/btn_capture"
/>
<com.example.mycameraapp.RectangleView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/btn_capture"
android:id="#+id/bound_box"
/>
Adding the RectangleView in my Java code as a child of the FrameLayout helped.Now,it draws itself behind the ShutterButton and allows me to click the Button even if it is drawn behind the ShutterButton.
mPreview=new CameraPreview(this,mCamera);
mBox=new RectangleView(this);
container.addView(mPreview);
container.addView(mBox);
In onPause,container.removeAllViews(); ensures that the RectangleView is removed as well

Categories

Resources