I have two Activities: Activity A and Activity B. Activity A contains a view hierarchy with a circular ImageView in the center that looks like the following:
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/image_profile"
android:layout_width="105dp"
android:layout_height="105dp"
android:layout_weight="2"
android:transitionName="#string/transition_profile_image"/>
Activity B is a basic FrameLayout that contains a single, rectangular ImageView with the same transitonName. The goal: when clicking on the CircleImageView in Activity A, I want to transition into an expanded, fullscreen view of the image in Activity B. Going back to Activity A should reverse this transition.
I can get a transition to work using the following, basic scene transition:
profileImageView.setOnClickListener(view -> {
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
profileImageView, getString(R.string.transition_profile_image));
startActivity(ActivityB.getStartIntent(this, imageUrl),
options.toBundle());
});
Using this code, Activity B's rectangular ImageView overlays on top of the CircleImageView and then grows to fill the screen. It looks like the circle blinks into a rectangle. The transition of the image should instead perform some sort of transform animation from a circle to a rectangle. Anyone familiar with how to achieve this?
Related
I am creating a chatting app and when a image arrives in chat it looks like this.
Now I want to achieve WhatsApp like effect. I think on WhatsApp when you click the image it expands to whole screen with a smooth animation. I can add click Listener on the image but I don't know how to achieve that effect with smooth animation.
You can achieve this effect pretty easily with a SharedElementTransition. In short, you create a new activity that only displays the image and tell the framework which view from the first activity/fragment corresponds to the image in the new activity and the rest is done automatically.
In the new activity layout add a transition name to the ImageView. You'll have to load the image in this activity manually, so you have to pass the URL to the activity if you're loading from the network, or pass the bitmap in another way.
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="image"/>
When the image is clicked you start the activity and specify ImageView clicked and map it to the transitionName:
// If you're in a fragment
val activity = requireActivity()
// imageView here corresponds to the image before it is animated
// "image" is transitionName in the new activity
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView, "image")
activity.startActivity(Intent(context, ImageActivity::class.java), options.toBundle())
Also, the style used for the activities must set android:windowContentTransitions to true:
<style name="...">
<item name="android:windowContentTransitions">true</item>
</style>
Please look at this video showing a shared elements activity transition.
It's a transition from a list activity to a detail activity.
[Video link no longer works]
As you can see the imageview gets drawn in front of the tabs.
What I would expect is the tabs being drawn in font on the imageview and fading out throughout the transition (so that at the end of the animation they are gone).
The only thing that seems to work is setting windowSharedElementsUseOverlay to true,
but that has other ugly effects, so that seems not to be an option.
The most commonly suggested approach is to include the tabs in the transition itself, but the problem is that the tabs are not there in the detail activity so they cannot be shared.
Code:
I start the detail activity like this:
options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, pairs);
ActivityCompat.startActivity(activity, subActivity, options.toBundle());
I believe what you may need is to exclude, rather than include, the tab layout from the transition animation.
So in the onCreate of your list activity, include:
Transition fade = new Fade();
fade.excludeTarget(R.id.tab, true); // use appropriate id for you tab
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade); // try getWindow().setReenterTransition(fade); instead
Definitely have a look at Alex Lockwood's answer to How do I prevent the status bar and navigation bar from animating during an activity scene animation transition? where he gives a greater and more in-depth but digestible explanation on the topic. You may also want to consider adding/implementing the solution in that post.
You should try this:
On the exiting activity, call getWindow().setExitTransition(null);
On the entering activity, call getWindow().setEnterTransition(null);
It will prevent the fade out of the exiting activity and the fade in of the entering activity, which removes the apparent blinking effect and make transition smooth.
My calling activity has a both a tablayout and a toolbar within and each time I did the transition, the image would appear on top of both tablayout and toolbar, making the transition look untidy.
I fixed the problem quite elegantly by just adding a "dummy" tablayout and a "dummy" toolbar in my called activity. The "dummy" elements are not visible so it doesn't impact the layout of my called activity but the transition effect will work properly if you add them in.
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar2"
android:transitionName="toolbar"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="60dp"
android:visibility="gone"
android:transitionName="tab"
></android.support.design.widget.TabLayout>
I then added the tablayout and the toolbar as a pair in my transition:
Pair<View, String> p4 = Pair.create(getActivity().findViewById(R.id.sliding_tabs), "tab");
Pair<View, String> p5 = Pair.create(getActivity().findViewById(R.id.toolbar), "toolbar");
Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), p1, p2, p3, p4, p5).toBundle();
I'm trying to apply a TranslateAnimation to an ImageView inside of a LinearLayout. As soon as the ImageView(marked "1" in the image below) crosses the bounds of the LinearLayout that contains the ImageView, it goes "black"/disappears. This does NOT happen if I animate the entire green LinearLayout, so I don't think it has to do with it's z-value. Rather, I believe that the ImageView can't visually "escape" its container layout (green). What can I do to make the ImageView display in front of everything when the animation is being performed? I've already tried .bringToFront()(followed by .requestLayout/.invalidate of the root view).
Try to set android:clipChildren="false" in a parent container
Can anyone explain how can I add shape (for example a rectangle or an arrow) on to a image (in ImageView)? Once added, the shape will need to be draggable to anywhere in the image. And finally need to save the image edited (with the shape on top of that).
What informations do you really need?
This can be some steps to do:
Maybe create a new object to handle this:
Create a new class and extend from ImageView or use LayerDrawable for that.
Write setters/getters for the main-background-image/bitmap.
Add your own Vector shape (create a new class with definable color,thickness... or hard-code it)
Do all of your drawings in onDraw-Methods
Implement onTouch interfaces to handle your selection and dragging.
Create new method (render to jpeg/png/..) to save your resulting image
Create a Custom view from View that completely overlaps your ImageView. This view will have a transparent background and contain the draggging view. Initially set visibility to invisible.
In Custom view class override the onTouch event where you update the dragging views margins.
On save, get drawing cache of the parent layout(that contains both the ImageView and Custom view) and use as needed.
Sample xml code:
Relative layout parent whose drawing cache has to be grabbed using rel.getDrawingCache()
<RelativeLayout .......>
<ImageView ......./>
<CustomView ......./>
</RelativeLayout>
I have a button that starts out as a placeholder, but once the user authenticates, it changes to a custom image for that user.
<ImageButton android:id="#+id/button"
android:background="#null"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/button_default"/>
And then later:
ImageButton ib = (ImageButton)findViewById(R.id.button);
ib.setImageBitmap(previouslyDecodedBitmap);
But this looks terrible. I can't figure out how to style it properly so that the newly decoded bitmap is the right size and behaves like an ImageButton. I suspect there is some combination of widgets I can use other than ImageButton to achieve this? I was hoping I could just nest an ImageView on top of the ImageButton by adding it as a child to ImageButton, but that doesn't seem to be allowed (it is in Silverlight...).
Anyway, any suggestions on how to properly do this are welcome. Thanks.
One way would be to use frame layout and place buttons and image one over the other , top being imageview , keep it invisible (android:visibility = "invisible")
On clicking the button and authenticating , make it visible over the button or else even you can hide the button below and show only image on top.