FragmentManager not calling onCreateView with second tab after orientation change - android

I have 3 fragments in TabA, and a PreferenceFragment in TabB. To recreate the problem I start the program, TabA displays fine. I click TabB and it also displays fine. If I return to TabA, and do an orientation change, the next time I click on TabB there is just a blank screen. I've narrowed it down to the FragmentManager not calling onCreateView on the Fragment in TabB.
I'm checking that the Fragments are not null and don't need to be recreated and getting references to them with their findFragmentByTag after orientation changes. TabA never has an issue, i tried to recreate the issue with TabA but onCreateView would always get called by the FragmentManager for each Fragment. I have min API 15, target 19.
Pruned down version of MyActivity.java to be runnable
public class MyActivity extends Activity {
private static final String TAG = "MainActivity";
public FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master);
fm = getFragmentManager();
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabA = actionBar.newTab().setText("Main");
ActionBar.Tab tabB = actionBar.newTab().setText("Settings");
tabA.setTabListener(new TabAListener(this));
actionBar.addTab(tabA);
tabB.setTabListener(new TabBListener(this));
actionBar.addTab(tabB);
if (savedInstanceState != null) {
int index = savedInstanceState.getInt("index");
actionBar.setSelectedNavigationItem(index);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.d(TAG, "onSaveInstanceState");
super.onSaveInstanceState(outState);
int i = getActionBar().getSelectedNavigationIndex();
outState.putInt("index", i);
}
public class TabAListener implements ActionBar.TabListener {
private static final String genTag = "GenerateFragment";
private static final String aboutTag = "AboutFragment";
public static final String resultsTag = "ResultsListFragment";
private ArrayList<Fragment> fragList;
public TabAListener(Activity activity) {
fragList = null;
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// Reselected don't do anything
Log.d(TAG, "Tab A: on Tab reselected");
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Log.d(TAG, "Tab A: on Tab Selected");
// attach all the fragments
if (fragList == null) {
fragList = new ArrayList<Fragment>();
TestFragment genFrag;
if (fm.findFragmentByTag(genTag) == null) {
genFrag = new TestFragment();
ft.add(R.id.gen_fragment, genFrag, genTag);
} else genFrag = (TestFragment) fm.findFragmentByTag(genTag);
TestFragment aboutFrag;
if (fm.findFragmentByTag(aboutTag) == null) {
aboutFrag = new TestFragment();
ft.add(R.id.about_fragment, aboutFrag, aboutTag);
} else aboutFrag = (TestFragment) fm.findFragmentByTag(aboutTag);
TestFragment resultsFrag;
if (fm.findFragmentByTag(resultsTag) == null) {
resultsFrag = new TestFragment();
ft.add(R.id.results_fragment, resultsFrag, resultsTag);
} else {
resultsFrag = (TestFragment) fm.findFragmentByTag(resultsTag);
}
fragList.add(genFrag);
fragList.add(aboutFrag);
fragList.add(resultsFrag);
Log.d(TAG, "Tab A: Added fragments to the ArrayList");
} else {
Iterator iter = fragList.iterator();
while (iter.hasNext()) {
Log.d(TAG, "Tab A: Attaching fragments");
ft.attach((Fragment) iter.next());
}
}
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
Log.d(TAG, "Tab A: on Tab Unselected");
if (fragList != null) {
Iterator iter = fragList.iterator();
while (iter.hasNext()) {
Log.d(TAG, "Tab A: Fragments detached");
ft.detach((Fragment) iter.next());
}
}
}
}
public class TabBListener implements ActionBar.TabListener {
private static final String settingsTag = "SettingsFragment";
private ArrayList<Fragment> fragList;
public TabBListener(Activity activity) {
fragList = null;
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// Reselected don't do anything
Log.d(TAG, "Tab B: on Tab reselected");
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Log.d(TAG, "Tab B: on Tab Selected");
// attach all the fragments
if (fragList == null) {
fragList = new ArrayList<Fragment>();
TestFragment settingsFrag;
if (fm.findFragmentByTag(settingsTag) == null) {
settingsFrag = new TestFragment();
ft.add(R.id.frame_main, settingsFrag, settingsTag);
} else {
Log.d(TAG, "Tab B: not null");
settingsFrag = (TestFragment) fm.findFragmentByTag(settingsTag);
}
fragList.add(settingsFrag);
Log.d(TAG, "Tab B: Added fragments to the ArrayList");
} else {
Iterator iter = fragList.iterator();
while (iter.hasNext()) {
Log.d(TAG, "Tab B: Attaching fragments");
ft.attach((Fragment) iter.next());
}
}
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
Log.d(TAG, "Tab B: on Tab Unselected");
if (fragList != null) {
Iterator iter = fragList.iterator();
while (iter.hasNext()) {
Log.d(TAG, "Tab B: Fragments detached");
ft.detach((Fragment) iter.next());
}
}
}
}
public static class TestFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_text, container, false);
}
}
}
activity_master.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frame_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical">
<FrameLayout
android:id="#+id/gen_fragment"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/about_fragment"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
<FrameLayout
android:id="#+id/results_fragment"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
</FrameLayout>
fragment_text.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="test" />
</LinearLayout>

So, I guess I have to remove the super call in MainActivity.onSaveInstanceState in order for onCreateView to be called correctly for TabB's fragment after an orientation change. Umm, I'm not sure why that works so could someone explain why?
I've been able to gather that the super.onSaveInstanceState saves the activities views for when the user navigates away from the application and eventually returns. And the FragmentManager also has responsibility for the contents of the fragment through orientation changes. I'm kind of lost at that point.

Related

Google map in Sherlock Tab

I have a tab navigation working ( 2 tabs). In the second tab, I want to insert a google map object.
Code for using tabs :
public class FragmentTabsTienda extends SherlockFragmentActivity {
private static String TAG = "TabActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frag_pdvs);
FragmentManager fm = getSupportFragmentManager();
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = actionBar.newTab();
tab1.setText("Lista");
tab1.setIcon(R.drawable.ic_action_view_as_list);
ActionBar.Tab tab2 = getSupportActionBar().newTab();
tab2.setText("Mapa");
tab2.setIcon(R.drawable.ic_action_location_map);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("");
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
// create the two fragments we want to use for display content
tab1.setTabListener(new TabListener<ListTiendaTabFragment>(this,
"lista", ListTiendaTabFragment.class));
tab2.setTabListener(new TabListener<MapTiendasTabFragment>(this,
"mapa", MapTiendasTabFragment.class));
actionBar.addTab(tab1);
actionBar.addTab(tab2);
// tab2.setTabListener(new TabListener(fMapTiendas));
}
public static class TabListener<T extends Fragment> implements
ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
/**
* Constructor used each time a new tab is created.
*
* #param activity
* The host Activity, used to instantiate the fragment
* #param tag
* The identifier tag for the fragment
* #param clz
* The fragment's Class, used to instantiate the fragment
*/
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("camara").setIcon(R.drawable.ic_action_device_access_camera)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.add("chat").setIcon(R.drawable.ic_action_social_chat)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.add("settings").setIcon(R.drawable.ic_settings)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
return super.onCreateOptionsMenu(menu);
}
}
In the first tab, my list is displaying well.
But I can't display my map :
This is the code for the tab I want to display the map:
public class MapTiendasTabFragment extends SherlockFragment {
GoogleMap mMap = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = super.onCreateView(inflater, container, savedInstanceState);
return root;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mMap = initMap();
}
private GoogleMap initMap() {
if (mMap == null) {
FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
SupportMapFragment smf = (SupportMapFragment) fm.findFragmentById(R.id.map); // is null !!
mMap = smf.getMap();
} else {
mMap.setMyLocationEnabled(true);
// Iniciar centrado en Mexico
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
19.506467, -99.131417), 4));
}
return mMap;
}
}
and the associated xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/fl_map"
android:layout_width="fill_parent"
android:layout_height="0.0dip"
android:layout_weight="1.0" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
<TextView
android:id="#+id/maps_unavailable"
style="#style/placeholder_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/maps_unavailable"
android:visibility="gone" />
<View
android:id="#+id/shadow"
android:layout_width="fill_parent"
android:layout_height="4.0dip"
android:layout_gravity="bottom|center"
android:background="#drawable/inset_bottom_shadow" />
<ProgressBar
android:id="#+id/ab_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"
android:visibility="gone" />
</FrameLayout>
<!--
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="#dimen/map_pager_height" />
-->
</LinearLayout>
In my code , the SupportMapFragment smf is null, I can't get any value !!!
Any help would be appreciated
The problem were resolved with this gist :
https://gist.github.com/joshdholtz/4522551
public class SomeFragment extends Fragment {
MapView mapView;
GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.some_layout, container, false);
// Gets the MapView from the XML layout and creates it
mapView = (MapView) v.findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
// Gets to GoogleMap from the MapView and does initialization stuff
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(false);
map.setMyLocationEnabled(true);
// Needs to call MapsInitializer before doing any CameraUpdateFactory calls
try {
MapsInitializer.initialize(this.getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
// Updates the location and zoom of the MapView
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
map.animateCamera(cameraUpdate);
return v;
}
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}

Unable to start activity componentInfo Tablistener suddenly crashing the app

So i'm getting this annoying problem. I'm pretty noob when it comes to android, so any help would be nice.
This is my MainActivity which seems to be crashing according to LogCat.
The app i'm trying to create must pull data from XML data, which i'm trying to get. Then from this data it must set the tabs name (that's what i'm trying to do).
public class MainActivity extends SherlockActivity {
private String uniqeAppId;
private ArrayList<StartupInfo> info;
private String ChannelTab;
private String VicinityTab;
private String CustomTab;
private String TrackingTab;
private String MoreTab;
public static Context appContext;
private DownloadXmlTask downloadxml = new DownloadXmlTask(this);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = new ArrayList<StartupInfo>();
downloadxml.loadPage();
appContext = getApplicationContext();
ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setTitle(uniqeAppId);
ActionBar.Tab Frag1 = actionbar.newTab().setText(ChannelTab);
ActionBar.Tab Frag2 = actionbar.newTab().setText(VicinityTab);
ActionBar.Tab Frag3 = actionbar.newTab().setText(CustomTab);
ActionBar.Tab Frag4 = actionbar.newTab().setText(TrackingTab);
ActionBar.Tab Frag5 = actionbar.newTab().setText(MoreTab);
Fragment Fragment1 = new Channeltab();
Fragment Fragment2 = new Vicinitytab();
Fragment Fragment3 = new Customtab();
Fragment Fragment4 = new Trackingtab();
Fragment Fragment5 = new Moretab();
Frag1.setTabListener(new MyTabListener(Fragment1));
Frag2.setTabListener(new MyTabListener(Fragment2));
Frag3.setTabListener(new MyTabListener(Fragment3));
Frag4.setTabListener(new MyTabListener(Fragment4));
Frag5.setTabListener(new MyTabListener(Fragment5));
actionbar.addTab(Frag1);
actionbar.addTab(Frag2);
actionbar.addTab(Frag3);
actionbar.addTab(Frag4);
actionbar.addTab(Frag5);
}
public void GetTextForTabs(ArrayList<StartupInfo> info2) {
this.info = info2;
StartupInfo info3 = info.get(0);
this.ChannelTab = info3.getChannelTab();
this.VicinityTab = info3.getVicinityTab();
this.CustomTab = info3.getCustomTab();
this.TrackingTab = info3.getTrackingTab();
this.MoreTab = info3.getMoreTab();
}
#Override
public void onStart() {
super.onStart();
}
public void setInfo(ArrayList<StartupInfo> info) {
this.info = info;
}
public void alert(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
public class MyTabListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
}
Then the LogCat:
It seems to be the TabListener. But I don't understand why. It wasn't doing that earlier. It was when i tried to add data it started to crash. Can anyone help me here ?
You have a null pointer exception at line 111 of your activity (in onTabSelected). It looks as though the null reference is probably to "fragment". Look at the section on "Performing fragment transactions":
http://developer.android.com/guide/components/fragments.html
This code will not fit your program exactly, but it gives you the general idea. You need to begin, do your add/replace/why and then commit.
By the by, since you are using ActionBarSherlock why not use the Support library so as to be able to support older versions of Android ?
Here is a simple example (it contains some superfluous stuff that you don't need) that might help:
public class ExtraContent extends SherlockFragmentActivity {
// Declare Tab Variable
com.actionbarsherlock.app.ActionBar.Tab tab;
boolean mDebugLog = false;
String mDebugTag="ian_";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//mDebugLog = true;
debugLog("ExtraContent onCreate" );
// Create the actionbar
com.actionbarsherlock.app.ActionBar bar = getSupportActionBar();
// Show Actionbar Home Icon (as normal)
bar.setDisplayShowHomeEnabled(true);
// Show Actionbar Title (as normal)
bar.setDisplayShowTitleEnabled(true);
// Create Actionbar Tabs
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//enable home ...
bar.setDisplayHomeAsUpEnabled(true); // ?
bar.setHomeButtonEnabled(true); // this is the one that enables home navigation
//ib18 view for fragments ...
setContentView(R.layout.extra_content);
//create the fragment we want to use for display content
Fragment ExtraLogin = new ExtraLogIn();
// Create First Tab
ActionBar.Tab tab0 = bar.newTab();
tab0 = bar.newTab();
tab0.setText("Unlock");
tab0.setTabListener(new TabListener<ExtraTab0>(this, "tab0",ExtraTab0.class, null));
bar.addTab(tab0);
// Create Second Tab
ActionBar.Tab tab1 = bar.newTab();
tab1 = bar.newTab();
tab1.setText("Level 1");
tab1.setTabListener(new TabListener<ExtraTab1>(this, "tab1",ExtraTab1.class, null));
bar.addTab(tab1);
// Create Third Tab
ActionBar.Tab tab2 = bar.newTab();
tab2 = bar.newTab();
tab2.setText("Level 2");
tab2.setTabListener(new TabListener<ExtraTab2>(this, "tab2",ExtraTab2.class, null));
bar.addTab(tab2);
if (savedInstanceState != null) { //if there is a saved bundle use it ...
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
else {
//ib18 savedInstanceState null so fti so start Login frag ...
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.fb, ExtraLogin, "ExtraLogin").commit();
}
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
debugLog("ExtraContent onMenuItemSelected" );
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, QuizLaunch.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
debugLog("ExtraContent onSaveInstanceState");
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}
public class TabListener<T extends Fragment> implements ActionBar.TabListener{
private final FragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener (FragmentActivity activity, String tag, Class<T> clz,
Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
debugLog("ExtraContent TabListener" );
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
//
if (mFragment != null && !mFragment.isDetached()) {
ft.detach(mFragment);
}
ft.commit();
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
debugLog("ExtraContent onTabSelected");
ft = mActivity.getSupportFragmentManager()
.beginTransaction();
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(),mArgs);
debugLog("adding fragment "+mTag );
ft.add(R.id.tab, mFragment, mTag); //ib18 add to "tab" holder
ft.show(mFragment); //ib1.6 show fragment ...
ft.commit();
} else {
debugLog("attaching fragment "+mTag );
ft.attach(mFragment);
ft.show(mFragment); //ib1.6 show fragment ...
ft.commit();
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
debugLog("ExtraContent onTabUnSelected");
ft = mActivity.getSupportFragmentManager()
.beginTransaction();
if (mFragment != null) {
debugLog("hide and detach fragment "+mFragment );
ft.hide(mFragment); //ib1.6 hide fragment ...
ft.detach(mFragment);
ft.commitAllowingStateLoss();
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
debugLog("ExtraContent onTabReSelected");
}
}
void debugLog(String message) {
if (mDebugLog)
Log.d(mDebugTag, message);
}
}

Tab navigation in new HoloEverywhere not displays fragment after screen rotation

Yesterday I downloaded new HoloEverywhere library.
Currently, I have problem with tab navigation after screen rotation.
My Home Activity:
public class MainActivity extends Activity implements TabListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUpTabs();
}
private void setUpTabs() {
String[] titles = {
"First", "Second",
};
ActionBar supportActionBar = getSupportActionBar();
for (int i = 0; i < titles.length; i++) {
ActionBar.Tab tab = supportActionBar.newTab();
tab.setText(titles[i]);
tab.setTag(MyFragment.TAG);
tab.setTabListener(this);
supportActionBar.addTab(tab, false);
}
supportActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
supportActionBar.setSelectedNavigationItem(0);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
final String fragmentTag = tab.getTag().toString();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
if (fragment == null) {
fragment = new MyFragment();
fragmentTransaction.add(android.R.id.content, fragment, fragmentTag);
} else {
fragmentTransaction.attach(fragment);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag((String) tab.getTag());
if (fragment != null) {
fragmentTransaction.detach(fragment);
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
}
}
And my Fragment class.
public class MyFragment extends Fragment {
public static final String TAG = MyFragment.class.getCanonicalName();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = new View(getActivity());
view.setBackgroundColor(Color.BLACK);
return view;
}
}
When I rotate the screen fragment not displaying. It displays when i select tab (which is not currently selected) manually.
I just solve the problem.
I post my code here and see if those can help you :D
if (savedInstanceState == null){
TabHomeFragment homeFragment = new TabHomeFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, homeFragment, "home_fragment").commit();
}else{
TabHomeFragment homeFragment = (TabHomeFragment) getSupportFragmentManager().findFragmentByTag("home_fragment");
}
Those code are located in OnCreate method.
When the Device rotate and Ortiention change, the fragment will recreate again. So add a if clase to check if there is already one here.
But I am using normal Fragment in Android. Hope it can help you a little.

Sherlock, Fragments, Tabs and MapView

As i point in the headline I have implemented ActionBar Sherlock and Tab navigation inside. Tabs are fragments. Inside one Fragment I have a mapView. I have some problems when i change between tabs. Two tabs are just lists, inside one is MapView with some other views and one with some settings informations.
My problem is that when i change tabs i get some flickering... It's just long enough to catch it with an eye. This is when i move in regular tabs, but when i go to a mapview tab first i get a black screen that lasts a bit longer then a flickering.
Does somebody had some issues with this or some similar problems???
EDITED CODE:
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
//setContentView(R.layout.sherlock);
Log.i(TAG, "onCreate");
settings_drawable = new StateListDrawable();
settings_drawable.addState(new int [] {STATE_PRESSED}, getResources().getDrawable(R.drawable.jk_uma_button_settings_pressed));
settings_drawable.addState(new int[] {}, getResources().getDrawable(R.drawable.jk_uma_button_settings_normal));
home = new StateListDrawable();
home.addState(new int [] {STATE_PRESSED}, getResources().getDrawable(R.drawable.jk_button_home_pressed));
home.addState(new int[] {}, getResources().getDrawable(R.drawable.jk_button_home_normal));
bar = getSupportActionBar();
bar.setDisplayShowTitleEnabled(false);
bar.setIcon(R.drawable.jk_uma_logo);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setHomeButtonEnabled(true);
tabs_adapter = new TabAdapter(this);
tabs_adapter.addTab(bar.newTab().setText(" Home").setIcon(R.drawable.jk_icon_home), "Tab1", MapHome.class, null);
tabs_adapter.addTab(bar.newTab().setText(" Explore").setIcon(R.drawable.jk_icon_explore), "Tab2", MapExplore.class, null);
tabs_adapter.addTab(bar.newTab().setText(" My Views").setIcon(R.drawable.jk_icon_myview), "Tab3", MapMyStreams.class, null);
}
public static class TabAdapter implements ActionBar.TabListener {
private final Context context;
private final ActionBar action_bar;
private final HashMap<String, TabInfo> tabs = new HashMap<String, TabInfo>();
private TabInfo last_tab = null;
private TabInfo camera_info;
private String current_camera_tab;
private String current_fragment_tab;
private class TabInfo {
private String tag;
private Class clss;
private Bundle args;
private Fragment fragment;
private Fragment fragment_details;
private String current_fragment;
TabInfo(String tag, Class clazz, Bundle args, String curent) {
this.tag = tag;
this.clss = clazz;
this.args = args;
this.current_fragment = curent;
}
}
public TabAdapter(SherlockFragmentActivity activity) {
super();
this.context = activity;
this.action_bar = activity.getSupportActionBar();
}
public void addTab(ActionBar.Tab tab, String tag, Class<?> clss, Bundle args){
Log.i(((Sherlock)context).TAG, "addTab");
TabInfo info = new TabInfo(tag, clss, args, "1");
tab.setTag(tag);
tab.setTabListener(this);
tabs.put(tag, info);
action_bar.addTab(tab);
}
Handler h = new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switchTab(String.valueOf(msg.obj));
}
};
public void changeOnRuntime(String camera_no){
Log.i("TABS ADAPTER", "=================changeOnRuntime========="+camera_no);
Bundle args = new Bundle();
args.putString("camera_no", camera_no);
FragmentTransaction ft = ((Sherlock)context).getSupportFragmentManager().beginTransaction();
String tag = (String) action_bar.getSelectedTab().getTag();
TabInfo tab = tabs.get(tag);
Fragment fragm = MapCamera.newInstance(camera_no);
tab.fragment_details = fragm;
tab.current_fragment = "2";
ft.hide(tab.fragment);
ft.add(android.R.id.content, tab.fragment_details, "Tab5");
ft.commit();
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.i("TAB SELECTED", "===================NOT NULL=============="+ ft);
if(ft == null){
Log.i("TAB SELECTED", "===================NULLLLLLLLLLLL==============");
}
String tag = (String) tab.getTag();
TabInfo newTab = (TabInfo) this.tabs.get(tag);
if (last_tab != newTab) {
if (newTab != null) {
Log.i("TAB SELECTED", "===================NEW TAB==============");
if(newTab.current_fragment.equalsIgnoreCase("1")){
Log.i("TAB SELECTED", "===================NEW TAB 1==============");
if (newTab.fragment == null) {
Log.i("TAB SELECTED", "===================NEW TAB 1 NULL==============");
newTab.fragment = Fragment.instantiate(context,
newTab.clss.getName(), newTab.args);
ft.add(android.R.id.content, newTab.fragment, newTab.tag);
}else {
Log.i("TAB SELECTED", "===================NEW TAB 1 NOT NULL==============");
ft.attach(newTab.fragment);
}
}else{
Log.i("TAB SELECTED", "===================NEW TAB 2==============");
ft.attach(newTab.fragment_details);
}
}
last_tab = newTab;
}
}
}
public void switchTab(String tab){
if(tab.equalsIgnoreCase("Tab1")){
action_bar.setSelectedNavigationItem(0);
}else if (tab.equalsIgnoreCase("Tab2")) {
action_bar.setSelectedNavigationItem(1);
}else if (tab.equalsIgnoreCase("Tab4")) {
action_bar.setSelectedNavigationItem(3);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.i("TAB SELECTED", "=================== 2222 ==============");
if (last_tab != null) {
if (last_tab.fragment != null) {
if(last_tab.current_fragment.equalsIgnoreCase("1")){
Log.i("TAB SELECTED", "=================== detach 1 ==============");
ft.detach(last_tab.fragment);
}else{
Log.i("TAB SELECTED", "=================== detach 2 ==============");
ft.detach(last_tab.fragment_details);
}
}
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
The "black view" that it sounds like you're describing is a know issue when switching between fragments, one of which is a v2 map. You can read more about it in this post. I have encountered this issue myself. The solution proposed in the cited post is very simple.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
<!-- hack to fix ugly black artefact with maps v2 -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent" />
</FrameLayout>
Adding a view over the black view that is transparent removes the issue. Not sure why but it does.

how to set up ListFragment properly?

I try to create tabs with ListFragment in it. I've tried several different appoaches but neither of them works. I don't know how to set container for ListFragment obkect properly.
Here is java code.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabOne = actionBar.newTab().setText("ONE");
ActionBar.Tab tabTwo = actionBar.newTab().setText("TWO");
tabParkCinema.setTabListener(new tabListener());
tab28Cinema.setTabListener(new tabListener());
actionBar.addTab(tabOne);
actionBar.addTab(tabTwo);
}
protected class tabListener implements ActionBar.TabListener {
ParkFragment firstFragment;
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()){
case 0:
if (firstFragment == null){
firstFragment = new ParkFragment();
System.out.println("initialized");
ft.add(R.id.cont, firstFragment,"FIRST");
}
else{
ft.attach(firstFragment);
}
break;
case 1:
if (firstFragment == null){
firstFragment = new ParkFragment();
ft.add(R.id.cont,firstFragment,"SECOND");
}
else{
ft.attach(firstFragment);
}
break;
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
};
public class ParkFragment extends ListFragment {
private ArrayList<Cinemas> cinema;
private CinemasAdapter cinemaAdapter;
private View v;
//private ListView list;
#Override
public View onCreateView(LayoutInflater in, ViewGroup gr, Bundle savedInstanceState) {
v = in.inflate(R.id.listing1, gr,false);
super.onActivityCreated(savedInstanceState);
cinema = new Handler().handle();
cinemaAdapter = new CinemasAdapter(MainActivity.this, R.layout.movie_data_row, cinema);
setListAdapter(cinemaAdapter);
return gr;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Cinemas movie = cinemaAdapter.getItem(position);
Intent intent = new Intent (MainActivity.this, More.class);
intent.putExtra("Cinemas", movie);
intent.putExtra("data", movie.getBitmap());
Bundle translateBundle =
ActivityOptions.makeCustomAnimation(MainActivity.this,
R.anim.slide_in_left, R.anim.slide_out_left).toBundle();
startActivity (intent, translateBundle);
}
}
}
And activity_main.XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cont"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id = "#+id/listing1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
Thank you for reading, any help will be appreciated!
1) Create a FragmentManager object.
2) Use method beginTransaction() on this object to create a FragmentTransaction object.
3) Add fragment with the method add(int containerViewId, Fragment fragment, String tag) on the FragmentTransaction object.
In this method, you put a reference to the id of the container, a new ListFragment (or the class you have writen) and a tag (to easily get a reference to the ListFragment if needed).
Note that you have to change your xml layout. You can add a FrameLayout with an id. And then, give this id to the method add() of your FragmentTransaction object.
EDIT
Example of code:
public class ContentActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
//your action bar stuff
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.parkfragment, new ParkFragment(), "locations");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.commit();
}
public class ParkFragment extends ListFragment {
//your methods
}
protected class tabListener implements ActionBar.TabListener {
//your methods
}
}
Your xml would look like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/parkfragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

Categories

Resources