Croutons not showing from time to time - android

I have the official Navigation Drawer in my app. Clicking items in the drawer opens new Fragments in the content part of the screen. Every Fragment contains FrameLayout with the same id which is used for displaying a Crouton.
Basic use is that an infinite Crouton is shown when user clicks refresh button in Action Bar (notifying about ongoing refresh). After refresh is finished, another crouton is shown (replacing the old one). In some cases Croutons are shown even right after a screen is entered (and replaced when refresh is triggered).
The issue I'm experiencing is a bit difficult to describe. Some Croutons are just not showing from time to time. It usually happens when I switch between screens (the initial Crouton is not shown or the Crouton is not shown when I press refresh button for the first time on that screen - however, it is displayed when refresh finishes and when I press refresh button afterwards).
So it is pretty unpredictable. There even are cases, when the screen doesn't show the Crouton at all until I switch to another screen and back.
For displaying Croutons I use this in every Framgnet's layout:
<FrameLayout
android:id="#+id/crouton_view"
android:layout_width="match_parent"
android:layout_height="#dimen/crouton_height"
android:layout_alignParentTop="true" />
In code I have CroutonBuilder class with following methods:
public static Crouton getNewLastUpdateCrouton(Activity activity, boolean infinite, String plateNumber) {
String lastUpdateString = ...;
Crouton newCrouton = Crouton.makeText(activity, lastUpdateString, CroutonBuilder.getLastUpdate(activity),
R.id.crouton_view);
if (infinite) {
newCrouton.setConfiguration(new Configuration.Builder().setDuration(
Configuration.DURATION_INFINITE).build());
}
return newCrouton;
}
and then just call .show() on the returned Crouton.
When I debug and step through, the show() method is called but sometimes just nothing is shown.
Do you have any ideas what am I do wrong?

I found out Croutons stopped appearing when I left a Fragment while a Crouton was currently shown. Calling Crouton.cancelAllCroutons() in onPause() helped.

Related

Android: View Visibility set to View.VISIBLE but View is not Visible

In my app (general construction described below), I have a timer, which the user can start by clicking an in-app button.
When the timer starts, a notification is shown. In the notification, there's a "STOP" button, which when clicked is supposed to open the app (if closed or killed) and then show a custom dialog.
The custom dialog is built of a bunch of views and a blur-background view.
There are two ways to open that dialog:
Clicking an in-app button triggers the method that opens this dialog.
Clicking the "STOP" button in the notification also triggers the same method (By calling a BroadcastReceiver that lives in the same fragment as the dialog, and in the BroadcastReceiver I call the method that opens the dialog - it all happens after the app opens (if it was closed or killed)).
The first method works - clicking the button opens the dialog when it's supposed to.
The second, however, opens the app but not the dialog (To clarify - opening the dialog means changing its views visibility to View.VISIBLE).
To check what goes wrong, I used a Toast message that shows the visibility of the dialog every time the method that opens the dialog gets called. The Toast message shows "VISIBLE", so that means the Views visibility is set to View.VISIBLE indeed - but the dialog is not shown, nor the blur-background.
General Construction: The app has multiple Fragments, stored inside a view pager, inside the MainActivity and the dialog lives in the main fragment.
Might Be Relevant: when clicking the notifications button, the app opens, but the notification panel stays fully opened. The Toast message shows behind the notification panel.
Also might be worth mentioning, that when I click the notification button while I didn't yet leave the app, the dialog pops up. Only after I leave the app and then come back (manually or by clicking the notification button) the dialog doesn't pop up.
dialog's XML: (stored inside of fragment_main.xml)
<com.google.android.material.circularreveal.CircularRevealFrameLayout
android:id="#+id/dialog_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_behavior="com.google.android.material.transformation.FabTransformationSheetBehavior">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardPreventCornerOverlap="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="15.0dip">
//Here is the content of the dialog, textviews and custom buttons
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
</com.google.android.material.circularreveal.CircularRevealFrameLayout>
dialog opening method:
private void openDialog() {
//while "dialog" refers to the "dialog_container" in the dialog xml
dialog.setVisibility(View.VISIBLE);
fadeBlurIn(); //fades the blur-background view in
dialog.setClickable(true);
}
calling the method in the BroadcastReceiver: (stored inside MainFragment.java)
private final BroadcastReceiver endTimerReceiver = new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onReceive(Context context, Intent intent) {
.
.
.
boolean openDialog = {gets a boolean extra, works fine};
if (openDialog){
openDialog();
}
}
}
};
this BroadcastReceiver is attached to this fragment and works fine.
Why doesn't the dialog show?
And how can I fix it?
Problem Solved
What was the issue all about?
The problem was when re-opening the app after closing or leaving it, the main-fragment was re-created, and with it a new blur-background and a new custom dialog.
The BroadcastReceiver was stored in the old main-fragment, and so it referred to the old views (the old blur and dialog views)
The old views' visibility has changed, but the new ones didn't, so the visibility state change wasn't visible to the user.
But that's not all. Later on, I discovered that in addition to all that, even if I refer to the right view and try to display it, it's not displaying, and I found another problem - I try to change its visibility state too early.
Solution
Solving it was quite simple.
All I had to do was make the blur-background and the custom dialog static, so they'll not re-create every time a main-fragment is created. Then Their visibility state changes were visible to the user.
And the solution for the second half of the problem was even easier - all I had to do is put the command calling the method to show the dialog inside a Runnable, running in delay by a Handler. 10 ms of delay has done the job.
Although this thread's issue is solved by now, this issue still isn't.
Note to self
A good habit is to think ahead, knowing what objects I should set static, so that stuff like this won't happen frequently
By notification panel, do you mean it's a bar on top of the app activity?
If so, my guess is that opening the notification panel pushes the dialog outside the device screen. Perhaps the dialog is constrained to the notification panel?
I'm not very sure about this, so sorry if this turns out to be incorrect!
Also, posting some code might help.
You have made the view invisible and shown when clicked on either button or notification bar.
You can do is
Make the view visible and add the condition if called by Notification bar it remains as it is, if not then hide it and make it visible again on call on button.
Give the fix height and width to dialog
box and set the visibilty to "Gone".
android:visibility="gone"
After that call open dialog function and setVisibility to Visible.

Re-display parent dialog after child dialog closes

In my app, I display a custom Dialog (using DialogFragment), which on certain action causes another custom Dialog to be shown (using another DialogFragment). This all works fine. However when the "child" dialog is closed, I want to return to the parent dialog (which is closed/hidden when the child is displayed).
I do not want just display another instance of the same dialog, as I need to maintain states and behaviours of the parent prior to the child being open. Therefore I need to re-display physically the same dialog.
I can't seem to find a way of doing so.
Coming back to it as I now got a solution that seems to work. Apparently, using dialog directly will close the previous dialog when a new one is opened. Yet, when using DialogFragment, the previous fragment stays on screen when the new fragment is displayed. Then when the dialog on the new fragment is closed the previous fragment is still visible - exactly what I need.

ActionBar animation does not stop

I am using ActionBar Sherlock with a number of fragments.
The app I am building is a basic RSS reader much like the one shown here (http://www.youtube.com/watch?v=R_qR2glTTAs), except that there are multiple tabs for several different RSS feeds. When a tab is clicked, I replace the active fragment with the appropriate new fragment.
I am trying to get ActionBar animated refresh button functionality much like it is depicted in the YouTube video above. Basically, when the user clicks the refresh button, I expect the refresh button to rotate until the refresh is complete. If the user switches tabs while the current tab is refreshing, I want to show a refresh button that is NOT rotating.
The problem is: after I click on the refresh button and the button starts rotating, if I switch to another tab, I simply get a non-rotating refresh button on top of the rotating refresh button! This happens despite my calling menu.clear() and recreating the menu each time a tab is clicked. Interestingly, rotating the device causes the extra rotating refresh buttons to disappear.
Nothing I've tried seems to be able to stop the refresh animation when I change tabs! Any ideas why? I can post more of my code here if necessary.
I think the problem could be that you are animating and / or creating the menu inside your fragements... if this is the case do the things you want to do with your menu in the FragmentActivity
By the way, the effect you experience while rotating the screen is caused by the android architecture. Android always recreates the view if you are switching from portrait to landscape mode or the other way around.

Hide Progress Dialog from background-fragment

I'm encountering the following problem. I implemented a navigation with tabs and viewpager to swipe through my fragments. This is working fine so far.
But the fragments are all loading data via Async Task and for that they are showing an progress dialog. Which is self is also working as it should. My problem is, that because of the Viewpager not only the actual fragment is loaded but also the one next to it. So I see wrong progress dialog.
Is there any way, to achieve a behavior that the progress dialog stays visible for it's fragment (so, that the user is informed, when he moves to the next tab before the async task finished loading) but not anywhere else?
Hope it's clear, what I wanted to say.
Thanks for your help.
Best wishes
The progress dialog can be a "dialog" that hangs out in front of everything, or it can be a View that sits in place. So, my advice would be to make either a full screen (or just partial screen) layout that sits in your fragment and displays the progress dialog. It will move aside with the rest of the fragment if the user moves to a different fragment. If you set it at the top Z level, make it full screen and capture all taps to it (and swallow them so they don't cascade down into the layouts beneath in the z-order) I believe you'll have exactly what you're describing as your desired result.
The key is not to use ProgressDialog dynamically in code, but rather just the View version of it that you just place in your XML.
Edit:
I'm talking about one of these...
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

Refreshing an Activity

I created an Activity which allows navigating between pages with a couple of Buttons (Previous and Next). When the user clicks one of the buttons, the Activity (same) needs to be "refreshed". In order to do this, I set up the buttons to make a call to
onCreate(this);
after they set up the other stuff that the activity uses for the paging to work.
And it is working so far, but I'm wondering if there is a better way. Is there?
You should rethink your approach. Having Previous and Next buttons looks like an iphone's NavigationBar View. Remember that in android you have the back button, so a previous button shouldn't be necessary.
If you wish to do it, check Android's Activity Lifecycle. You should update your Activity on the onStart() method and avoid the call to onCreate(this) which doesn't sound good.
The activity displays data related to a certain day. The navigation allows choosing the day which is being displayed. As such, clicking one of the buttons changes the information which is displayed.
Example:
When the Activity first loads, it shows a given day - let's say August 23rd. Then when the user clicks the activity's "Previous" Button, the Activity shows August 22nd.
Then the user clicks the "Next" button and the Activity shows August 23rd again. If the user clicks the "Next" button again, the Activity will show August 24th.
Doesn't it seam a little strange to only have a "Next" (and rely on the physical "Back" button) ?
Thanks.
I fixed this trough refactoring:
Created a new function with the code that was being executed in onCreate (i.e. Layout initialization, database access and information display). The new function is called by the onCreate method (when the Activity gets the "Create" notification) and at anytime that I need to "refresh" the contents of the Activity (i.e. when a button is pressed).
Thanks for your comments.

Categories

Resources