Broken elevation shadow during animation on Android Pie - android

I am experiencing weird shadow behavior, when animation of parent viewGroup is taking place on Android Pie. It is happening on all phones with android 9.0 I have. Except for emulator.
So, the shadow is blinking and kinda offset.
To simulate, I have this simple Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.animated_item).startAnimation(AlphaAnimation(0.9f, 1.0f).apply {
duration = 500
repeatCount = Animation.INFINITE
repeatMode = Animation.REVERSE
})
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:layout_width="120dp"
android:layout_height="200dp"
android:layout_margin="8dp"
android:background="#fff"
android:elevation="6dp" />
</FrameLayout>
<FrameLayout
android:id="#+id/animated_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:layout_width="120dp"
android:layout_height="200dp"
android:layout_margin="8dp"
android:background="#fff"
android:elevation="6dp" />
</FrameLayout>
</LinearLayout>
Result:

Probably, it's too late, but to get rid of this effect I had to apply animation to the View with elevation itself, but not to its parent layout.

Related

Android: WebView inside of appBarLayout unable to scroll

I have an activity which I will show xml for below, containing a webView inside an appBarLayout. Now to be frank, I don't know where the appBarLayout came from because I dont remember adding it in. But anyways, the screen has stacked in the following order top->bottom: a textView, a videoView, and a webView. So the HTML being displayed in the webview is only maybe the bottom half of the screen. Below the xml snippet, I have a image of how this looks from the design POV. The closest I ever got to scrolling is if the webView and friends are NOT children of appBarLayout but then the webview takes up entire screen which is not desirable.
I admit, this probably is setup wrong but I will gladly take whatever advice you have and suggestions on editing the way this is arranged/configured.
Activity XML
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".Lesson">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="true"
android:scrollbars="vertical"
android:theme="#style/Theme.ProjectName.AppBarOverlay"
android:verticalScrollbarPosition="right">
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="64dp"
android:fontFamily="#font/reem_kufi"
android:gravity="center"
android:isScrollContainer="false"
android:linksClickable="true"
android:text="Title Goes Here"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold" />
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<WebView
android:id="#+id/lessonContentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="true"
android:isScrollContainer="true"
android:nestedScrollingEnabled="true"
android:overScrollMode="ifContentScrolls"
android:persistentDrawingCache="scrolling"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_scrollFlags="scroll" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Kotlin File
class Lesson : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityLessonBinding
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLessonBinding.inflate(layoutInflater)
setContentView(binding.root)
webView = findViewById(R.id.lessonContentView)
if(webView != null){
webView.requestFocus()
webView.settings.javaScriptEnabled = true
webView.isSoundEffectsEnabled = true
webView.isVerticalScrollBarEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.allowContentAccess = true
webView.settings.domStorageEnabled = true
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (url != null) {
view?.loadUrl(url)
}
return true
}
}
webView.loadUrl("file:///android_asset/lesson.html")
}
val youTubePlayerView: YouTubePlayerView? = findViewById(R.id.videoView)
if (youTubePlayerView != null) {
lifecycle.addObserver(youTubePlayerView)
}
youTubePlayerView?.addYouTubePlayerListener(object : AbstractYouTubePlayerListener() {
override fun onReady(youTubePlayer: YouTubePlayer) {
val videoId = "yJdkdiAly0w"
youTubePlayer.cueVideo(videoId, 0F)
}
})
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_lesson)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
Component Tree & Design
How it looks now
How it looked when I got it to scroll but not how I wanted
I have already tried the advice given on several posts here on StackOverflow so please do not just mark as Duplicate and run off. Probably a quarter of the code in the project right now is from me trying to get scrolling to work with the advice of this site.
I have tried messing with all the scroll attributes for basically every view on here.
I have added StackOverflow recommended items such as the app:layout_behavior and these webview settings below:
webView.isVerticalScrollBarEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.allowContentAccess = true
When I got it to scroll but wasnt correct, shown in image link earlier, I had removed all the views from the appBarLayout parent making everything a direct child of what this says is a "CoordinatorLayout".
Received help outside of SO (Discord) and I will go over the changes below.
First, I removed the appBarLayout. As originally mentioned, I wasn't even sure about it or how it got there as a parent of everything. I also removed ITS PARENT the coordinatorLayout by changing it to a constraintLayout. This is the parent of my 3 needed pieces (text, video, web) all stacked on top of each other. A few attributes were removed from the xml as well.
Please feel free to comment if you see this in the future and have questions about how I solved this.
<?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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Lesson">
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="#+id/videoView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<TextView
android:id="#+id/textView2"
android:layout_width="412dp"
android:layout_height="54dp"
android:fontFamily="#font/reem_kufi"
android:gravity="center"
android:isScrollContainer="false"
android:linksClickable="true"
android:text="Winds & Temperatures Aloft"
android:textAlignment="center"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<WebView
android:id="#+id/lessonContentView"
android:layout_width="412dp"
android:layout_height="0dp"
android:fadeScrollbars="true"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoView"
app:layout_constraintVertical_bias="0.483"
app:layout_scrollFlags="scroll" />
</androidx.constraintlayout.widget.ConstraintLayout>

AndroidStudio: Explode animation doesn't work when i set background color to the root layout in the xml

I don't know if it is a bug or i am making some mistake but when i set Explode animation when opening an Activity it animates like a Slide animation from top to bottom. I did some trial and error and it turns out that when i use a custom background color in the root layout in the xml file this unexpected behavior occures. When i remove the background color everything works as expected.
Can anyone tell me what's going on here??? Because it is important for me to set background color in the root layout.
Here's a sample of my xml code:
<?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"
android:background="#000000" // This causes the unexpected behavior.
tools:context=".ExplodeActivity">
<ImageView
android:id="#+id/imageView2"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/b" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the ExplodeActivity 's onCreate method where i am assigning the animation:
class ExplodeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
window.requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_explode)
val enterTransition = Explode()
enterTransition.duration = 500
window.enterTransition = enterTransition
}
}
Here's the previous activity's code which responsible for starting the ExplodeActivity:
val options = ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
val intent = Intent(this, ExplodeActivity::class.java)
startActivity(intent, options)

SnackBar showing above a certain height when using Coordinator layout

So I have the coordinate layout as the root layout as I am using a floating Action button.
Here is my xml.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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"
tools:context=".activities.teacher.TeacherJobBoard"
android:id="#+id/rootLayout_job_board"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/anchor"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/color_black_darker_overlay"
android:layout_gravity="bottom"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/all_night_background"
android:orientation="vertical"
tools:context=".activities.teacher.TeacherJobBoard">
<com.hugocastelani.waterfalltoolbar.WaterfallToolbar
android:id="#+id/teacher_job_board_waterfall_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:final_elevation="15dp">
<androidx.appcompat.widget.Toolbar
android:id="#+id/teacher_job_board_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/tutor_bear_dark_blue"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme" />
</com.hugocastelani.waterfalltoolbar.WaterfallToolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/discretescrollview_teacherJobBoard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</LinearLayout>
<com.github.ybq.android.spinkit.SpinKitView
android:id="#+id/spin_kit_job_board"
style="#style/SpinKitView.Large.WanderingCubes"
android:layout_width="#dimen/_80sdp"
android:layout_height="#dimen/_80sdp"
android:layout_gravity="center_horizontal|center_vertical"
app:SpinKit_Color="#color/color_white" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/extended_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:gravity="center"
style="#style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:onClick="expand"
app:iconSize="#dimen/_12sdp"
android:elevation="#dimen/_5sdp"
android:fontFamily="#font/roboto_light"
android:textColor="#color/white"
android:text="Filter"
app:iconPadding="#dimen/_5sdp"
android:layout_marginBottom="#dimen/_10sdp"
android:layout_marginRight="#dimen/_10sdp"
app:backgroundTint="#color/tutor_bear_dark_blue"
app:iconTint="#color/white"
app:icon="#drawable/ic_filter"
/>
<View
android:id="#+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_black_darker_overlay"
android:visibility="gone"
/>
<include layout="#layout/bottom_filter_dialog"
android:id="#+id/filterSheet"
android:visibility="gone"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I have a simple snack bar in my code like this.
Snackbar.make(binding.getRoot(), "This is main activity", Snackbar.LENGTH_LONG)
.setAction("CLOSE", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
}). show();
Problem is when I show the snack bar , it always appears above a certain height from the bottom of the screen. As if there is some kind of a bottom margin set. This only happens when I use coordinate layout.
Snackbar works fine in other layouts.
Picture of the problem is given as a reference.
Give the root view instead, rootLayout_job_board
CoordinatorLayout rootLayout = findViewById(R.id.rootLayout_job_board);
Snackbar.make(rootLayout), "This is main activity", Snackbar.LENGTH_LONG)
.setAction("CLOSE", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
}). show();
If that doesn't work, try giving GRAVITY using LayoutParams
If that doesn't work, also give margins as 0 in LayoutParams.
Also, if your device is Above 9 then you should consider navigation gestures,
snackbar.isGestureInsetBottomIgnored(false);
See here

Why viewBinding makes XML root full screen

I am wondering why adding viewBinding to my app, makes the XML root display in full screen when running the app. The root doesn't display in full screen in the designer view inside Android Studio.
Due to the root displaying in full screen, I had to add android:gravity="center" to vertically align the children in the center. While I don't think this should be a problem, I'm still interested in knowing why this is the case.
I have the following code;
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center_vertical"
android:background="#color/colorAccent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="1"
android:textSize="30sp" />
<Button
android:id="#+id/roll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/roll"/>
</LinearLayout>
package com.example.diceroller
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.diceroller.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.rollButton.text = "testBind"
setContentView(binding.root)
}
}
I am not sure but I think that when You execute this setContentView(binding.root) You are setting a linear layout as fullscreen.
setContentView Android Docs
Set the activity content to an explicit view. This view is placed directly into the activity's view hierarchy. It can itself be a complex view hierarchy. When calling this method, the layout parameters of the specified view are ignored. Both the width and the height of the view are set by default to ViewGroup.LayoutParams#MATCH_PARENT. To use your own layout parameters, invoke setContentView(android.view.View, android.view.ViewGroup.LayoutParams) instead.
To do make it looks like in the preview You can write this code.
XML:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#color/colorAccent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="1"
android:textSize="30sp" />
<Button
android:id="#+id/roll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Roll" />
</LinearLayout>
</FrameLayout>
</layout>
MainActivity.kt:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = ActivityMainBinding.inflate(layoutInflater)
binding.rollButton.text = "Test Roll"
setContentView(binding.root)
}
}
Tip: To convert fast Your layout to data binding layout use: Alt + Enter ➡ Convert to data binding layout

Android animate visibility change for two views at once

I want to hide two views (a Viewpager and a LinearLayout) at once when a Button is clicked. I tried using android:animateLayoutChanges="true", but it will always start hiding the Viewpager first and then the LinearLayout, which doesn't look good.
How can I manually hide both views at the same time? I have seen examples like this were the visibility of one view is changed:
myImageView.animate()
.translationY(myImageView.getHeight())
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
myImageView.setVisibility(View.GONE);
}
});
Is there a way to chain two animate() calls of different Viewsto trigger them simultaneously?
EDIT: This is my layout file, the Views I want to hide at the same time are the Viewpagerwith the id viewpager and the LinearLayout with the id ll_indicators:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<include
android:id="#+id/tv_statusbar"
layout="#layout/layout_statusbar"
android:layout_width="match_parent"
android:layout_height="#dimen/statusbar_height" />
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:textColor="#color/black"
android:text="#string/some_text"
android:padding="10dp"
android:textSize="#dimen/fontSizeMedium"
android:gravity="center_horizontal"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<LinearLayout
android:id="#+id/ll_indicators"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="#+id/intro_indicator_0"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="#dimen/activity_margin_half"
android:layout_marginRight="#dimen/activity_margin_half"
android:background="#drawable/indicator_unselected" />
<ImageView
android:id="#+id/intro_indicator_1"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="#dimen/activity_margin_half"
android:layout_marginRight="#dimen/activity_margin_half"
android:background="#drawable/indicator_unselected" />
</LinearLayout>
<include
android:id="#+id/ll_login"
android:layout_weight="0"
layout="#layout/item_login"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</include>
</LinearLayout>
Since you didn't post your layout, if you can put your ViewPager and LinearLayout in one layout, (for example inside a RelativeLayout) then you can animate that.
if( A.isShowing && B.isSowing(
A.hide
b.hide
)
Maybe this?
You can either just animate the parent LinearLayout, all Views within will animate with it :
yourLinearLayout.animate().setDuration(300).alpha(0). ...
, or call animate() on two Views simultaneously :
yourImageView.animate().alpha(0). ...
yourLinearLayout.animate().alpha(0). ...
which would look like they are disappearing at the same time.

Categories

Resources