How can I do a animation that pushes the current fragment by the next fragment
Here is the Animation that I want:
My current animation code just overlaps the first fragment by the second fragment it didnt push it just like in the picture
Here is the code:
result_list.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> av, final View view,
final int i, long i2) {
result_list.setEnabled(false);
view.animate().setDuration(300).translationX(widthListView).alpha(0).
withEndAction(new Runnable() {
@Override
public void run() {
//setResult(Activity.RESULT_OK,new Intent().putExtra("bussStopCode", data.get(i).getStopCode()).putExtra("bussStopName", data.get(i).getStopName()));
////int get 1
//data.remove(i);
int temporaryInteger = i;
listLastPostion = temporaryInteger;
//customAdapter.notifyDataSetChanged();
//view.setTranslationX(0);
Log.d("data",conreq.getCollectedData().getBusRouteSetData().get(temporaryInteger - 1).getRouteHeading());
Bundle bundle = new Bundle();
bundle.putString("busdestination", conreq.getCollectedData().getBusRouteSetData().get(temporaryInteger-1).getRouteHeading());
bundle.putString("busnumber", conreq.getCollectedData().getBusRouteSetData().get(temporaryInteger-1).getRouteNo());
Fragment fragment = new FragmentNextTripForStop();
fragment.setArguments(bundle);
FragmentTransaction fragmentManager = getFragmentManager().beginTransaction();
fragmentManager.setCustomAnimations(R.anim.right_left_anim_x_left,R.anim.right_left_anim_x_right,R.anim.left_right_anim_x_left,R.anim.left_right_anim_x_right);
fragmentManager.add(R.id.fragment_searched_data_xml, fragment).addToBackStack(null).commit();
// finish();
//overridePendingTransition(R.anim.right_left_anim_x_left,R.anim.right_left_anim_x_right);
}
});
}});
Although this question is a duplicate, the answer that was provided on that question does not work for many viewers and requires them to make a few assumptions on their end.
This is an excellent question considering this functionality exists in many applications, however it requires a very elaborate answer. I will try to break the answer down into a series of compartmentalized steps to ensure that it is repeatable!
The problem inhibiting most of us from doing this easily is one of a compound nature. To fully understand this problem, let me list the issues:
FragmentManager
and FragmentTransaction
classes provide a convenience method, setCustomAnimations(int, int, int int)
, that require ObjectAnimators
ObjectAnimators
(the traditional approach)In order to tackle this problem and provide the immersive experience desired, we must tackle the it from many angles. These next few steps explain exactly how to acquire this functionality!
We first need to define a custom layout for each Fragment
as we must have runtime access to the width of the screen, and a self-contained method to manipulate the x-position of the View
(the layout) based on this width.
public class FractionTranslateLinearLayout extends LinearLayout{
private int screenWidth;
private float fractionX;
protected void onSizeChanged(int w, int h, int oldW, int oldh){
// Assign the actual screen width to our class variable.
screenWidth = w;
super.onSizeChanged(w, h, oldW, oldH);
}
public float getFractionX(){
return fractionX;
}
public void setFractionX(float xFraction){
this.fractionX = xFraction;
// When we modify the xFraction, we want to adjust the x translation
// accordingly. Here, the scale is that if xFraction is -1, then
// the layout is off screen to the left, if xFraction is 0, then the
// layout is exactly on the screen, and if xFraction is 1, then the
// layout is completely offscreen to the right.
setX((screenWidth > 0) ? (xFraction * screenWidth) : 0);
}
}
Now, since we have a special layout that will allow us to translate based on the physical width of the screen, we can use it in the associated Fragment XML files.
<com.[your_package_here].FractionTranslateLinearLayout
// Omitted namespace.
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text_view_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment 1" />
</com.[your_package_here].FractionTranslateLinearLayout>
<com.[your_package_here].FractionTranslateLinearLayout
// Omitted namespace.
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text_view_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment 2" />
</com.[your_package_here].FractionTranslateLinearLayout>
Then, we must create the Fragment
classes that will contain the logic to implement the transitions.
public class Fragment1 extends Fragment {
public View onCreateView(LayoutInflater inf, ViewGroup vg, Bundle b){
// Simply inflate the View from the .xml file.
return inf.inflate(R.layout.fragment_1, vg, false);
}
}
public class Fragment2 extends Fragment {
public View onCreateView(LayoutInflater inf, ViewGroup vg, Bundle b){
// Simply inflate the View from the .xml file.
return inf.inflate(R.layout.fragment_2, vg, false);
}
public void onActivityCreated (Bundle savedInstanceState){
View v = getView();
FractionTranslateLinearLayout layout;
layout = (FractionTranslateLinearLayout) v.findViewById(R.id.layout);
// Move the entire View off to the right of the screen for now.
layout.setFractionX(1.0f);
}
}
Let's now create the objectAnimator
.xml files that we will use to translate the View
s across the screen. Note that we will need four of these files because we need one for each process (out and in), and one for each side (left and right).
<objectAnimator
// Omitted namespace.
android:valueFrom="0"
android:valueTo="-1"
// This String must be the exact name of the class variable.
android:propertyName="xFraction"
android:valueType="floatType"
// Duration in milliseconds.
android:duration="500"/>
<objectAnimator
// Omitted namespace.
android:valueFrom="0"
android:valueTo="1"
// This String must be the exact name of the class variable.
android:propertyName="xFraction"
android:valueType="floatType"
// Duration in milliseconds.
android:duration="500"/>
<objectAnimator
// Omitted namespace.
android:valueFrom="-1"
android:valueTo="0"
// This String must be the exact name of the class variable.
android:propertyName="xFraction"
android:valueType="floatType"
// Duration in milliseconds.
android:duration="500"/>
<objectAnimator
// Omitted namespace.
android:valueFrom="1"
android:valueTo="0"
// This String must be the exact name of the class variable.
android:propertyName="xFraction"
android:valueType="floatType"
// Duration in milliseconds.
android:duration="500"/>
Note that these folders must be placed in the 'res/animator' directory in your project structure.
Create the container layout that will hold each Fragment
as we transition between them.
<com.android.FrameLayout
// Omitted namespace.
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Now, we must create the Activity
that will wrap everything together!
public class Main extends Activity {
private boolean showingFirstFragment;
public void onCreate(Bundle savedInstanceState){
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
// Keep track of which Fragment we are facing.
showingFirstFragment = true;
// Add the first Fragment to the container.
trans.add(R.id.main_container, new Fragment1(), "fragment_1");
trans.commit();
}
public void onBackPressed(){
// Override the back button functionality to simply switch
// Fragments. Note that this would normally be done in a click
// click listener.
switchFragments();
}
private void switchFragments(){
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
// Set the animations that will emulate the functionality you
// requested.
int rightIn = R.animator.slide_right_in;
int rightOut = R.animator.slide_right_out;
int leftIn = R.animator.slide_left_in;
int leftOut = R.animator.slide_left_out;
// Note that we pass in 4 animations here. Please see the
// documentation on this method as it is critical to the
// understanding of this solution.
trans.setCustomAnimations(rightIn, leftOut, leftIn, rightOut);
if(showingFirstFragment){
int container = R.id.main_container;
// Show the second Fragment.
trans.replace(container, new Fragment2(), "fragment_2");
trans.commit();
showingFirstFragment = false;
}
else{
// Show the first Fragment by popping the back stack!
manager.popBackStack(null);
showingFirstFragment = true;
}
}
}
In this code example, this class is used heavily. Its methods are crucial to the execution of the process!
Note that I have made a few assumptions here, and that this code is quite unique:
Fragment
class, and thus will not work with the support package unless the necessary modifications are made.Android API 13.0
or above.Hopefully there is sufficient detail here to answer your question. Please let me know if you require any more.
At this point, there should be enough code to implement your own twist on the solution. I did type this up without the crutch of the Eclipse editor, so if there are any errors, please accept my apologies in advance!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With