Shared element transition image jumps down on exit transition - android

I've been searching everywhere for a cause of this problem and applied most of the solutions that I've found online but I've had no luck.
Here's the situation, I have two activities, one with a viewpager with a recyclerview inside each tab. When I click one of the items from the recyclerview it will open a modal activity that has the target transition image inside a fragment.
So the image will expand from the recyclerview item to the activity modal image
So something like this: Activity1/ViewPager/RecyclerView/Item/Image -> Activity2/Fragment/Image
It works beautifully from Activity1 to Activity2 but when the exit animation occurs the image jumps down, like half the image and lands in Activity one half an image down so it looks really clunky.
Here there are some code snippets:
recyclerview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/product_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical">
<RelativeLayout
android:background="#drawable/bordered_image"
android:padding="2dp"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/product_image"
android:layout_width="match_parent"
android:layout_height="140dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/default_item" />
</RelativeLayout>
<TextView
android:id="#+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:textColor="#color/black"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="16sp" />
</LinearLayout>
I open the activity like this:
val options = ActivityOptions
.makeSceneTransitionAnimation(this, sharedImage, sharedImage.transitionName)
startActivity(intent, options.toBundle())
This is how I handle the modal activity
requestWindowFeature(Window.FEATURE_NO_TITLE)
window.setBackgroundDrawableResource(R.drawable.rounded_dialog)
window.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
And inside the onCreateView of the fragment I add this
image.transitionName = "image_${mItem.id}"
image.loadUrl(mItem.image)
startPostponedEnterTransition()
And I use glide for showing the image like this
private fun ImageView.loadUrl(url: String) {
val options = RequestOptions()
Glide.with(context)
.load(url)
.apply(
options.transforms(
CenterCrop(),
RoundedCorners(150)
)
)
.into(this)
}
This is how the image returns to the activity 1:
EDIT: So I've found the problem. I use a custom style for the activity dialog. In the android manifest I add this to the activity:
<activity android:name=".activities.Activity2"
android:theme="#style/AppTheme.ActivityDialog"/>
And the style is this:
<style name="AppTheme.ActivityDialog" parent="Theme.AppCompat.DayNight.Dialog">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowContentTransitions">true</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowBackground">#color/white</item>
</style>
This is somehow breaking the animation

So I found what the problem was:
An activity transition works like this. When you start your second activity, it is >displayed on top of your first one with a transparent background. The shared elements are >positioned the same way they are on the first activity and then animated to the correct >position specified on the second activity.
In your case you are using android:theme="#style/Theme.AppCompat.Dialog" which mean the >size of the second activity's drawing area is smaller than the one from the first >activity. This explains the clipping and the no transition when clicking outside.
I changed the theme of the Activity2 to this:
<style name="AppTheme.ActivityDialog" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
And added a cardview to the activity 2 layout and it works now

Related

Change the default color of main activity when it starts, The starting and opening default color

When user opens any application by clicking on app icon, the app starts with mainactivity.java. and its xml layout is shown to user.
I am making a splash screen with simple background color and text. But what my problem is, when it starts it shows a default layout color for a very little fraction of time and then it draws my given color. I do not want default color to be there even for that small fraction of time.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
tools:context="com.example.rushi.demon.MainActivity"
android:background="#color/SplashScreen" >
<RelativeLayout
android:id="#+id/SplashScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/SplashScreen">
<TextView
android:id="#+id/SplashText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:text="#string/splash_name"
android:textColor="#color/SplashText"
android:textSize="40sp"
android:textStyle="bold"/>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
The SplashScreen color is shown after a lag and starting default color is shown for little time, which i do not want. I want to open this activity with my set color only from starting.
Add this to your AppTheme (theme of MainActivity) ..
<item name="android:windowDisablePreview">true</item>
Edit
Go to app -> res -> values -> styles.xml open styles.xml there you do this to the theme you have..
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowDisablePreview">true</item> //add this line
</style>
The best way to achieve this is well described here, By this way Splash Activity will start instantly
Refer this: https://medium.com/#ssaurel/create-a-splash-screen-on-android-the-right-way-93d6fb444857

Screen height depending on theme

I have layout with centered Image View.
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/WHITE">
<ImageView
android:id="#+id/powered_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/powered_by" />
<ImageView
android:id="#+id/splash_logo"
android:src="#drawable/logo"
app:layout_widthPercent="70%"
app:layout_heightPercent="70%"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:visibility="invisible" />
</android.support.percent.PercentRelativeLayout>
Here is theme setting for my activity
<style name="SplashTheme" parent="android:Theme.Holo.Light">
<item name="android:windowBackground">#drawable/splash</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
</style>
When i change parent theme to android:Theme.DeviceDefault.Light, ImageView appears a little bit higher, not in center of the screen. It seems like parent view for my device now starts not from the bottom of the screen, but from the bottom toolbar (i use Nexus 5X with on-screen buttons).
I want to use device default theme for a modern dialog appearance, but i also need to have this image view exactly in center on all devices.
How to do it?
It seems like android:Theme.DeviceDefault.Light is not setting android:windowFullScreen. So you will need to create your own theme with the parent android:Theme.DeviceDefault.Light and change the values for the items you want to change
<style name="TestTheme" parent="android:Theme.DeviceDefault.Light">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
</style>

Android shared element to dialog actvitiy

I've got one activity with an image in a toolbar and an activity that is themed like a dialog with the same image in big. These are the layout files:
my_activity.xml:
...
<com.makeramen.roundedimageview.RoundedImageView
android:id="#+id/my_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:scaleType="centerCrop"
android:src="#drawable/my_drawable"
android:transitionName="#string/my_image_transition"
app:riv_oval="true" />
...
my_dialog_activity.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#id/my_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/my_drawable"
android:tint="#color/accent"
android:transitionName="#string/my_image_transition" />
</LinearLayout>
The dialog activity becomes a dialog by applying this theme in the manifest:
<style name="MyDialogActivity" parent="Theme.AppCompat.Light.Dialog.MinWidth">
<item name="windowNoTitle">true</item>
<item name="android:windowMinWidthMajor">#dimen/abc_dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">#dimen/abc_dialog_min_width_minor</item>
</style>
Both the activity and the dialog look exactly how I want them to look like.
Now I want to implement a shared element animation with these ImageViews: When the user clicks on the first activity's image, it has to grow and move into the middle of the screen so it fits the bigger dialog's image.
So I wrote this code:
Intent intent = new Intent(MyActivity.this, MyDialogActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
MyActivity.this, v, getString(R.string.my_image_transition)
);
startActivityForResult(intent, 999, options.toBundle());
} else {
startActivityForResult(intent, 999);
}
The animation does actually happen, but the moved image is only visible inside of the dialog's area. So you see an image that comes from the dialog's upper left corner, but you don't see it moving from the first activity outside of the dialog.
Here's a HTML version of how it should look like and what it currently looks like: https://jsfiddle.net/wutqdh9d/1/
The Share Element Animation was drawn in the second activity. As you use the Theme.AppCompat.Light.Dialog.MinWidth theme, the second activity's window size is smaller than the drawing area of animation.
Hence, just get rid of using the dialog theme. To change this below:
<style name="MyDialogActivity" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
The second activity layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#id/my_image"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="#drawable/your_icon"
android:transitionName="#string/my_image_transition"/>
Then it will be this effect(http://gph.is/1UzZZzV).
Hope it help.
Reference: https://stackoverflow.com/a/28508306/3171537
<style name="dialog_style_activity">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
Above style is work for me. Reference this style in manifest.xml.

Error when Setting transparent background for Android Activity

I created an Activity (which has and YoutubePlayerView and other image) with transparent background using
following code:
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.9</item>
After compiling, background is Dimmed correctly with DimAmount = 0.9. BUT, my VideoView also dimmed
with same dimAmount.
Full xml for my Activity:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#33000000"
android:orientation="vertical" >
<com.google.android.youtube.player.YouTubePlayerView
android:id="#+id/youtube_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/other_views"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitStart"
android:src="#drawable/ads" />
</LinearLayout>
How Can I fix it.
Thanks!
Put this theme in the activity tag in your project's manifest.
android:theme="#android:style/Theme.Translucent.NoTitleBar"
it will make your activity completely transparent.
Then set the background of the root layout oht that activity in black with some alpha according to your requirement using this.
android:background="#33000000"
Change 33 as per your requirement.
It will dim the background things without effecting other views.
Hop this works for you.

Android - ListView doesn't scroll inside DialogFragment

I am starting developing for Android. I wanted t create my sort of modal alert (like UIAlertView in iOS). I considered using Activity which worked fine. It took some time for me to do it. But later, I found a better solution using DialogFragment. I changed my activity to a dialog fragment and modified all required parts with respect to a fragment. It works fine. Except that the ListView in my fragment doesn't scroll any more! What the problem could be?
Note: It was working already in the Activity solution. There is no scroll view.
Here is the XML:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/modal_list_outter_frame_margin_vertical"
android:layout_marginLeft="#dimen/modal_list_outter_frame_margin_horizontal"
android:layout_marginRight="#dimen/modal_list_outter_frame_margin_horizontal"
android:layout_marginTop="#dimen/modal_list_outter_frame_margin_vertical"
android:background="#drawable/modal_list_outter_frame"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="#dimen/modal_list_padding_bottom" >
<TextView
android:id="#+id/title_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/modal_list_title_horizontal_margin"
android:layout_marginRight="#dimen/modal_list_title_horizontal_margin"
android:layout_marginTop="#dimen/modal_list_title_top_margin"
android:gravity="center"
android:maxLines="#integer/modal_list_title_number_of_lines"
android:shadowColor="#color/modal_list_text_shadow_color"
android:shadowDx="0"
android:shadowDy="#integer/modal_list_title_shadow_offset_y"
android:shadowRadius="#integer/modal_list_title_shadow_radius"
android:text="#string/modal_list_title_small"
android:textColor="#color/modal_list_text_color"
android:textSize="#dimen/modal_list_title_font_size"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/modal_list_inner_frame_margin_bottom"
android:layout_marginLeft="#dimen/modal_list_inner_frame_margin_horizontal"
android:layout_marginRight="#dimen/modal_list_inner_frame_margin_horizontal"
android:layout_marginTop="#dimen/modal_list_inner_frame_margin_top"
android:background="#drawable/modal_list_inner_frame"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="#dimen/modal_list_padding_bottom" >
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/modal_list_list_view_margin_horizontal"
android:layout_marginRight="#dimen/modal_list_list_view_margin_horizontal"
android:layout_marginTop="#dimen/modal_list_list_view_margin_top"
android:divider="#null"
android:dividerHeight="0dp"
android:listSelector="#color/modal_list_selector_color_selected"
>
</ListView>
</LinearLayout>
</LinearLayout>
Update: I found something really strange! It's like the fragment is transparent! If I tap anything in the fragment, it seems like I am tapping the buttons below it! Here is the code I am using to show the fragment:
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.addToBackStack("SingleSelectionCustomRowModalList");
modalList = ASModalList.newInstance(modalListStateForCustomRow) ;
modalList.show(ft, "SingleSelectionCustomRowModalList");
Update 2: It seems the problem is the DialogFragment is not modal. I am using this style:
int style = DialogFragment.STYLE_NO_TITLE | DialogFragment.STYLE_NO_FRAME;
setStyle(style, R.style.ASModaListDialogStyle);
The used theme is:
<style name="ASModaListDialogStyle" parent="#android:style/Theme.Dialog">
<item name="android:windowBackground">#drawable/modal_list_background_view</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowTitleStyle">#null</item>
<item name="android:colorBackgroundCacheHint">#null</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:gravity">center</item>
</style>
I am using this theme to make the background of the dialog dimmed.
Old question without an answer that actually worked for me.
Hope it'll help someone.
The solution is to set the list height to 0dp, and add a weight field. And remove the inner LinearLayout. This way the outer LinearLayout can set the correct size to the list, and it will scroll.
<android.support.v7.widget.ListViewCompat
android:id="#+id/ev_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"/>
Please provide some code, otherwise it will be difficult to say what is wrong. For example the Layout XML or your DialogFragment Class.
It ends up with the dialog being non modal. Fixed it using:
int style = DialogFragment.STYLE_NORMAL | DialogFragment.STYLE_NO_FRAME;
setStyle(style, R.style.ASModaListDialogStyle);

Categories

Resources