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?
Related
My App uses a single activity architecture which has a NestedScrollView in the activity layout
<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/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.navigationadvancedsample.MainActivity">
<androidx.core.widget.NestedScrollView
android:id="#+id/app_scroll_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true">
<FrameLayout
android:id="#+id/nav_host_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_nav"/>
</LinearLayout>
My issue is that that when I scroll a fragment, then navigate to another, then go back, the scroll position is reset. I've seen another answer which stated that adding IDs to the layouts should fix the issue, but it hasn't for me. Also, interestingly, the scroll position saves fine on configuration change.
I'm using NavigationComponents, could this be related? Here's a sample project that reproduces the issue (based on Google's NavigationAdvancedSample)
NestedScrollView has wrapped the Navigation Container in the activity_main layout. So it is the activity that saves the scroll state. There are 3 fragments. Home fragment has fixed height, Leaderboard and Register fragments are scrolling. When you scroll in the Leaderboard or Register and switch to the other one the scroll state does not change(since both can scroll to roughly the same height) but if you switch to home fragment scroll state resets because it has fixed height(size of the screen). Replacing NestedScrollView with the ScrollView didn't change anything as I examined it.
I think the right design is to wrap each fragment with NestedScrollView and set and get scroll state for each fragment.
Navigation component does not add the fragment to the activity state but replace it. So fragments get recreated after by switching between them. So you see scroll state is being reset. You can check it yourself by putting some log in the onCreateView of first fragment and see the log appears twice.
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"
I have a question regarding the android layout transition framework. In particular i want to achieve an effect that a certain part of an layout slides down or up depending on the visibility of another view(s).
Imagine the following layout. (And please overlook the nested LinearLayouts here ;) )
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/changingView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<View
android:id="#+id/changingView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout>
<LinearLayout
android:id="#+id/movingView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="false"/>
</LinearLayout>
Now what i want to achieve is that when changingView1 and changingView2 change their visibility that movingView slides up or down.
By enabling the LayoutTransition.CHANGING for the parent layout the sliding part works fine so. But this has the side effect that the movingView will also be animated when there are being items added or removed because this layout changes its bounds. And here lies my problem because this results in a very strange looking animation.
So back to my question. Is there a way to keep the sliding animation without animating layout bound changes on the movingView?
Disabling layoutTransitions on the movingView obviously does not help because this only effects the animations of the child views. I also tried playing around with enabling and disabling different LayoutTransitions on the parent layout but so far without the desired effect.
If i can add more details please let me know otherwise i hope someone can help me out.
Thanks in advance!
I know it's late but hope it can help someone. Since android:animateLayoutChanges is the property of the direct parent, you can wrap your View/Layout in a FrameLayout (or some other ViewGroup) and set android:animateLayoutChanges="false" on the new parent.
To avoid unwanted animations you can remove the animate layout changes by code when needed, something like this:
//removing the animate layout changes to prevent the default animation for the newly added items
parentLayout.setLayoutTransition(null);
/* do some logic to add the new views */
//add the animate layout changes back so the over changes will be still animated
new Handler().post(() -> {parentLayout.setLayoutTransition(new LayoutTransition());});
I am using the LinearLayout and inside there's button I am making visibilty gone based on supported states. SupportedStatuses are true then making Button as Visible but SupprtedStatuse are false then making button as Gone.
This is in a header and Button is Gone but still takes up the space.
Here is the Layout which I am using.
<LinearLayout
android:id="#+id/llparentView"
android:layout_width="match_parent"
android:layout_height="wrap_content
android:orientation="vertical">
<Button
android:id="#+id/btn_change_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Anybody have a good solution then it helps me a lot.
You could use a FrameLayout around whatever layout you are using
For example:
<FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content">
<!-- put your views here -->
</FrameLayout>
This will ensure when using View.GONE the FrameLayout collapses on the space.
Try to wrap your button in another Linear/Frame layout and change their visibility as well.
My question is simple: How to disable any event on a View in Android? (including removing its focussability, like I just want it to be there visually but be inexistant on everything else)
And does it work on a whole view tree? (like if I disable events on the root, all the events will be disabled for its children?).
Now, before you say anything I have tried all the following:
setEnabled
setFocusable
setSelected
setClickable
setActivated
And none of these methods appear to work, seriously.
I have tried them directly on a WebView, as well as on the parent layout on everything but I am still able to interact with it.
Any idea?
Thanks!
EDIT#1
The solution that consists in adding a view on top of the view that needs to be disabled doesn't work. Actually, it's still possible to click on the inner view, I have tried with a simple example:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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:background="#ff0000">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Click Me!"
/>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
/>
</FrameLayout>
Here it's still possible to click on the button.
EDIT#2
The reason why I want to do this is related to the following question that I asked weeks ago.
What I have is a ListViewacting as a navigation bar which is underneath a View that holds the content of my app. The problem with this implementation is that when I try to scroll through the ListView when there is a focusable view in the layer on top of it, well the ListView doesn't scroll and instead it's the top view that takes focus (That's the case when there is a
Webview or an EditText etc.).
So yes as mentioned in one of the answers, I can disable any click events on a WebView by overriding setOnTouchListener but the view remains focussed and I think this is the reason why I am still having the same issue with my navigation bar.
Simply put a view on top of your view. You can toggle it on off by setting view.visibility = gone/visible.
<FrameLayout>
<WebView/>
<FrameLayout This view will be on top/>
</FrameLayout>
Edit: Just stumpled upon this link: https://stackoverflow.com/a/3856199/969325
Basically disables all touch event for the webview. Tryed that?
Edit 2 reedit: Try to set the visibility to gone for the the top view below your listview.