I always used Activity enter/return transitions (using xml transitions like slide and fade to animate views) and always worked because it's very straightforward. Now in my last project I was having problems even with dummy activites (without any real processing), the transitions simply don't work, so after hours of changing layout code, I figured out that the responsible is the android:background in root FrameLayout of Activity Layout where I set some background color. When I removed this attribute, the transitions came back to work. Also, if I apply this attribute only in activity theme, the transitions stop again.
Currently my project is only animating the second activity that only has this layout structure:
<FrameLayout 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:background="#color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView>
<RecyclerView>
</FrameLayout>
And the transition does slide in ImageView from top and slide in RecyclerView from bottom. But like I've said. It only works if the root FrameLayout don't have a background color.
Do you have any idea if it's a bug or anything else?
EDIT: If I use an ugly dummy view just to provide background color, the transitions work:
<FrameLayout 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">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary" />
<ImageView>
<RecyclerView>
</FrameLayout>
EDIT 2: Same problem happens if I use another root ViewGroup like LinearLayout instead FrameLayout.
I've found a solution (or workaround) using a friend tip:
if I use this attribute in root FrameLayout, the transition works:
android:transitionGroup="false"
Related
I have a problem with SlidingUpPanelLayout. My view is build like that:
<com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:sothree="http://schemas.android.com/apk/res-auto"
android:id="#+id/list_sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top"
sothree:umanoDragView="#+id/dragView"
sothree:umanoOverlay="true"
sothree:umanoPanelHeight="#dimen/filtering_list_closed_height"
sothree:umanoShadowHeight="#dimen/app_bar_elevation">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
// some views
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<FrameLayout
android:id="#+id/list_filtering_fragment_container"
android:name="com.example.test.scenes.list.filtering.FilteringFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.sothree.slidinguppanel.SlidingUpPanelLayout>
and it was working until I've added new feature where I have to set list_filtering_fragment_container visibility to GONE. Everything works fine when I switch visibility status but it's not working when I move to another fragment and come back to previous one.
EDIT
It looks like:
Normal state that I want to achieve after set visibility to VISIBLE
State that I have after set visibility to VISIBLE (after changing fragments)
also I can see in layout inspector that location on Screen and height of this element is different for both cases.
I tried to use slidingUpPanel.setPanelState(PanelState.HIDDEN) but it for some reason doesn't work in 100% cases. It look like view goes outside screen and doesn't come back to it's proper position. And question is why it behaves like that?
I have a layout that transitions between 2 Scenes.
layout.xml
<FrameLayout
android:id="#+id/framelayout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
// Some background views.
<FrameLayout
android:id="#+id/scene_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/scene_a" />
</FrameLayout>
</FrameLayout>
res/layouts/scene_a.xml
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
// Child views removed for brevity
</android.support.constraint.ConstraintLayout>
Scene B layout is identical.
In the activity, ViewCompat.setOnApplyWindowInsetsListener(frameLayout, (v, insets) -> insets); is called to use fitsSystemWindows with FrameLayout.
The views are correct on initial view inflation i.e views are drawn under the status bar, but content is pushed down by the window insets to avoid the status bar.
However, when I transition to Scene B, that padding provided by fitsSystemWindows is lost and the content jumps up. Scene A loses the padding too, when returning.
Any assistance greatly appreciated with how to keep this padding through the transitions.
OK, so had nothing to do with Scene Transitions and everything to do with android:fitsSystemWindows.
The default behaviour for any view that uses android:fitsSystemWindows is to consume the window insets it gets passed. The insets get passed down depth first - see this blog.
So in my example above, the first scene - which has set android:fitsSystemWindows consumes the insets, so scene B does not get a chance. Similarly when I transition back to scene A (they have already been consumed).
The fix in my example was to remove the android:fitsSystemWindows from both scenes and place it in the scene root instead.
I'm using android:windowSoftInputMode="adjustPan" in my manifest.xml.
It's doing me the job just fine but there is something retarded about it.
when i focus an EditText view that's, say in the bottom half of the screen, the title bar is also scrolled with the content of the activity.
image here
all i want is to freeze/float the title bar in place when scrolling the content. just like this:
image here
and no, I don't want to use adjustResize It overlaps views on top of each other
any help is greatly appreciated, been looking for the answer for a long time.
Found it!
Simply changing the root view in the layout xml file to a ScrollView does the job.
I don't even need to specify android:windowSoftInputMode
Of course I have to have everything else in a single layout as the child of the ScrollView
Edit
your .xml file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
... >
<LinearLayout> // could be any other layout but linear works well here
//insert all other views of the activity here
</LinearLayout>
</ScrollView>
The answer suggested by Ace is essentially what is needed. My answer just aims to make things a little clearer.
There are two things you need to do. Firstly in the Manifest set the following on the activity. android:windowSoftInputMode="adjustResize"
Then, in the activity's layout you'll want to set a ScrollView beneath the Toolbar/Title Bar, as shown in the code below.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
.../>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
...>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
From what I understand, here's how it works.
When you open the soft keyboard on your device, it will 'adjustResize' the layout of the activity. As the layout sits in a ScrollView, this is the part which is resized, and made smaller. Therefore the Toolbar/Titlebar will stay in place and the layout in the ScrollView will be scrollable when the keyboard is shown.
I have a main layout being hosted by an activity (setContentView method).
I have a button in the layout. I want to be able to click this button and a new layout will slide down from the left/top until the middle of the screen. So, the screen now will have two layouts where one is on top and another one is just beneath it.
This is something like the UI in Android Jelly Bean where you can pull the settings layout down using a touch gesture.
What are the possible implementations?
A method I have tried:
add the slide down layout into main.xml but set its visibility to gone
when button is clicked, run some code that will set the layout visibility to
VISIBLE and add some animations.
the result of this implementation is that this layout will push the rest of the
views down in order to have a "squeeze" space for itself which is not
what I intended to do (see above)
<?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:orientation="vertical"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
<LinearLayout
android:id="#+id/PR_slidedown" <---this is the intended slidedown layout
android:layout_width="8dp"
android:layout_height="40dp"
android:visibility="gone"
android:orientation="vertical" >
</LinearLayout>
....
Your implementation is partially correct, the other part is to host your two layouts in a FrameLayout so they can overlap with each other. Search for FrameLayout in here, there are a lot of example on how to use it.
Or try the SlidingDrawer
I would like to achieve a popup/overlay screen like Places (i`m more interested how can i place that screen for example in the right/left side of the screen ) in the android maps application (image below). I can create an activity and use the Dialog theme, this mostly resolve my problem, but it placed center in the screen. Somebody have any better idea how i can create a popup/overlay screen like the places in a non-map application and place to top/right of the screen ?. My guess they did it with map overlays.
well, here's what I did... I used a FrameLayout to overlay a LinearLayout where I can fill it with a View. Here's an excerpt of my code:
XML:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<fragment class="com.some.location.to.fragment"
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="#+id/overlay_pane"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="#color/transparent">
</LinearLayout>
</FrameLayout>
Then in my code on some button, I would just add a View (in your case it can just be the dialog's contents) to the overlay_pane LinearLayout.
Java example:
ViewGroup container = findViewById(R.id.overlay_pane);
container.setVisibility(View.VISIBLE);
container.addView(some_view_you_inflated);
But this inflated view would have the following background: #drawable/dialog_full_holo_light for a nice border effect like the Honeycomb style.
You can find the background drawable in your SDK in the following folder
your_SDK_dir/platforms/android-12/data/res/drawable-hdpi/dialog_full_holo_light.9.png
So just copy that into your drawables.
Note: that you can also use the dialog_full_holo_dark or any custom background for the same effect.
I hope that helps :) Let me know if I was unclear at any point
Note: Instead of using a fragment, you could merely use a LinearLayout with match_parent for both layout_width and layout_height. And then you would fill that LinearLayout with the "background" UI (in the question's example.. that would be the map)