I have two main activities - a list view (using the RecyclerView), and a detailed page. Each item in the list has a small image, and when clicking on an item in the list, I have an animation (using a shared element transition) that makes the image larger, and it takes up the upper half of the screen.
The bottom half of the detailed activity, has many details in various layouts.
My problem is that during the shared element transition of the image, I see all the details just appearing on the overlay.
I would like for the detailed activity to wait for the shared element transition to finish, and then slide in the details from the bottom of the page.
I searched the internet for this, but all the posts I found on the subject are either too old, or don't have enough details, so I couldn't get them to work.
Things I tried already :
In the detailed view, in onCreate() I tried creating a TransitionSet object with a delayed slide transition, and call getContentTransitionManager().beginDelayedTransition(). This didn't seem to do anything.
Creating the same TransitionSet object and calling getWindow().setEnterTransition(myTransitionSet) but this also doesn't seem to work.
I have defined getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); in the beginning of the onCreate() method in the detailed activity.
I'm sure I'm just missing something, I just have no idea what...
Related
I'm trying to do a sort of infinite scroll. Each Fragment contains a scrolling WebView (or ScrollView), and when the user hits the bottom, I'd like to test for continued swiping to reveal the next Fragment below.
The user should not be able to go back, and I'm not interested in caching, so that rules out RecyclerView or ViewPager (modified to scroll vertically). I'm only concerned about managing the current Fragment, loading the next, and removing the last one once it's offscreen.
I want the next Fragment to follow the users touch, and I want the transition to abort if the user lets go below a certain threshold.
FragmentManager allows custom animations but they are non-interactive. I could perhaps write my own ViewGroup where I can manually animate a Fragment into position, and remove the previous Fragment manually, but I'm not sure if this is the best path forward.
Anyone have thoughts/tips on a good approach here?
This may sound stupid, but can I do that? I have searched a little, and this says "Re-attach a fragment ... causes its view hierarchy to be re-created, attached to the UI, and displayed.", probably meaning that the UI of the fragment is recreated losing states and other things.
The reason why I am trying to do is that I would like to achieve something like the Bottom Sheet of Google Maps. The only title part is showed at the bottom, but we can swipe it up and it becomes a Bottom Sheet. I think when only the title part is showing, it is not actually a Bottom Sheet, as it would be difficult to make exactly that part of a Bottom Sheet to be shown. I think Google Maps has put the title part separately, and is replacing it with a Bottom Sheet whose top part looks just like the title part, when swiping up begins.
So, to achieve similar effect, I thought I would create a cluster of UI as a fragment, and when the user begins swiping up, I place a Bottom Sheet with the peek size is set exactly to the height of the fragment, and move the fragment into the top of the Bottom Sheet, so that it can be swiped up.
But I want to keep everything of the fragment without recreating anything, as if I take the fragment and just move into the fragment instantly. Is that possible, or should I save the states and restore them when the fragment's UI is recreated?
Yes. Consider fragment as View and play with ObjectAnimator or any animation class as per behaviour. (Slide-up animation will do the trick)
Note: Fragment will initialize first even you display 20% of portion over main layout. State will remain same This does answers your question i guess.
Here is similar example for your work around. Reference
I have the requirement for what is effectively two activities side by side, allowing the user to scroll from one to the other, and back. I've decided that ViewPager is probably the best way to handle this, but am open to suggestions.
When the activity loads, the left hand view is displayed. I want to indicate to the user that the other view exists, by just scrolling it a small amount to the left and back again (similar to the way it's now common to show that a sliding drawer menu exists).
I've tried a number of things but have yet failed to find a method where both the views scroll smoothly together. Another way of interpretting the requirement is saying I want to programmatically fake a user flicking the page briefly.
Try calling the method fakeDragBy(float)! According to the documentation you need to first call beginFakeDrag() to initiate it and then call endFakeDrag(). This will mantain the ViewPagers default snapping behavior, so once you've revealed the other screen is there you don't have to animate the transition back, simply call endFakeDrag and the ViewPager will correctly snap back to the last screen (As long as you haven't dragged it past the half-way mark).
After seeing a couple questions here on SO regarding Fragments "passing" their click events down to clickable Views in underlying Fragments, I recalled that I once encountered this problem. What is actually happening is that if a user clicks on a blank area of the top most Fragment, since its ViewGroup is not clickable, the event will be handled by the clickable View (i.e. Button) that is conveniently placed just below the user's finger. I fixed it by making the top Fragment's ViewGroup clickable. Back then I didn't give it much thought, but this solution seems a bit "hacky".
I understand that it is normal behavior for a View that is non clickable by default to not intercept click events, but one would think that given that one big use for Fragments is to display the view hierarchy (a task done by the Activity only before) that it will resemble an Activity in this sense. When one Activity fires the Intent to create a new Activity, and then this Activity is on the screen, no click events are delivered to the underlying Activity. I realize that an Activity can contain many Fragments that may not fill the whole screen or even have no xml, but sometimes click events are only meant to be retained by the top most Fragment.
With all that said, here come the questions:
1) Is setting the ViewGroup on the top most Fragment to be clickable the best way to solve this?
2) Does this feature exist and I am not aware of it? And if not, should it?
Is setting the ViewGroup on the top most Fragment the best way to solve this?
Assuming that your UI is akin to the UI from the question you linked to, the UI is written improperly.
My take on the UI from that question is that the developer has two fragments, A and B, each of which fill the screen. A is there initially, with the three buttons at the bottom. The developer then calls add() to display B, where B has an opaque black background.
This is dumb on a few levels. Not only do you run into this touch event propagation issue, but you have overdraw problems, because Android is going to render the buttons, then render the black background on top of them.
The right answer here is to have B replace() A.
(I realize that the developer actually does not have a fragment A, but has those widgets in the activity, which adds another level of sketchiness to that UI)
More generally, I would not have fragments, or anything else, higher on the Z axis with the intent to hide underlying widgets. So, for example, having a full-screen VideoView, with a pop-up MediaController higher on the Z axis is fine, because touch events destined for the controller would be picked up by the controller, yet the user can still tap on portions of the VideoView not blocked by the controller. Conversely, I would not implement a tabbed Web browser by having one WebView overlay another WebView on the Z axis -- either there would only be one WebView, or there would only be one visible WebView (with the other removed from the view hierarchy or marked as View.GONE).
When one Activity fires the Intent to create a new Activity, and then this Activity is on the screen, no click events are delivered to the underlying Activity.
That is because there is no "underlying activity" in terms of the view hierarchy. More technically, each activity is in its own Window, and so even if the top-most Window does not fill the screen (e.g., dialog-themed activity), the "underlying activity" is visible but cannot receive touch events.
I realize that an Activity can contain many Fragments that may not fill the whole screen or even have no xml, but sometimes click events are only meant to be retained by the top most Fragment.
Then there should not be anything underneath "the top most Fragment", IMHO. Use replace(), not add(), when doing this sort of UI switch. Or, use a DialogFragment, if you want to temporarily have something modal take over foreground input (as a dialog gets its own Window, if I understand correctly). Do not just paint a solid background and pretend that other widgets, now painted over, do not exist.
Does this feature exist and I am not aware of it?
No, because fragments are not ViewGroups and therefore are not involved in managing the routing of touch events.
And if not, should it?
IMHO, no, though you're welcome to file an issue for it.
Here's what I want to do in an app, hope it's clear:
NOTE: I don't want to have all 3 views on the screen at once!
I have a search window, I have results, and I want to show details about a result item when it's clicked.
On a small screen (phone) it's pretty clear: I show one view at a time.
On a tablet, especially in landscape mode I'd like to show 2 views at a time, means:
[search | results] and when a result item is clicked, show [results | item detail].
My ideas:
Have an Activity "SearchAndResults", when result item is clicked, open another Activity calles ResultsAndDetails. Both Activities would use Fragments, eg SearchFragment, ResultFragment, DetailFragment.
This might be quite easy to implement but doesn't seem very elegant to me, especially because I can't have any animation (let the result view slide to the left, let the detail view slide in from the right)
Have all 3 view in one activity and hide/ show them with layout.setvisibility(). No animations either, and I hate to do too much layout stuff in my code.
A viewpager that shows 2 views, but can't be swiped by the user, only from code?
What's a good way to do this?
I would use Fragments, as in your idea #1. This question seems to be describing the exact same type of layout that you are trying to implement. It has several answers on how to animate fragment transitions, including complete code examples.