Fragment changes to blanck fragment after destroy
When I start my activity by the first time everything is fine I can navigate normally but after rotating the screen the fragmentMananger appears to bug, and after every change of fragment it loads a blank fragment if I rotate the screen and the activity is recreated the correct fragment appears but the bug persists.
when I quit the app and back to use it the error persists and only disappears after clear the user data, I try to recreate the activity after every fragment change but it only turn things worst.
the one thing solve the problem is to clear user data after every app finalization but it erases important data managed by the app at runtime that need persist via file for the next execution.
I use a companion object for manage fragment names:
companion object
val TAG = this::class.java.canonicalName!!
const val MAIN_FRAGMENT = "MainFragment"
const val SECOND_FRAGMENT = "SecondFragment"
const val THIRD_FRAGMENT = "ThirdFragment"
const val FOURTH_FRAGMENT = "FourthFragment"
const val FIFTH_FRAGMENT = "FifthFragment"
functions for manage fragments:
fun callFragment(s: String? = null)
validateFrag(s ?: MAIN_FRAGMENT, ::setFragment)
fun updateFragment()
Control.logData("updating fragment $fragment_state")
validateFrag(fragment_state, ::setFragment)
private fun validateFrag(s: String, f: (String) -> Unit)
when (s)
SECOND_FRAGMENT -> f(s)
THIRD_FRAGMENT -> f(s)
FOURTH_FRAGMENT -> f(s)
FIFTH_FRAGMENT -> f(s)
else -> f(MAIN_FRAGMENT)
private fun createFrag(id: String): Fragment = when (id)
SECOND_FRAGMENT -> SecondFragment.newInstance()
THIRD_FRAGMENT -> ThirdFragment.newInstance()
FOURTH_FRAGMENT -> FourthFragment.newInstance()
FIFTH_FRAGMENT -> FifthFragment.newInstance(this)
else -> MainFragment.newInstance()
private fun setFragment(id: String)
val userAuth = userAuth
userAuth ?: return
Control.logData("loading fragment $id")
val frame = R.id.app_frame
val fragment = (fragmentManager.findFragmentByTag(id) ?: createFrag(id))
currentFragment = fragment as MyAppFragment
fragment_state = id
when
fragmentManager.fragments.size == 0 ->
fragmentManager.beginTransaction()
.add(frame, createFrag(MAIN_FRAGMENT), MAIN_FRAGMENT)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
!fragmentManager.fragments.contains(fragment as Fragment) ->
fragmentManager.beginTransaction()
.add(frame, fragment, id)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
else ->
with(fragmentManager.beginTransaction())
replace(frame, fragment, id)
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
commitNowAllowingStateLoss()
for the commits I try Commit(), CommitNow() too
my fragment implementation:
package com.domain.app.fragments
import android.content.Context
import android.support.v4.app.Fragment
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ScrollView
import com.reactivex.disposables.Disposable
import com.domain.app.Control
import com.domain.app.R
import com.domain.app.AppApplicatcomn
import com.domain.app.activities.appActivity
import com.domain.app.dagger.services.IRXService
import com.domain.app.recycler.adapter.DataListAdapter
import kotlinx.android.synthetic.main.fragment_main.*
import javax.inject.Inject
class MainFragment : Fragment(), AppFragment
// instanciate data
compancomn object
fun newInstance(): MainFragment
return MainFragment()
override fun onAttach(context: Context?)
super.onAttach(context)
activity?.let act ->
//subscribe RX
override fun onDetach()
super.onDetach()
//disposeRX
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View?
return inflater.inflate(R.layout.fragment_main, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
dockInit()
recyclerInit()
if(Control.index.isEmpty())
noDataScreen()
else
Control.putOnScreen()
override fun noDataScreen()
activity?.runOnUiThread
main_noDataQrButton?.visibility = View.VISIBLE
main_noDataText?.visibility = View.VISIBLE
Control.loadingDataStream.onNext(false)
isInit = false
override fun notifyRecycler()
activity?.runOnUiThread
if(::list.isInitialized)
mAdapter.update()
list.adapter?.notifyDataSetChanged()
private fun recyclerInit()
mAdapter = DataListAdapter(activity as appActivity)
mAdapter.setHasStableIds(true)
list = view!!.findViewById<RecyclerView>(R.id.main_listDataListRecycler).apply
setHasFixedSize(true)
setItemViewCacheSize(8)
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.domain.app">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".AppApplication"
android:allowBackup="true"
android:icon="@drawable/app"
android:label="@string/app_name"
android:roundIcon="@drawable/app_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"
android:allowClearUserData="true"
android:fullBackupContent="@xml/backup_descriptor">
<!-- android:theme="@style/AppTheme" -->
<activity
android:name=".activities.AppActivity"
android:screenOrientation="portrait"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<!-- para ser aberto com action APP -->
<action android:name="android.intent.action.APP" />
<action android:name="android.intent.action.MAIN" />
<action android:name="io.ubivis.digitalmobility.action.CONSUME_APP_NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="app.domain.io"
android:scheme="https" />
</intent-filter>
</activity>
<service android:name=".services.FirebaseMessageService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".services.FirebaseTokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_logo_app_60dp" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorPrimary" />
<!-- Para Android 8 - Necessário um canal para notificações -->
<!-- <meta-data -->
<!-- android:name="com.google.firebase.messaging.default_notification_channel_id" -->
<!-- android:value="@string/default_notification_channel_id"/> -->
</application>
my activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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.support.v7.widget.CardView
android:id="@+id/app_connectionCard"
android:layout_width="match_parent"
android:layout_height="40dp"
android:visibility="gone"
app:cardBackgroundColor="@android:color/holo_red_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_toolbar">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connectionFail"
android:textColor="@color/cardview_light_background"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.Toolbar
android:id="@+id/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ubivis_background_blue"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/app_drawer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_connectionCard"
tools:openDrawer="start">
<FrameLayout
android:id="@+id/app_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/app_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorPrimaryDark"
android:fitsSystemWindows="true"
android:theme="@style/UbivisDrawerTheme"
app:headerLayout="@layout/nav_header_app"
app:itemIconTint="@color/ubivis_orange"
app:menu="@menu/activity_app_drawer" />
</android.support.v4.widget.DrawerLayout>
fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:theme="@style/AppTheme.NoActionBar"
tools:context=".fragments.MainFragment">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="false"
android:cropToPadding="false"
android:scaleType="fitEnd"
android:tint="@color/background"
android:translationX="128dp"
android:translationY="128dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/logo_domain_vasado" />
<android.support.v7.widget.RecyclerView
android:id="@+id/main_listDataListRecycler"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="@+id/main_noDataText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="@string/noDataMessage"
android:textAlignment="center"
android:textSize="30sp"
android:textStyle="bold"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/main_noDataQrButton"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/main_noDataQrButton"
android:layout_width="220dp"
android:layout_height="220dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp"
android:background="@drawable/shape_qr_code_frame"
android:elevation="16dp"
android:onClick="qrScan"
android:theme="@style/AppTheme"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="@+id/main_listDataListRecycler"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="OnClick" />
for the activity lifecycle:
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Control.logData("creating activity")
setContentView(R.layout.activity_app)
// keep screen alive
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
// set toolbar
setSupportActionBar(findViewById(R.id.app_toolbar))
supportActionBar?.title = getString(R.string.Datas)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
isWaitingResult = savedInstanceState?.getBoolean(isWaitingResultCode) ?: false
savedInstanceState?.let
fragment_state = savedInstanceState.getString(fragState) ?: fragment_state
userAuth = savedInstanceState.getSerializable(userAuthCode) as? UserAuthentication?
val DataMenu = findViewById<NavigationView>(R.id.app_navigation)
.menu.findItem(R.id.DataButton)
DataMenu?.isChecked = true
if (!Control.filters) filterMenu?.icon = drawable(R.drawable.filter_inactive)
//injection
if (!isInjected)
onInject()
override fun onStop()
super.onStop()
Control.logData("stopping activity")
fragmentManager.executePendingTransactions()
Control.mainRunning = false
loop = false
saveFav()
override fun onDestroy()
super.onDestroy()
Control.logData("destroying activity")
Control.rx.forEach it.dismiss()
Control.rx.clear()
Control is a object with some function and data commonly used across the App
android android-fragments kotlin
add a comment |
When I start my activity by the first time everything is fine I can navigate normally but after rotating the screen the fragmentMananger appears to bug, and after every change of fragment it loads a blank fragment if I rotate the screen and the activity is recreated the correct fragment appears but the bug persists.
when I quit the app and back to use it the error persists and only disappears after clear the user data, I try to recreate the activity after every fragment change but it only turn things worst.
the one thing solve the problem is to clear user data after every app finalization but it erases important data managed by the app at runtime that need persist via file for the next execution.
I use a companion object for manage fragment names:
companion object
val TAG = this::class.java.canonicalName!!
const val MAIN_FRAGMENT = "MainFragment"
const val SECOND_FRAGMENT = "SecondFragment"
const val THIRD_FRAGMENT = "ThirdFragment"
const val FOURTH_FRAGMENT = "FourthFragment"
const val FIFTH_FRAGMENT = "FifthFragment"
functions for manage fragments:
fun callFragment(s: String? = null)
validateFrag(s ?: MAIN_FRAGMENT, ::setFragment)
fun updateFragment()
Control.logData("updating fragment $fragment_state")
validateFrag(fragment_state, ::setFragment)
private fun validateFrag(s: String, f: (String) -> Unit)
when (s)
SECOND_FRAGMENT -> f(s)
THIRD_FRAGMENT -> f(s)
FOURTH_FRAGMENT -> f(s)
FIFTH_FRAGMENT -> f(s)
else -> f(MAIN_FRAGMENT)
private fun createFrag(id: String): Fragment = when (id)
SECOND_FRAGMENT -> SecondFragment.newInstance()
THIRD_FRAGMENT -> ThirdFragment.newInstance()
FOURTH_FRAGMENT -> FourthFragment.newInstance()
FIFTH_FRAGMENT -> FifthFragment.newInstance(this)
else -> MainFragment.newInstance()
private fun setFragment(id: String)
val userAuth = userAuth
userAuth ?: return
Control.logData("loading fragment $id")
val frame = R.id.app_frame
val fragment = (fragmentManager.findFragmentByTag(id) ?: createFrag(id))
currentFragment = fragment as MyAppFragment
fragment_state = id
when
fragmentManager.fragments.size == 0 ->
fragmentManager.beginTransaction()
.add(frame, createFrag(MAIN_FRAGMENT), MAIN_FRAGMENT)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
!fragmentManager.fragments.contains(fragment as Fragment) ->
fragmentManager.beginTransaction()
.add(frame, fragment, id)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
else ->
with(fragmentManager.beginTransaction())
replace(frame, fragment, id)
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
commitNowAllowingStateLoss()
for the commits I try Commit(), CommitNow() too
my fragment implementation:
package com.domain.app.fragments
import android.content.Context
import android.support.v4.app.Fragment
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ScrollView
import com.reactivex.disposables.Disposable
import com.domain.app.Control
import com.domain.app.R
import com.domain.app.AppApplicatcomn
import com.domain.app.activities.appActivity
import com.domain.app.dagger.services.IRXService
import com.domain.app.recycler.adapter.DataListAdapter
import kotlinx.android.synthetic.main.fragment_main.*
import javax.inject.Inject
class MainFragment : Fragment(), AppFragment
// instanciate data
compancomn object
fun newInstance(): MainFragment
return MainFragment()
override fun onAttach(context: Context?)
super.onAttach(context)
activity?.let act ->
//subscribe RX
override fun onDetach()
super.onDetach()
//disposeRX
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View?
return inflater.inflate(R.layout.fragment_main, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
dockInit()
recyclerInit()
if(Control.index.isEmpty())
noDataScreen()
else
Control.putOnScreen()
override fun noDataScreen()
activity?.runOnUiThread
main_noDataQrButton?.visibility = View.VISIBLE
main_noDataText?.visibility = View.VISIBLE
Control.loadingDataStream.onNext(false)
isInit = false
override fun notifyRecycler()
activity?.runOnUiThread
if(::list.isInitialized)
mAdapter.update()
list.adapter?.notifyDataSetChanged()
private fun recyclerInit()
mAdapter = DataListAdapter(activity as appActivity)
mAdapter.setHasStableIds(true)
list = view!!.findViewById<RecyclerView>(R.id.main_listDataListRecycler).apply
setHasFixedSize(true)
setItemViewCacheSize(8)
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.domain.app">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".AppApplication"
android:allowBackup="true"
android:icon="@drawable/app"
android:label="@string/app_name"
android:roundIcon="@drawable/app_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"
android:allowClearUserData="true"
android:fullBackupContent="@xml/backup_descriptor">
<!-- android:theme="@style/AppTheme" -->
<activity
android:name=".activities.AppActivity"
android:screenOrientation="portrait"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<!-- para ser aberto com action APP -->
<action android:name="android.intent.action.APP" />
<action android:name="android.intent.action.MAIN" />
<action android:name="io.ubivis.digitalmobility.action.CONSUME_APP_NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="app.domain.io"
android:scheme="https" />
</intent-filter>
</activity>
<service android:name=".services.FirebaseMessageService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".services.FirebaseTokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_logo_app_60dp" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorPrimary" />
<!-- Para Android 8 - Necessário um canal para notificações -->
<!-- <meta-data -->
<!-- android:name="com.google.firebase.messaging.default_notification_channel_id" -->
<!-- android:value="@string/default_notification_channel_id"/> -->
</application>
my activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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.support.v7.widget.CardView
android:id="@+id/app_connectionCard"
android:layout_width="match_parent"
android:layout_height="40dp"
android:visibility="gone"
app:cardBackgroundColor="@android:color/holo_red_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_toolbar">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connectionFail"
android:textColor="@color/cardview_light_background"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.Toolbar
android:id="@+id/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ubivis_background_blue"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/app_drawer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_connectionCard"
tools:openDrawer="start">
<FrameLayout
android:id="@+id/app_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/app_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorPrimaryDark"
android:fitsSystemWindows="true"
android:theme="@style/UbivisDrawerTheme"
app:headerLayout="@layout/nav_header_app"
app:itemIconTint="@color/ubivis_orange"
app:menu="@menu/activity_app_drawer" />
</android.support.v4.widget.DrawerLayout>
fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:theme="@style/AppTheme.NoActionBar"
tools:context=".fragments.MainFragment">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="false"
android:cropToPadding="false"
android:scaleType="fitEnd"
android:tint="@color/background"
android:translationX="128dp"
android:translationY="128dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/logo_domain_vasado" />
<android.support.v7.widget.RecyclerView
android:id="@+id/main_listDataListRecycler"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="@+id/main_noDataText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="@string/noDataMessage"
android:textAlignment="center"
android:textSize="30sp"
android:textStyle="bold"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/main_noDataQrButton"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/main_noDataQrButton"
android:layout_width="220dp"
android:layout_height="220dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp"
android:background="@drawable/shape_qr_code_frame"
android:elevation="16dp"
android:onClick="qrScan"
android:theme="@style/AppTheme"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="@+id/main_listDataListRecycler"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="OnClick" />
for the activity lifecycle:
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Control.logData("creating activity")
setContentView(R.layout.activity_app)
// keep screen alive
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
// set toolbar
setSupportActionBar(findViewById(R.id.app_toolbar))
supportActionBar?.title = getString(R.string.Datas)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
isWaitingResult = savedInstanceState?.getBoolean(isWaitingResultCode) ?: false
savedInstanceState?.let
fragment_state = savedInstanceState.getString(fragState) ?: fragment_state
userAuth = savedInstanceState.getSerializable(userAuthCode) as? UserAuthentication?
val DataMenu = findViewById<NavigationView>(R.id.app_navigation)
.menu.findItem(R.id.DataButton)
DataMenu?.isChecked = true
if (!Control.filters) filterMenu?.icon = drawable(R.drawable.filter_inactive)
//injection
if (!isInjected)
onInject()
override fun onStop()
super.onStop()
Control.logData("stopping activity")
fragmentManager.executePendingTransactions()
Control.mainRunning = false
loop = false
saveFav()
override fun onDestroy()
super.onDestroy()
Control.logData("destroying activity")
Control.rx.forEach it.dismiss()
Control.rx.clear()
Control is a object with some function and data commonly used across the App
android android-fragments kotlin
add a comment |
When I start my activity by the first time everything is fine I can navigate normally but after rotating the screen the fragmentMananger appears to bug, and after every change of fragment it loads a blank fragment if I rotate the screen and the activity is recreated the correct fragment appears but the bug persists.
when I quit the app and back to use it the error persists and only disappears after clear the user data, I try to recreate the activity after every fragment change but it only turn things worst.
the one thing solve the problem is to clear user data after every app finalization but it erases important data managed by the app at runtime that need persist via file for the next execution.
I use a companion object for manage fragment names:
companion object
val TAG = this::class.java.canonicalName!!
const val MAIN_FRAGMENT = "MainFragment"
const val SECOND_FRAGMENT = "SecondFragment"
const val THIRD_FRAGMENT = "ThirdFragment"
const val FOURTH_FRAGMENT = "FourthFragment"
const val FIFTH_FRAGMENT = "FifthFragment"
functions for manage fragments:
fun callFragment(s: String? = null)
validateFrag(s ?: MAIN_FRAGMENT, ::setFragment)
fun updateFragment()
Control.logData("updating fragment $fragment_state")
validateFrag(fragment_state, ::setFragment)
private fun validateFrag(s: String, f: (String) -> Unit)
when (s)
SECOND_FRAGMENT -> f(s)
THIRD_FRAGMENT -> f(s)
FOURTH_FRAGMENT -> f(s)
FIFTH_FRAGMENT -> f(s)
else -> f(MAIN_FRAGMENT)
private fun createFrag(id: String): Fragment = when (id)
SECOND_FRAGMENT -> SecondFragment.newInstance()
THIRD_FRAGMENT -> ThirdFragment.newInstance()
FOURTH_FRAGMENT -> FourthFragment.newInstance()
FIFTH_FRAGMENT -> FifthFragment.newInstance(this)
else -> MainFragment.newInstance()
private fun setFragment(id: String)
val userAuth = userAuth
userAuth ?: return
Control.logData("loading fragment $id")
val frame = R.id.app_frame
val fragment = (fragmentManager.findFragmentByTag(id) ?: createFrag(id))
currentFragment = fragment as MyAppFragment
fragment_state = id
when
fragmentManager.fragments.size == 0 ->
fragmentManager.beginTransaction()
.add(frame, createFrag(MAIN_FRAGMENT), MAIN_FRAGMENT)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
!fragmentManager.fragments.contains(fragment as Fragment) ->
fragmentManager.beginTransaction()
.add(frame, fragment, id)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
else ->
with(fragmentManager.beginTransaction())
replace(frame, fragment, id)
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
commitNowAllowingStateLoss()
for the commits I try Commit(), CommitNow() too
my fragment implementation:
package com.domain.app.fragments
import android.content.Context
import android.support.v4.app.Fragment
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ScrollView
import com.reactivex.disposables.Disposable
import com.domain.app.Control
import com.domain.app.R
import com.domain.app.AppApplicatcomn
import com.domain.app.activities.appActivity
import com.domain.app.dagger.services.IRXService
import com.domain.app.recycler.adapter.DataListAdapter
import kotlinx.android.synthetic.main.fragment_main.*
import javax.inject.Inject
class MainFragment : Fragment(), AppFragment
// instanciate data
compancomn object
fun newInstance(): MainFragment
return MainFragment()
override fun onAttach(context: Context?)
super.onAttach(context)
activity?.let act ->
//subscribe RX
override fun onDetach()
super.onDetach()
//disposeRX
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View?
return inflater.inflate(R.layout.fragment_main, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
dockInit()
recyclerInit()
if(Control.index.isEmpty())
noDataScreen()
else
Control.putOnScreen()
override fun noDataScreen()
activity?.runOnUiThread
main_noDataQrButton?.visibility = View.VISIBLE
main_noDataText?.visibility = View.VISIBLE
Control.loadingDataStream.onNext(false)
isInit = false
override fun notifyRecycler()
activity?.runOnUiThread
if(::list.isInitialized)
mAdapter.update()
list.adapter?.notifyDataSetChanged()
private fun recyclerInit()
mAdapter = DataListAdapter(activity as appActivity)
mAdapter.setHasStableIds(true)
list = view!!.findViewById<RecyclerView>(R.id.main_listDataListRecycler).apply
setHasFixedSize(true)
setItemViewCacheSize(8)
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.domain.app">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".AppApplication"
android:allowBackup="true"
android:icon="@drawable/app"
android:label="@string/app_name"
android:roundIcon="@drawable/app_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"
android:allowClearUserData="true"
android:fullBackupContent="@xml/backup_descriptor">
<!-- android:theme="@style/AppTheme" -->
<activity
android:name=".activities.AppActivity"
android:screenOrientation="portrait"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<!-- para ser aberto com action APP -->
<action android:name="android.intent.action.APP" />
<action android:name="android.intent.action.MAIN" />
<action android:name="io.ubivis.digitalmobility.action.CONSUME_APP_NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="app.domain.io"
android:scheme="https" />
</intent-filter>
</activity>
<service android:name=".services.FirebaseMessageService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".services.FirebaseTokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_logo_app_60dp" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorPrimary" />
<!-- Para Android 8 - Necessário um canal para notificações -->
<!-- <meta-data -->
<!-- android:name="com.google.firebase.messaging.default_notification_channel_id" -->
<!-- android:value="@string/default_notification_channel_id"/> -->
</application>
my activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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.support.v7.widget.CardView
android:id="@+id/app_connectionCard"
android:layout_width="match_parent"
android:layout_height="40dp"
android:visibility="gone"
app:cardBackgroundColor="@android:color/holo_red_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_toolbar">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connectionFail"
android:textColor="@color/cardview_light_background"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.Toolbar
android:id="@+id/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ubivis_background_blue"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/app_drawer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_connectionCard"
tools:openDrawer="start">
<FrameLayout
android:id="@+id/app_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/app_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorPrimaryDark"
android:fitsSystemWindows="true"
android:theme="@style/UbivisDrawerTheme"
app:headerLayout="@layout/nav_header_app"
app:itemIconTint="@color/ubivis_orange"
app:menu="@menu/activity_app_drawer" />
</android.support.v4.widget.DrawerLayout>
fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:theme="@style/AppTheme.NoActionBar"
tools:context=".fragments.MainFragment">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="false"
android:cropToPadding="false"
android:scaleType="fitEnd"
android:tint="@color/background"
android:translationX="128dp"
android:translationY="128dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/logo_domain_vasado" />
<android.support.v7.widget.RecyclerView
android:id="@+id/main_listDataListRecycler"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="@+id/main_noDataText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="@string/noDataMessage"
android:textAlignment="center"
android:textSize="30sp"
android:textStyle="bold"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/main_noDataQrButton"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/main_noDataQrButton"
android:layout_width="220dp"
android:layout_height="220dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp"
android:background="@drawable/shape_qr_code_frame"
android:elevation="16dp"
android:onClick="qrScan"
android:theme="@style/AppTheme"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="@+id/main_listDataListRecycler"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="OnClick" />
for the activity lifecycle:
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Control.logData("creating activity")
setContentView(R.layout.activity_app)
// keep screen alive
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
// set toolbar
setSupportActionBar(findViewById(R.id.app_toolbar))
supportActionBar?.title = getString(R.string.Datas)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
isWaitingResult = savedInstanceState?.getBoolean(isWaitingResultCode) ?: false
savedInstanceState?.let
fragment_state = savedInstanceState.getString(fragState) ?: fragment_state
userAuth = savedInstanceState.getSerializable(userAuthCode) as? UserAuthentication?
val DataMenu = findViewById<NavigationView>(R.id.app_navigation)
.menu.findItem(R.id.DataButton)
DataMenu?.isChecked = true
if (!Control.filters) filterMenu?.icon = drawable(R.drawable.filter_inactive)
//injection
if (!isInjected)
onInject()
override fun onStop()
super.onStop()
Control.logData("stopping activity")
fragmentManager.executePendingTransactions()
Control.mainRunning = false
loop = false
saveFav()
override fun onDestroy()
super.onDestroy()
Control.logData("destroying activity")
Control.rx.forEach it.dismiss()
Control.rx.clear()
Control is a object with some function and data commonly used across the App
android android-fragments kotlin
When I start my activity by the first time everything is fine I can navigate normally but after rotating the screen the fragmentMananger appears to bug, and after every change of fragment it loads a blank fragment if I rotate the screen and the activity is recreated the correct fragment appears but the bug persists.
when I quit the app and back to use it the error persists and only disappears after clear the user data, I try to recreate the activity after every fragment change but it only turn things worst.
the one thing solve the problem is to clear user data after every app finalization but it erases important data managed by the app at runtime that need persist via file for the next execution.
I use a companion object for manage fragment names:
companion object
val TAG = this::class.java.canonicalName!!
const val MAIN_FRAGMENT = "MainFragment"
const val SECOND_FRAGMENT = "SecondFragment"
const val THIRD_FRAGMENT = "ThirdFragment"
const val FOURTH_FRAGMENT = "FourthFragment"
const val FIFTH_FRAGMENT = "FifthFragment"
functions for manage fragments:
fun callFragment(s: String? = null)
validateFrag(s ?: MAIN_FRAGMENT, ::setFragment)
fun updateFragment()
Control.logData("updating fragment $fragment_state")
validateFrag(fragment_state, ::setFragment)
private fun validateFrag(s: String, f: (String) -> Unit)
when (s)
SECOND_FRAGMENT -> f(s)
THIRD_FRAGMENT -> f(s)
FOURTH_FRAGMENT -> f(s)
FIFTH_FRAGMENT -> f(s)
else -> f(MAIN_FRAGMENT)
private fun createFrag(id: String): Fragment = when (id)
SECOND_FRAGMENT -> SecondFragment.newInstance()
THIRD_FRAGMENT -> ThirdFragment.newInstance()
FOURTH_FRAGMENT -> FourthFragment.newInstance()
FIFTH_FRAGMENT -> FifthFragment.newInstance(this)
else -> MainFragment.newInstance()
private fun setFragment(id: String)
val userAuth = userAuth
userAuth ?: return
Control.logData("loading fragment $id")
val frame = R.id.app_frame
val fragment = (fragmentManager.findFragmentByTag(id) ?: createFrag(id))
currentFragment = fragment as MyAppFragment
fragment_state = id
when
fragmentManager.fragments.size == 0 ->
fragmentManager.beginTransaction()
.add(frame, createFrag(MAIN_FRAGMENT), MAIN_FRAGMENT)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
!fragmentManager.fragments.contains(fragment as Fragment) ->
fragmentManager.beginTransaction()
.add(frame, fragment, id)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commitNowAllowingStateLoss()
else ->
with(fragmentManager.beginTransaction())
replace(frame, fragment, id)
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
commitNowAllowingStateLoss()
for the commits I try Commit(), CommitNow() too
my fragment implementation:
package com.domain.app.fragments
import android.content.Context
import android.support.v4.app.Fragment
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ScrollView
import com.reactivex.disposables.Disposable
import com.domain.app.Control
import com.domain.app.R
import com.domain.app.AppApplicatcomn
import com.domain.app.activities.appActivity
import com.domain.app.dagger.services.IRXService
import com.domain.app.recycler.adapter.DataListAdapter
import kotlinx.android.synthetic.main.fragment_main.*
import javax.inject.Inject
class MainFragment : Fragment(), AppFragment
// instanciate data
compancomn object
fun newInstance(): MainFragment
return MainFragment()
override fun onAttach(context: Context?)
super.onAttach(context)
activity?.let act ->
//subscribe RX
override fun onDetach()
super.onDetach()
//disposeRX
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View?
return inflater.inflate(R.layout.fragment_main, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
dockInit()
recyclerInit()
if(Control.index.isEmpty())
noDataScreen()
else
Control.putOnScreen()
override fun noDataScreen()
activity?.runOnUiThread
main_noDataQrButton?.visibility = View.VISIBLE
main_noDataText?.visibility = View.VISIBLE
Control.loadingDataStream.onNext(false)
isInit = false
override fun notifyRecycler()
activity?.runOnUiThread
if(::list.isInitialized)
mAdapter.update()
list.adapter?.notifyDataSetChanged()
private fun recyclerInit()
mAdapter = DataListAdapter(activity as appActivity)
mAdapter.setHasStableIds(true)
list = view!!.findViewById<RecyclerView>(R.id.main_listDataListRecycler).apply
setHasFixedSize(true)
setItemViewCacheSize(8)
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.domain.app">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".AppApplication"
android:allowBackup="true"
android:icon="@drawable/app"
android:label="@string/app_name"
android:roundIcon="@drawable/app_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"
android:allowClearUserData="true"
android:fullBackupContent="@xml/backup_descriptor">
<!-- android:theme="@style/AppTheme" -->
<activity
android:name=".activities.AppActivity"
android:screenOrientation="portrait"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<!-- para ser aberto com action APP -->
<action android:name="android.intent.action.APP" />
<action android:name="android.intent.action.MAIN" />
<action android:name="io.ubivis.digitalmobility.action.CONSUME_APP_NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="app.domain.io"
android:scheme="https" />
</intent-filter>
</activity>
<service android:name=".services.FirebaseMessageService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".services.FirebaseTokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_logo_app_60dp" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorPrimary" />
<!-- Para Android 8 - Necessário um canal para notificações -->
<!-- <meta-data -->
<!-- android:name="com.google.firebase.messaging.default_notification_channel_id" -->
<!-- android:value="@string/default_notification_channel_id"/> -->
</application>
my activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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.support.v7.widget.CardView
android:id="@+id/app_connectionCard"
android:layout_width="match_parent"
android:layout_height="40dp"
android:visibility="gone"
app:cardBackgroundColor="@android:color/holo_red_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_toolbar">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connectionFail"
android:textColor="@color/cardview_light_background"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.Toolbar
android:id="@+id/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ubivis_background_blue"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/app_drawer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_connectionCard"
tools:openDrawer="start">
<FrameLayout
android:id="@+id/app_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/app_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorPrimaryDark"
android:fitsSystemWindows="true"
android:theme="@style/UbivisDrawerTheme"
app:headerLayout="@layout/nav_header_app"
app:itemIconTint="@color/ubivis_orange"
app:menu="@menu/activity_app_drawer" />
</android.support.v4.widget.DrawerLayout>
fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:theme="@style/AppTheme.NoActionBar"
tools:context=".fragments.MainFragment">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="false"
android:cropToPadding="false"
android:scaleType="fitEnd"
android:tint="@color/background"
android:translationX="128dp"
android:translationY="128dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/logo_domain_vasado" />
<android.support.v7.widget.RecyclerView
android:id="@+id/main_listDataListRecycler"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="@+id/main_noDataText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="@string/noDataMessage"
android:textAlignment="center"
android:textSize="30sp"
android:textStyle="bold"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/main_noDataQrButton"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/main_noDataQrButton"
android:layout_width="220dp"
android:layout_height="220dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp"
android:background="@drawable/shape_qr_code_frame"
android:elevation="16dp"
android:onClick="qrScan"
android:theme="@style/AppTheme"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/main_dock"
app:layout_constraintStart_toStartOf="@+id/main_listDataListRecycler"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="OnClick" />
for the activity lifecycle:
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Control.logData("creating activity")
setContentView(R.layout.activity_app)
// keep screen alive
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
// set toolbar
setSupportActionBar(findViewById(R.id.app_toolbar))
supportActionBar?.title = getString(R.string.Datas)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
isWaitingResult = savedInstanceState?.getBoolean(isWaitingResultCode) ?: false
savedInstanceState?.let
fragment_state = savedInstanceState.getString(fragState) ?: fragment_state
userAuth = savedInstanceState.getSerializable(userAuthCode) as? UserAuthentication?
val DataMenu = findViewById<NavigationView>(R.id.app_navigation)
.menu.findItem(R.id.DataButton)
DataMenu?.isChecked = true
if (!Control.filters) filterMenu?.icon = drawable(R.drawable.filter_inactive)
//injection
if (!isInjected)
onInject()
override fun onStop()
super.onStop()
Control.logData("stopping activity")
fragmentManager.executePendingTransactions()
Control.mainRunning = false
loop = false
saveFav()
override fun onDestroy()
super.onDestroy()
Control.logData("destroying activity")
Control.rx.forEach it.dismiss()
Control.rx.clear()
Control is a object with some function and data commonly used across the App
android android-fragments kotlin
android android-fragments kotlin
asked Nov 13 '18 at 14:18
beltraoluisbeltraoluis
13
13
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
in my case the blank screen was caused by the main thread blocked, after an api update some deprecated functions started to return null and block the main thread inside the fragments for solve the problem I used the new functions provided by the api to replace the deprecated ones
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283051%2ffragment-changes-to-blanck-fragment-after-destroy%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
in my case the blank screen was caused by the main thread blocked, after an api update some deprecated functions started to return null and block the main thread inside the fragments for solve the problem I used the new functions provided by the api to replace the deprecated ones
add a comment |
in my case the blank screen was caused by the main thread blocked, after an api update some deprecated functions started to return null and block the main thread inside the fragments for solve the problem I used the new functions provided by the api to replace the deprecated ones
add a comment |
in my case the blank screen was caused by the main thread blocked, after an api update some deprecated functions started to return null and block the main thread inside the fragments for solve the problem I used the new functions provided by the api to replace the deprecated ones
in my case the blank screen was caused by the main thread blocked, after an api update some deprecated functions started to return null and block the main thread inside the fragments for solve the problem I used the new functions provided by the api to replace the deprecated ones
answered 2 days ago
beltraoluisbeltraoluis
13
13
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283051%2ffragment-changes-to-blanck-fragment-after-destroy%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown