Friday, April 26, 2013

Implement animation in FragmentTransaction

setCustomAnimations(int enter, int exit, int popEnter, int popExit) and setCustomAnimations(int enter, int exit) methods of FragmentTransaction class set specific animation resources to run for the fragments that are entering and exiting in this transaction. The popEnter and popExit animations will be played for enter/exit operations specifically when popping the back stack.

Example Code:

    FragmentTransaction fragmentTransaction =
getActivity().getFragmentManager().beginTransaction();

fragmentTransaction.setCustomAnimations(
R.anim.fadein, R.anim.fadeout, R.anim.fadein, R.anim.fadeout);

fragmentTransaction.replace(R.id.phone_container, myDetailFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();


animation in FragmentTransaction


Further work on previous exercise "implements OnBackStackChangedListener to display UP icon, automatically by getBackStackEntryCount()".

Create /res/anim/fadein.xml.
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="alpha"
android:valueFrom="0.0"
android:valueTo="1"
android:duration="500"
/>


/res/anim/fadeout.xml.
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0.0"
android:duration="500"
/>


MainActivity.java
package com.example.androiddualmode;

import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager.OnBackStackChangedListener;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnBackStackChangedListener{

// if run on phone, isSinglePane = true
// if run on tablet, isSinglePane = false
static boolean isSinglePane;

static String[] month ={
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"};

public static class MyListFragment extends ListFragment {

@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);

ListAdapter myArrayAdapter =
new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_list_item_1, month);
setListAdapter(myArrayAdapter);

}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {

String clickedDetail = (String)l.getItemAtPosition(position);

if(isSinglePane == true){
/*
* The second fragment not yet loaded.
* Load MyDetailFragment by FragmentTransaction, and pass
* data from current fragment to second fragment via bundle.
*/
MyDetailFragment myDetailFragment = new MyDetailFragment();
Bundle bundle = new Bundle();
bundle.putString("KEY_DETAIL", clickedDetail);
myDetailFragment.setArguments(bundle);
FragmentTransaction fragmentTransaction =
getActivity().getFragmentManager().beginTransaction();

fragmentTransaction.setCustomAnimations(
R.anim.fadein, R.anim.fadeout, R.anim.fadein, R.anim.fadeout);

fragmentTransaction.replace(R.id.phone_container, myDetailFragment);

/*
* Add this transaction to the back stack.
* This means that the transaction will be remembered after it is
* committed, and will reverse its operation when later popped off
* the stack.
*/
fragmentTransaction.addToBackStack(null);

fragmentTransaction.commit();

}else{
/*
* Activity have two fragments. Pass data between fragments
* via reference to fragment
*/

//get reference to MyDetailFragment
MyDetailFragment myDetailFragment =
(MyDetailFragment)getFragmentManager().findFragmentById(R.id.detail_fragment);
myDetailFragment.updateDetail(clickedDetail);

}
}

}

public static class MyDetailFragment extends Fragment {

TextView textDetail;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.layout_detailfragment, null);
textDetail = (TextView)view.findViewById(R.id.text_detail);

Bundle bundle = getArguments();
if(bundle != null){
String detail = bundle.getString("KEY_DETAIL", "no argument pass");
textDetail.setText(detail);
}

return view;
}

public void updateDetail(String detail) {
textDetail.setText(detail);
}

}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

View v = findViewById(R.id.phone_container);
if(v == null){
//it's run on tablet
isSinglePane = false;
/*
* MyListFragment and MyDetailFragment have been loaded in XML,
* no need load.
*/

}else{
//it's run on phone
//Load MyListFragment programmatically
isSinglePane = true;

if(savedInstanceState == null){
//if's the first time created
MyListFragment myListFragment = new MyListFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();

fragmentTransaction.add(R.id.phone_container, myListFragment);
fragmentTransaction.commit();
}
}

getFragmentManager().addOnBackStackChangedListener(this);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getFragmentManager().popBackStack();
return true;
}

return super.onOptionsItemSelected(item);
}

final static String KEY_DISPLAY_OPT = "KEY_Display_Option";

@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putInt(KEY_DISPLAY_OPT, getActionBar().getDisplayOptions());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
int savedDisplayOpt = savedInstanceState.getInt(KEY_DISPLAY_OPT);
if(savedDisplayOpt != 0){
getActionBar().setDisplayOptions(savedDisplayOpt);
}
}

@Override
public void onBackStackChanged() {
int backStackEntryCount = getFragmentManager().getBackStackEntryCount();
if(backStackEntryCount > 0){
getActionBar().setDisplayHomeAsUpEnabled(true);
}else{
getActionBar().setDisplayHomeAsUpEnabled(false);
}
}

}


download filesDownload the files.

No comments:

Post a Comment