Shared elements and content transitions in Fragments - android

I have the following problem:
I'm trying to transition from Fragment A to Fragment B. There is a shared element between these fragments in the form of a Button and some other View's (see layout).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:flipper="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mypackage.view.IndicatorViewFlipper
android:transitionGroup="true"
android:id="#+id/intro_viewflipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
flipper:indicatorColor="#color/white"
flipper:indicatorMargin="4dp"
flipper:indicatorRadius="4dp"
flipper:indicatorBarMargin="104dp"/>
<Button
android:id="#+id/account_create_btn"
style="?android:attr/borderlessButtonStyle"
android:textColor="#color/white"
android:layout_width="match_parent"
android:layout_height="#dimen/button_standard_height"
android:layout_above="#+id/txt_already_account"
android:background="#drawable/button_yellow_selector"
android:transitionName="create_account"
android:text="#string/account_create_btn"
android:textSize="24sp"
android:textAllCaps="false" />
<TextView
android:id="#+id/txt_already_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_above="#+id/account_login_btn"
android:layout_marginTop="24dp"
android:text="#string/account_welcome_already_account"/>
<Button
android:id="#+id/account_login_btn"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="#dimen/button_standard_height"
android:layout_marginTop="8dp"
android:layout_alignParentBottom="true"
android:transitionName="login"
android:background="#drawable/button_blue_selector"
android:textColor="#color/white"
android:textSize="24sp"
android:textAllCaps="false"
android:text="#string/account_create_login_btn"/>
</RelativeLayout>
What I'm trying to do is to let all the content in Fragment except for the shared element, transition (slide to the left) and let all the content form Fragment B except for the shared element slide in from the right. During this content transition I want the shared element to remain in its original position until the content transitions are done, and then let it slide to its new position in Fragment B.
This last behaviour is where it goes wrong: once I start the exit transition in Fragment A the shared element disappears and slides in from the right with the content transition of Fragment B. The behaviour of the shared element is correct if I don't add any exit/enter transitions.
The code (in Fragment A):
Fragment fragment = MyFragment.newInstance();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(this);
fragmentTransaction.add(R.id.frame_container, fragment, fragment.getClass().getSimpleName());
fragmentTransaction.addSharedElement(sharedElement, sharedElementTag);
Transition sharedElementTransaction = TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move);
sharedElementTransaction.setStartDelay(400);
fragment.setSharedElementEnterTransition(sharedElementTransaction);
setExitTransition(new Slide(Gravity.LEFT).setDuration(200));
fragment.setEnterTransition(new Slide(Gravity.RIGHT).setDuration(200));
Can anyone help me get the desired behaviour?
Update:
I've made a work around that almost does what I want using animate() on my views to slide/fade them and on completion of this animation trigger the shared element transaction:
Transition sharedElementTransition = TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move);
sharedElementTransition.setStartDelay(400);
fragment.setSharedElementEnterTransition(sharedElementTransition);
setSharedElementReturnTransition(sharedElementTransition);
mLoginBtn.animate()
.x(-mLoginBtn.getWidth())
.setDuration(400)
.start();
viewFlipper.animate()
.x(-viewFlipper.getWidth())
.setDuration(400)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
transaction.commit();
}
})
.start();
fragment.setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onSharedElementStart(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) {
super.onSharedElementStart(sharedElementNames, sharedElements, sharedElementSnapshots);
viewFlipper.animate()
.x(0)
.setDuration(400)
.setListener(null)
.start();
mLoginBtn.animate()
.x(0)
.setDuration(400)
.start();
});
The problem with this solution is that I can't slide in the Views of the called Fragment so there I now just fade in the Views.

If all you need is to animate the fragments while the button stays still, you can move the button to the activity and animate the fragment.

Related

Transition Manager - Sliding a view out is not working as wanted

I'm trying to slide this view in and out using Transition + Transition manager, however when hitting the hide button to make the view GONE it doesn't have the sliding animation. However, the show button does have the sliding in animation to make the view VISIBLE again.
#OnClick(R.id.testBtn)
public void onTestBtnClick(){
//hide
Transition transition = new Slide(Gravity.START);
transition.setDuration(600);
TransitionManager.beginDelayedTransition(mParentLayout, transition);
mLayout.setVisibility(View.GONE);
}
#OnClick(R.id.testBtn2)
public void onTestBtn2Click(){
//show
Transition transition = new Slide(Gravity.START);
transition.setDuration(600);
TransitionManager.beginDelayedTransition(mParentLayout, transition);
mLayout.setVisibility(View.VISIBLE);
}
I've tried changing the gravity of testBtn2 to Gravity.END, but that causes it to slide all the way starting from the right side of the screen.
Here's the layout:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/main_activity_root_view"
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:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="#+id/testBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:text="Hide"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="#+id/testBtn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/testBtn"
android:text="show"
/>
<LinearLayout
android:id="#+id/layout"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="250dp"
android:background="#drawable/background_side_bar_corners"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Not sure whats wrong with your code. i have created a sample, just try the code below it working fine. make sure to add android:visibility="gone" for panel view in layout so that its hidden at first launch.
public class MainActivity extends AppCompatActivity {
boolean isShowing = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_damm_activty);
findViewById(R.id.testBtn).setOnClickListener(v -> {
showSlidingPanel(!isShowing);
});
}
private void showSlidingPanel(boolean show) {
ViewGroup parent = findViewById(R.id.main_activity_root_view);
View layout = findViewById(R.id.layout);
Transition transition = new Slide(Gravity.START);
transition.setDuration(450);
transition.addTarget(R.id.layout);
transition.setInterpolator(new AccelerateDecelerateInterpolator());
TransitionManager.beginDelayedTransition(parent, transition);
layout.setVisibility(show ? View.VISIBLE : View.GONE);
isShowing = show;
}
}
Create these animations
slide up
<translate
android:duration="400"
android:fromYDelta="100%"
android:toYDelta="0" />
slide down
<translate
android:duration="400"
android:fromYDelta="0"
android:toYDelta="100%" />
When you want to set the layout visible
binding.musicOptionsLayout.setVisibility(View.GONE); binding.musicOptionsLayout.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_down));
When you want to set the layout Gone
binding.musicOptionsLayout.setVisibility(View.GONE); binding.musicOptionsLayout.startAnimation(AnimationUtils.loadAnimation(v.getContext(), R.anim.slide_down));
set android:visibility="gone" on XML..
Hope this will fix your issues...
The excellent answer here is very similar to this question.
I have noticed the constraint layout needs to be set up very specifically - if the view you are setting to GONE is constrained to it's sibling, those constraints seem to take precedence over any transition manager animation, i.e. setting a view to GONE just instantly kills it instead of smoothly animating, because the other view's constraints kick in immediately.
My solution was to use a guideline and have two views constrained to it, and set the GuidelineBegin for the transition manager. Just another option that may help:
val rootView = binding.constraintLayout
val constraintSet = ConstraintSet()
constraintSet.clone(rootView)
val transition = AutoTransition()
transition.duration = 150L
transition.excludeTarget(R.id.orders_recycler_view, true)
constraintSet.setGuidelineBegin(binding.guideline.id, if (showingDetailView) 0.px else 64.px)
TransitionManager.beginDelayedTransition(rootView as ViewGroup, transition)
constraintSet.applyTo(rootView)
Kotlin solution
Call the method wherever you want. Use FALSE to Slide out and TRUE
to Slide in.
targetView = View you want to slide in / out
rootLayout = Main layout where the targetView is located
In this example, it will slide from RIGHT to LEFT. If you want LEFT
to RIGHT, change Gravity.END to Gravity.START
private fun shareSlideInOut(show: Boolean) {
val slide = Slide(Gravity.END)
slide.duration = 450
slide.addTarget(targetView)
slide.interpolator = AccelerateDecelerateInterpolator()
TransitionManager.beginDelayedTransition(rootLayout, slide)
shareCodeLayout.visibility = if (show) View.VISIBLE else View.GONE
}

How to slide a view out of another view

I have a fragment with a navigation menu at the top-left corner. At the start of the activity, I want to gradually slide a view (let's call it black_view) out of the menu icon.
Here's a rough breakdown of how I want the animation to be in accordance with the images below:
Activity starts as the first image with black_view being invisible.
black_view gradually slides out from behind the menu icon length by length until it gets to the point of the second image.
>>>
What I've tried:
I tried achieving this by using a TranslateAnimation. However, the whole length of black_view shows up at the start of the animation and this is not what I want. I also saw a couple of sliding animation code snippets like this and this, but they all follow the TranlateAnimation model (with the whole length of black_view showing instantly).
How can I achieve this?
PS: If there's any important detail that I failed to add, kindly let me know.
It can be done easily with Slide transition from Transition API. Just use TransitionManager.beginDelayedTransition method then change visibility of black view from GONE to VISIBLE.
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
public class MainActivity extends AppCompatActivity {
private ViewGroup parent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
parent = findViewById(R.id.parent);
parent.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
parent.getViewTreeObserver().removeOnPreDrawListener(this);
animate();
return true;
}
});
}
private void animate() {
View textView = findViewById(R.id.text);
Transition transition = new Slide(Gravity.LEFT);
transition.setDuration(2000);
transition.setStartDelay(1000);
TransitionManager.beginDelayedTransition(parent, transition);
textView.setVisibility(View.VISIBLE);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="Button" />
<FrameLayout
android:id="#+id/parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/button">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000"
android:text="hello world"
android:textColor="#fff"
android:textSize="22sp"
android:visibility="gone" />
</FrameLayout>
</RelativeLayout>
Result:
All classes here are from androix package so code is backward compatible.

Animating Views while using DataBinding in Android

I have started using DataBinding in one of my projects and have been facing problems with Managing the views and Animations. I am using DataBinding in my application and also using BindingAdapters to animate views when a certain boolean gets set. I have used a similar approach described in this post.
In the animation I am trying to achieve using DataBinding, I have a searchbar in the middle of the screen and a list below it. When the user clicks on the searchBar, it animates to Top of the screen and the list scrolls to the bottom of the screen. (splitting a the center type animation)
I have certain boolean in my model, which gets set to true when the searchButton gets clicked and the BindingAdapter which listens in on that change in boolean, animates the view. I can get the view that needs to be animated but the amount by which the view animates depends on the size of another view, which is not being passed in the BindingAdapter. Is there a way to pass in multiple views in the BindingAdapter? My second question is, Since the searchbar and the list both animate on change of the same value, but how do I ensure that they animate simultaneously. If I were using 2 objectAnimators, I could use AnimatorSet and ensure synchronization, but how do I do this with DataBinding?
public class AnimHelper {
#BindingAdapter({"animatev1", "app:model"})
public static void Animate1(View view, boolean b, final Model model) {
if (b) {
ObjectAnimator a = ObjectAnimator
.ofFloat(view, View.TRANSLATION_Y, -view.getHeight())
.setDuration(2000);
a.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
model.setAnim2(true);
}
});
a.start();
}
}
#BindingAdapter({"animatev2", "app:model"})
public static void Animate2(View view, boolean anim, final Model model) {
if (anim) {
ObjectAnimator a = ObjectAnimator
.ofFloat(view, View.TRANSLATION_Y, view.getHeight())
.setDuration(2000);
a.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
a.start();
}
}
}
the xml file is as follows:
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="searchviewmodel"
type="com.example.mvvmvariableupdatinginanimend.ViewModel" />
</data>
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:animatev1="#{searchviewmodel.model.anim1}"
android:background="#android:color/transparent" >
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<TextView
android:id="#+id/search_button"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="202dp"
android:background="#fff"
android:drawableLeft="#android:drawable/ic_menu_search"
android:drawablePadding="12dp"
android:gravity="center_vertical"
android:hint="Search Button1..."
android:onClick="#{searchviewmodel.playSearchAnimation}"
android:textSize="16sp" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/scrl_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
app:animatev1="#{searchviewmodel.model.anim1}"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/lorem_ipsum"/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
In the above code on Click of searchBar, I am setting anim1 to true and the BindingAdapter written before does the animation of AppbarLayout and NestedScrollView on listening for changes in anim1. This seems to work as expected, but I want to account for the height of the Statusbar and searchButton in my animation, which is not happening currently, as I am not getting those views in my Animate1 function in AnimHelper.
You should be able to pass other views as values in binding expressions.
<TextView ...
app:animatev1="#{...}"
app:otherView="#{myOtherView}"/>
<TextView android:id="#+id/myOtherView" .../>
Your binding adapter can then take both parameters:
#BindingAdapter({"animatev1", "otherView"})
public static void animateV1(View view, boolean b, View otherView) {
//...
}
As for your second question, I don't think you should have to worry about the synchronization. They should start animations at the same time.
There's no great way to use an AnimatorSet on two different views with data binding. You can do it by passing one View to the other's binding adapter and animating them both in the same binding adapter. But that's not a great option. It is better to just animate them separately in different binding adapters and count on the framework to do the right thing.

How to build a viewpager that acts infinite and detects which side it was swiped?

I understand that a viewpager can be used, but I am having a hard time finding a good resource explaining how to use a viewpager with the following additions.
The view to record if the swipe was left or right, and either way just reload a new content (if left I want it to record no, right for it to record yes).
I want it to be infinite or really large, like 10000.
Finally, be able to add buttons underneath it as well.
In summary any direction, tutorials, or examples would be appreciated.
no tabs - just avoided implementing a tab listener and including tabs when creating the view pager
read swipes
load new content
infinite or really large
have buttons underneath it - done by including it in the drawer layout
Hopefully this clears things up:
UPDATE:
Here is the scenario I am trying to read swipes - if left record no and if right record yes, then grab new content from cache and display it, with the same two swipe options, I was thinking maybe I can just have 3 "pages" and swiping left records the action then it resets to position (middle - 1) and then loads the next content available in the cache... the only thing is I do not know how to call the reset and ask for a refresh of the content...
EDIT:
No tabs has been solved by just adding the code like so:
//viewpager adapter
private PageAdapter mAdapter;
private ViewPager viewPager;
// Initializing pager - in On Create
viewPager = (ViewPager) findViewById(R.id.random_pager);
FragmentManager fm = getFragmentManager();
mAdapter = new PageAdapter(getSupportFragmentManager(), new UserCreatedFragment(), new UserUpVotesFragment(),new UserDownVotesFragment());
viewPager.setAdapter(mAdapter);
// Here you would declare which page to visit on creation
viewPager.setCurrentItem(1);
This is the adapter:
public class PageAdapter extends FragmentPagerAdapter{
private Fragment frag1;
private Fragment frag2;
private Fragment frag3;
public PageAdapter(FragmentManager fm, Fragment frag1, Fragment frag2, Fragment frag3) {
super(fm);
this.frag1 = frag1;
this.frag2 = frag2;
this.frag3 = frag3;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
//fragments should record no and reset to the same frag with new content back in position 1
return frag2;
case 1:
//fragments for activity
return frag2;
case 2:
//fragments should record yes and reset to the same frag with new content back in position 1
return frag2;
}
return null;
}
//return count for number of tabs/swipes
#Override
public int getCount() {
return 3;
}
}
xml of activity:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Listview to display slider menu -->
<ListView
android:id="#+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector"
android:background="#color/list_background"/>
<!--View pager inside drawer so when opens it displays -->
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:id="#+id/viewPageLinear">
<android.support.v4.view.ViewPager
android:id="#+id/random_pager"
android:layout_width="wrap_content"
android:layout_height="300dp">
</android.support.v4.view.ViewPager>
<Button
android:layout_width="80dp"
android:layout_height="80dp"
android:gravity="center"
android:id="#+id/no"
android:layout_below="#+id/viewPageLinear"/>
<Button
android:layout_width="80dp"
android:layout_height="80dp"
android:gravity="center"
android:layout_below="#+id/no"/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
xml of fragment loaded:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:gravity="center"
android:layout_alignParentTop="true"
android:id="#+id/imagehere"/>
</RelativeLayout>
It's recommended to use FragmentStatePagerAdapter instead of FragmentPagerAdapter.
See http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html for reference.
This version of the pager is more useful when there are a large number
of pages, working more like a list view.
Other than that, it's not quite clear to me what the question (or the problem) is.
If you want to have Tabs title in your ViewPager you have to add this inside your ViewPager.
<android.support.v4.view.ViewPager
android:id="#+id/random_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.PagerTitleStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
And if you want infinite Tabs you should use FragmentStatePagerAdapter that is recommended when the number of Tabs is not specified.
Edit...
I've been looking a solution to your problem and this is what i found, if you want to know what direction user swiped you can do it this way, Implement SimpleOnPageChangeListener and on onPageSelected method do this:
#Override
public void onPageSelected(final int position) {
onTabChanged(mPager.getAdapter(), mCurrentTabPosition, position);
mCurrentTabPosition = position;
}
};
protected void onTabChanged(final PagerAdapter adapter, final int oldPosition, final int newPosition) {
if (oldPosition>newPosition){
// left to right
}
else{
//right to left
}
}

Android FragmentTransaction: How to generate an overlay slide in and move existing Fragement to left

I'm trying to do the following. Create a new Fragement B (Menu), slide it in from the right, and i want to move (no hide or replace!) the already shown Fragment A to the left.
I got the Transaction from Fragment B right, but Fragment A doesn't change his position at all. Seems like, my FragmentManager doesn't know that Fragment A exists (Fragment A is not added dynamically, it's defined in XML).
main_screen_layout-xml
<RelativeLayout //...
android:id="#+id/main_screen"
tools:context=".MainActivity"
<fragment
android:id="#+id/map_screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment" >
</fragment>
FragmentTransaction
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.add(R.id.main_screen, new MenuFragment(), MENU_FRAGMENT); //adding Fragment B
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left_cut);
ft.addToBackStack(null);
ft.commit();
Fragment A exists in the FragementManager and I can hide it, but that's not my goal
Fragment fragmentA = fragmentManager.findFragmentById(R.id.map_screen);
ft.hide(fragmentA); //hide FragmentA
What am I doing wrong?
Some Notes:
I'm using the Support Libaries (android.support.v4.app.FragmentManager..), but testing on API 17
As mentioned before, I didn't declare FragmentA specifically to the FragmentManager (tried so, but it says Fragment already exists)
Fragment A is (as you can see in XML) a google map from class SupportMapFragment
The animation XML is working, that's why I didn't post it
I'm not sure if this is exactly what you are looking for, but check out this Sliding Menu library... it allows one to slide in a fragment from the left or right while shifting the center content fragment.
Solution:
Create Relative Layout with overlapping fragments:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity" >
<RelativeLayout
android:id="#+id/back_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include layout="#layout/menu_fragment" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/front_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/map_screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/map_screen_bottom_bar"
class="com.google.android.gms.maps.SupportMapFragment" >
</fragment>
and simply call .translationX(-1 * mScreenWidth) (mScreenWidth is my ScreenWidth minus the gap you want).
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
((RelativeLayout) findViewById(R.id.front_frame)).animate()
.translationX(-1 * mScreenWidth);
} else {
TranslateAnimation slideOut = new TranslateAnimation(0, -1
* mScreenWidth, 0, 0);
slideOut.setDuration(getResources().getInteger(
R.integer.animation_transistion_length_short));
slideOut.setFillEnabled(true);
slideOut.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
RelativeLayout mView = (RelativeLayout) findViewById(R.id.front_frame);
int[] pos = { mView.getLeft() - mScreenWidth,
mView.getTop(), mView.getRight(),
mView.getBottom() };
mView.layout(pos[0], pos[1], pos[2], pos[3]);
}
});
((RelativeLayout) findViewById(R.id.front_frame))
.startAnimation(slideOut);
}

Categories

Resources