The issue appears to be that fragments seem to load in a very strange way in RARE occurrences.
Sometimes the view of a Fragment is NOT visible, onCreateView is called, but it does NOT add the view to the activity, it just loads a blank white page. When onResume is called from resuming the app (such as going to recent applications and clicking my app) the view appears.
ALL fragment transactions are done on the MAIN thread obviously.
This happens approx 1 in every 20 times.
I am happy to supply ANY code you want. So if something is missing then please let me know and I will happily supply it for you
My onCreate in my activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Variables.context = this;
Variables.activity = this;
Variables.p_class = HomeActivity.class;
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
toolbar.setNavigationIcon(null);
toolbar.getMenu().clear();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
actionbar_pw_spinner = (ProgressWheel) findViewById(R.id.actionbar_pw_spinner);
actionbar_pw_mins = (TextView) findViewById(R.id.actionbar_pw_mins);
actionBarTitleTV = (TextView) findViewById(R.id.custom_actionbar_title);
usersName = (TextView) findViewById(R.id.usersName);
usersEmail = (TextView) findViewById(R.id.usersEmail);
actionBarTitleTV.setText(this.getTitle());
btnBack = (ImageView) findViewById(R.id.button_back);
btnBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
btnBack.setVisibility(View.GONE);
btnMenu = (ImageView) findViewById(R.id.button_menu);
btnMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDrawer();
}
});
btnMenu.setVisibility(View.GONE);
setPersonInfo();
Fabric.with(this, new Crashlytics());
Variables.myLocation = new Location("myLoc");
Variables.myLocation.setLatitude(0.0);
Variables.myLocation.setLongitude(0.0);
if (!Variables.isThisBidTaxi()) {
CustomerComms.myOwnSocket = new MySocket(null);
CustomerComms.myOwnSocket.start();
}
SettingSQLHelper helper = new SettingSQLHelper(HomeActivity.this);
Variables.setting = helper.getSetting();
helper.close();
mRequestingLocationUpdates = false;
buildGoogleApiClient();
createLocationRequest();
buildLocationSettingsRequest();
checkLocationSettings();
setTitle("");
if (savedInstanceState != null) {
return;
} else {
getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, new SplashFragment()).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
}
containLayout = null;
containLayout = (FrameLayout) findViewById(R.id.fragmentspace);
getSupportFragmentManager().addOnBackStackChangedListener(getListener());
m_updateBooking = (Booking) getIntent().getSerializableExtra("booking");
m_TrackDriver = (Boolean) getIntent().getSerializableExtra("track");
Variables.initBooking();
}
My onResume in my activity:
protected void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
Variables.context = this;
Variables.activity = this;
if (m_updateBooking != null) {
if (m_updateBooking.getJobStatus() == Booking.eeJob_Complete) {
if (!Variables.driverrated) {
DriverRatingFragment DriverRatingFRA = DriverRatingFragment.newInstance(m_updateBooking);
getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, DriverRatingFRA).addToBackStack(DriverRatingFragment.class.getName()).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
}
} else {
if (m_TrackDriver) {
getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, TrackingDriverFragment.newInstance(m_updateBooking)).addToBackStack(TrackingDriverFragment.class.getName()).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
} else {
gotoMyBooking(m_updateBooking);
}
}
}
m_updateBooking = null;
getIntent().removeExtra("booking");
getIntent().removeExtra("track");
if (Variables.setting == null) {
final SettingSQLHelper helper = new SettingSQLHelper(HomeActivity.this);
Variables.setting = helper.getSetting();
}
}
My onPause
@Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
My onCreateView inside a fragment looks like this:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflatedView = inflater.inflate(R.layout.fragment_new_booking, container, false);//the rest of my code then follows here
return inflaterview
}
My activity XML file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ProgressWheel="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".Activity.HomeActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true">
<TextView
android:id="@+id/custom_actionbar_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:singleLine="true"
android:text="@string/new_booking"
android:textColor="@color/White"
android:textSize="18sp" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/button_back"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical|start"
android:contentDescription="@string/back_button"
android:fitsSystemWindows="true"
android:src="@drawable/ic_arrow_back_white_24dp" />
<ImageView
android:id="@+id/button_menu"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical|start"
android:contentDescription="@string/menu_button"
android:fitsSystemWindows="true"
android:src="@drawable/ic_menu_white_24dp" />
</FrameLayout>
<com.todddavies.components.progressbar.ProgressWheel
android:id="@+id/actionbar_pw_spinner"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="top|end"
android:layout_marginRight="10dp"
android:visibility="gone"
ProgressWheel:barColor="#86f066"
ProgressWheel:barLength="10dp"
ProgressWheel:barWidth="1dp"
ProgressWheel:rimColor="@color/White"
ProgressWheel:rimWidth="2dp"
ProgressWheel:textColor="@color/White"
ProgressWheel:textSize="15sp" />
<TextView
android:id="@+id/actionbar_pw_mins"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="15dp"
android:layout_marginTop="27dp"
android:text="@string/mins"
android:textColor="@color/White"
android:textSize="10sp"
android:visibility="gone" />
</FrameLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/fragmentspace"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/White" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
My Android Manifest looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.commandsoftware.androidbookingapp"
android:installLocation="auto">
<uses-permission android:name="com.chasesoftware.cabmaster.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">>
<activity
android:name=".Activity.HomeActivity"
android:label="@string/app_name"
android:noHistory="false"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_api" />
<receiver android:name=".Activity.SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<meta-data
android:name="io.fabric.ApiKey"
android:value="@string/fabric_key" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="@string/facebook_api"
android:exported="false" />
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
</manifest>
When I commit a Fragment transaction my code looks like this:
((HomeActivity) Variables.context).getSupportFragmentManager().beginTransaction().remove(((HomeActivity) Variables.context).getSupportFragmentManager().findFragmentById(R.id.fragmentspace)).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
((HomeActivity) Variables.context).getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, new MyBidsFragment().newInstance(booking)).addToBackStack(MyBidsFragment.class.getName()).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
Another example of Fragment Transaction
myBookingsFragment = MyBookingsFragment.newInstance(updateBooking);
getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, myBookingsFragment).addToBackStack(myBookingsFragment.getClass().getName()).commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
答案 0 :(得分:2)
我从:
开始替换:
((HomeActivity) Variables.context).getSupportFragmentManager().beginTransaction().remove(((HomeActivity) Variables.context).getSupportFragmentManager().findFragmentById(R.id.fragmentspace)).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
((HomeActivity) Variables.context).getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, new MyBidsFragment().newInstance(booking)).addToBackStack(MyBidsFragment.class.getName()).commitAllowingStateLoss();
((HomeActivity) Variables.context).getSupportFragmentManager().executePendingTransactions();
与
((HomeActivity) getActivity()).getSupportFragmentManager().
beginTransaction().
replace(R.id.fragmentspace, new MyBidsFragment().newInstance(booking)).
commit();
(顺便说一下,make newInstance()
static
,所以你不会对MyBidsFragment
的新实例进行奇怪的初始化
然后替换
myBookingsFragment = MyBookingsFragment.newInstance(updateBooking);
getSupportFragmentManager().beginTransaction().add(R.id.fragmentspace, myBookingsFragment).addToBackStack(myBookingsFragment.getClass().getName()).commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
与
myBookingsFragment = MyBookingsFragment.newInstance(updateBooking);
getSupportFragmentManager().beginTransaction().
replace(R.id.fragmentspace, myBookingsFragment).
addToBackStack(myBookingsFragment.getClass().getName()).
commit();
replace()
,而不是add()
然后我会做一些事实,即Activity有1000行代码。它使代码更难维护和理解(+甚至在SO上发布)
我希望,这有帮助