Android switching from ProgressDialog to ProgressBar, best implementation with many activities? - android-asynctask

The majority of my activities make an async call to an API as they open to retrieve the data which will be displayed. With ProgressDialog, I can simply pass the context of the activity to my AsyncTask class and display/hide the loading circle as this happens. This is useful as it requires no extra work when adding a new activity that will make an async call.
E.g in onPreExecute():
progressDialog = new ProgressDialog(contextRef.get());
progressDialog.setMessage("Please wait...");
progressDialog.show();
I'd like to make the switch to ProgressBar however this requires adding a ProgressBar to the XML of every activity that will require one. The best i've come up with is copy/pasting the XML to every activity and doing something like this in onPreExecute():
progressBar = ((Activity) contextRef.get()).findViewById(R.id.loading);
progressBar.setVisibility(View.VISIBLE);
This works fine however the ProgressBar is a relatively big chunk of XML:
<ProgressBar
android:id="#+id/loading"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#80000000"
android:indeterminateDrawable="#drawable/loading"
android:translationZ="2dp"
android:clickable="false"
android:paddingTop="250dp"
android:paddingBottom="250dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I'm not a fan of this as if I need to change something I would have to change it everywhere. Is there a way to put the ProgressBar in a layout file and have the other layouts reference this? Or just a better way to go about this in general?
Cheers

I use this library: https://github.com/FANMixco/spots-dialog
private SpotsDialog progressDialog;
and
progressDialog = (SpotsDialog) new SpotsDialog.Builder().setContext(activity)
.setMessage("One moment please ...")
.setCancelable(true)
.build();
progressDialog.show();
I also use it in asynctask, it's easy to swap for progressdialog and works great.
When you use proguard do not forget
-keep class dmax.dialog.** { *;}
Otherwise the points are not displayed

Related

Cannot add Flyout Footer in Xamarin forms app

I have a xamarin forms application and I want to add a footer to the flyout menu. After reading the official documentation it should be straightforward, just adding a few lines into the AppShell.xaml like so:
<Shell.FlyoutFooterTemplate>
<DataTemplate>
<Label HeightRequest="300" BackgroundColor="Red"/>
</DataTemplate>
</Shell.FlyoutFooterTemplate>
This works perfectly fine when I tried it in a new project, but for some reason, it doesn't work in my current application giving this error:
Error XLS0415 The attachable property 'FlyoutFooterTemplate' was not found in type 'Shell'.
I tried to find the definition of FlyoutHeaderTemplate and I found this in Shell [from metadata] file:
[1]: https://i.stack.imgur.com/xqZub.png
public Shell();
...
public DataTemplate FlyoutHeaderTemplate { get; set; }
public FlyoutHeaderBehavior FlyoutHeaderBehavior { get; set; }
public object FlyoutHeader { get; set; }
There should be a similar definition for both, Header and Footer, but there is only one for the Header. The file cannot be edited and I was not able to locate it either. Any ideas why the definition for Footer is missing, how can I add it, or workarounds?
PS: Adding the footer from C# code doesn't work either and I tried to clean/rebuild and resetting both, PC and VS.
First, Confirm that you can add a simple Header:
<Shell.FlyoutHeader>
<Label Text="This is the header." />
</Shell.FlyoutFooter>
If that doesn't work, then you are doing something fundamentally wrong - post the code for the <Shell> XAML, within which you added those lines. Make sure you include those lines, to show where in the XAML they are. Make sure they are between <Shell> and </Shell>, but not nested inside some deeper node. For example, they musn't be inside a <StackLayout> or <ContentView> or other container - they must be direct children of the <Shell>.
Unless you are doing something fancy, you don't need a Template.
Try simply:
<Shell.FlyoutFooter>
<Label HeightRequest="300" BackgroundColor="Red"/>
</Shell.FlyoutFooter>
If 1) above works, but not 2), then your project is referencing an out-of-date version of Shell. Fixes:
A. Check that project's Xamarin.Forms nuget doesn't need an Update. (Solution / Manage Nugets.)
B. OR delete bin and obj folders. Then Rebuild Solution.
C. Worst case, start with a new project, in which you are able to use that functionality, and add back in all your files.

Xamarin.forms Stand-alone resource dictionaries don't update dynamically if there is no cs code behind file

Xamarin team introduced 2 different way of stand-alone-resource-dictionaries. Obviously there is a big difference but they neglected to write in their documentation.
Basically if i use without cs code behind file and without x:class defined as defined in the documentation and referencing like that in my page
<ResourceDictionary Source="GradientStyles.xaml"/>
GradientStyles.xaml look like below and i am updating GradientStartColor , GradientStopColor of PancakeView on runtime based on the theme selected.
<pancakeView:GradientStopCollection x:Key="BackgroundGradientStops">
<pancakeView:GradientStop Color="{StaticResource GradientStartColor}"
Offset="0"/>
<pancakeView:GradientStop Color="{StaticResource GradientStopColor}"
Offset="0.74"/>
</pancakeView:GradientStopCollection>
Implementation above just not working. It doesn't update Colors at all.
The same exact code;
Works in ContentPage.Resources directly. It will update
Works if i define a stand-alone-resource-dictionary with cs code behind file and implement on the page like this below
<ResourceDictionary.MergedDictionaries>
<resDics:GradientStyles />
</ResourceDictionary.MergedDictionaries>
There is that annotation in the documentation but i don't get what exactly it means.
This syntax doesnot instantiate the MyResourceDictionary class.
Instead, it references the XAML file.
Does it mean that it extends the contentpage using like partial class or inherits. Or is it cached only once and remains static? And when you use it with code behind class, it creates a new instance every time?
Finally is that a bug or feature? :)

How to create LibVLCSharp custom playback controls in Xamarin Forms?

I've been searching for days now for a guide on how to create the custom playback controls for LibVLCSharp that everyone seems to talk about, which I never found a guid for.
I simply want to create other buttons with event handlers for the bottom playback control panel, I tried this but throws a System.NullReferenceException exception on startup while getting into break mode...
<vlc:MediaPlayerElement MediaPlayer="{Binding MediaPlayer}" LibVLC="{Binding LibVLC}">
<vlc:MediaPlayerElement.PlaybackControls>
<vlc:PlaybackControls>
<vlc:PlaybackControls.ControlTemplate>
<ControlTemplate>
<Grid>
<StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand">
<Button Grid.Column="0" Text="Test 1"/>
<Button Grid.Column="1" Text="Test 1"/>
<Button Grid.Column="2" Text="Test 1"/>
</StackLayout>
</Grid>
</ControlTemplate>
</vlc:PlaybackControls.ControlTemplate>
</vlc:PlaybackControls>
</vlc:MediaPlayerElement.PlaybackControls>
</vlc:MediaPlayerElement>
I want it to act just like the original one (Auto hides, overlays on tapping, etc...) but with my own layout and controls. I also thought about using the existing one and try to override their handler to implement my own code and override the text property for each button to change its icon but no luck of finding any help.
Thanks in advance ^_^
The code you are interested in is here: https://code.videolan.org/videolan/LibVLCSharp/-/blob/3.x/src/LibVLCSharp.Forms/Shared/Themes/Generic.xaml
I also thought about using the existing one and try to override their handler to implement my own code and override the text property for each button to change its icon
That'd be the way to go.
This previous SO question might answer your question: https://stackoverflow.com/a/14217500/4064749
Just create a new Style based on PlaybackControlsStyle, override what you want and then set it on the PlaybackControls element.
I created https://code.videolan.org/videolan/LibVLCSharp/-/issues/309 recently to track the need of a tutorial to customize the MediaElement.
Further docs on style inheritance: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/styles/xaml/inheritance
I finally found the problem which was making exceptions, when I create custom control template which completely correct, the MediaPlayerElement code behind by LibVLCSharp developers itself cannot find the elements with the names defined anymore as they used hardcoded names for the buttons and views instead of using bindings and dynamic setters.
Thus, several workarounds could be made to fix such issue, here are some of my ideas:
Use the generic style documented here and modify it without removing any elements but rather hide them out or overlay them.
Create your own style with controls obtaining the same names of the original ones.
Find a way to modify or maybe create a whole new playback control element using the original one which can be found here and here.
Thanks to mfkl's answer which helped me find out how everything worked under the hood to come up with the explaination, even though this took me a couple of days to figure out.

Populate HTML forms in WebView

I have a NativeScript-5 app (TypeScript flavor) with a simple page like this:
<Page class="page">
<StackLayout>
<WebView id="webView" loaded="onWebViewLoaded" src="http://google.com" />
</StackLayout>
</Page>
After loading the web page (onWebViewLoded()), I would like my app to populate certain HTML fields (access by id or name) and finally post the surrounding HTML form. Can this be done at all?
I know that there is a Nativescript-WebView-Interface plugin, but it requires me to embed a script in the loaded page (and I can't do this, because I don't own the page I am loading). So I assume I need another approach.
If anybody has a solution that works at least on Android, that would be great. Thanks guys!
Update:
In order to avoid misunderstandings: Submitting the page is optional. The important part is to load a web page and auto-fill some values that my app already knows (so the user does not have to enter these values in the HTML form himself).
You may easily execute JavaScript in the webpage context in Android.
export function onLoadFinished(args: EventData) {
const webView = (<WebView>args.object).nativeView;
if (isAndroid) {
// Make sure the element index is valid
const javaScript = `document.getElementsByTagName("input")[2].value = "It works!"`;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript(javaScript, null);
} else {
webView.loadUrl(`javascript:${javaScript}`);
}
}
}
Here is the Playground Sample
It's also possible with iOS, but you may have to override / extend the existing {N} WebView inject JavaScript upon creating native view.

Stopping a LinkButton from being greyed out when disabled in IE

I'm trying to make it so that a LinkButton doesn't get greyed out in IE when Enabled="False". Disabling the postback like they suggest here and here works but doesn't stop the cursor and text colour from changing when you hover over it as if it were a button, like Enabled="False" does.
<asp:LinkButton ID="LinkBut1" runat="server" CssClass="Tag" Enabled="False"
OnClick="LB_Click" Text="Add" />
(Using .NET 4 and C#)
Thanks.
Have you considered extending the LinkButton class, overwriting the Rend method and doing something like:
protected override void Render(HtmlTextWriter writer)
{
if (!this.enabled)
...write an html span that looks like a link or something ...
else
base.Render(writer);
}

Resources