How to show ProgressBar and make it progress?(Xamarin.Android) - xamarin.android

I call a web service which gets 4 files, and while these files are loading I want to show progress to the user (circular or horizontal it doesn't matter). I've followed the examples on internet but nothing appears on screen.
MobileSellReference.Service1 service = new MobileSellReference.Service1();
service.Url = settings.Synchronization.Msellurl;
ProgressBar progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar);
progressBar.Max = 100;
progressBar.Progress = 0;
byte[][] basedataResult = service.ToPPC(basedataZipName, objectId);
progressBar.IncrementProgressBy(25);
byte[][] dutybasedataResult = service.ToPPC(dutybasedataZipName, objectId);
progressBar.IncrementProgressBy(25);
byte[][] tranbasedataResult = service.ToPPC(tranbasedataZipName, objectId);
progressBar.IncrementProgressBy(25);
byte[][] vendbasedataResult = service.ToPPC(vendbasedataZipName, objectId);
progressBar.IncrementProgressBy(25);
I've found a lot of examples using external progressbar libraries but they all want to change the theme of the Activity. Instead I want some simple ProgressBar built into Xamarin.Android. For example when the first file is downloaded I want 1/4 of the circle to be filled, when 2 files are downloaded 1/2 of the circle to be filled et cetera. Similarly for a horizontal ProgressBar.

Use AsyncTask
.axml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="0" />
<ProgressBar
android:id="#+id/pb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal" />
</LinearLayout>
MainActivity:
public class MainActivity : Activity
{
ProgressBar pb;
TextView tv;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
pb = FindViewById<ProgressBar>(Resource.Id.pb);
tv = FindViewById<TextView>(Resource.Id.tv);
UpdatePB uptask = new UpdatePB(this,pb,tv);
uptask.Execute(100);
}
public class UpdatePB : AsyncTask<int, int, string>
{
Activity mcontext;
ProgressBar mpb;
TextView mtv;
public UpdatePB(Activity context,ProgressBar pb,TextView tv) {
this.mcontext = context;
this.mpb = pb;
this.mtv = tv;
}
protected override string RunInBackground(params int[] #params)
{
// TODO Auto-generated method stub
for (int i = 1; i <= 4; i++)
{
try
{
Thread.Sleep(3000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
Android.Util.Log.Error("lv",e.Message);
}
mpb.IncrementProgressBy(25);
PublishProgress(i * 25);
}
return "finish";
}
protected override void OnProgressUpdate(params int[] values)
{
mtv.Text = String.ValueOf(values[0]);
Android.Util.Log.Error("lv==", values[0] + "");
}
protected override void OnPostExecute(string result)
{
mcontext.Title = result;
}
}
}

This might be a helpful link:
https://developer.android.com/reference/android/widget/ProgressBar.html
Code:
<ProgressBar
android:id="#+id/determinateBar"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progress="25"/>
... and then you just change the progress; 25, 50, 75, 100?

After running into the same problem, I found another solution that got it working. I was reluctant to define a new class (like AsyncTask) to fix this, so looked into async await and threading. I found that after defining an Android.Widget.ProgressBar in an .axml layout file like so:
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="0"
style="?android:attr/progressBarStyleHorizontal" />
I could get it to update if I put the updating tasks in a System.Threading.Tasks.Task.Run and passing in an action that does the updates with RunOnUiThread call like:
btnDoStuff.Click += (sender, e) =>
{
Task.Run(() =>
{
RunOnUiThread(() =>
{
progressBar.Max = 100;
progressBar.Progress = 0;
progressBar.Visibility = ViewStates.Visible;
});
DoSomeWork1(arguments);
RunOnUiThread(() => progressBar.Progress += 25);
DoSomeWork2(arguments);
RunOnUiThread(() => progressBar.Progress += 25);
DoSomeWork3(arguments);
RunOnUiThread(() => progressBar.Progress += 25);
DoSomeWork4(arguments);
RunOnUiThread(() => progressBar.Progress += 25);
});
}
But even then I've had some inconsistent behavior - there may be an element of timing to it as well...

Related

How to wait for LottieAnimationView to finish then do something

I have the following code in Xamarin.Android, I want to show my main actcivty after the LottieAnimationView finshed.
<com.airbnb.lottie.LottieAnimationView
android:id="#+id/SplashAnimationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:lottie_autoPlay="true"
app:lottie_fileName="LoadingLottie.json"
app:lottie_loop="false"
app:lottie_speed="1.00"/>
There is an AnimationEnd event in it. So you can try the following code:
LottieAnimationView lottieAnimationView = this.FindViewById<LottieAnimationView>(Resource.Id.SplashAnimationView);
lottieAnimationView.Animation.AnimationEnd += (s, e) =>
{
Intent intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask);
StartActivity(intent);
};

Xamarin iOS - Text Changed event not showing results

Xamarin iOS is testing me lately. I have a form which has as Entry value for searching. This entry control has a text changed event. All works great , event executes and values passed as expected however the results dont appear on screen.
If i rotate the device, in this case and ipad, the results show. Everything in Android works as expected. Frustrating
CancellationTokenSource _cts;
private void Search_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
_cts?.Cancel(); // cancel previous search
}
catch { } // in case previous search completed
ShowResults((Entry)sender);
}
private async void ShowResults(Entry entry)
{
using (_cts = new CancellationTokenSource())
{
try
{
await Task.Delay(TimeSpan.FromSeconds(1), _cts.Token); // buffer
using (UserDialogs.Instance.Loading("Loading. . ."))
{
ObservableCollection<TMDB_Movie> itemSourceCollection = new ObservableCollection<TMDB_Movie>();
MovieSearchVM context = (MovieSearchVM)BindingContext;
try
{
if (!IsPublicCollection)
{
var results = PrivateCollection.Where(x => x.Title.Contains(entry.Text));
foreach (TMDB_Movie movie in results)
{
movie.PublicCollection = true;
movie.Type = "Digital";
itemSourceCollection.Add(movie);
}
}
else
{
if (PhysicalDevice.HasInternetConnection())
{
TMDB_Request request = new TMDB_Request();
TMDB_Movies movies = await request.ByMovieName(entry.Text, CustomSettings.GetSettings().Language);
int i = 0;
foreach (var movie in movies.Results)
{
if (i < 10)
{
FanartTv tv = new FanartTv();
movie.Movieposter = await tv.GetSingleMoviePoster(movie.Id);
if (movie.Release_date != null)
{
char[] Separator = new char[] { '-' };
string[] year = movie.Release_date.Split(Separator, StringSplitOptions.None);
movie.Release_year = year[0];
}
movie.PublicCollection = true;
itemSourceCollection.Add(movie);
i++;
}
else
{
break;
}
}
}
}
context.MovieCollection = itemSourceCollection;
}
catch { }
}
}
catch { }
}
}
View Model
private ObservableCollection<TMDB_Movie> _MovieCollection = new ObservableCollection<TMDB_Movie>();
public ObservableCollection<TMDB_Movie> MovieCollection
{
get { return _MovieCollection; }
set
{
_MovieCollection = value;
RaisePropertyChanged("MovieCollection");
}
}
XAML
<Grid Style="{StaticResource StyleBaseGrid}" Grid.Row="2" HorizontalOptions="FillAndExpand" >
<SfListView:SfListView x:Name="GridMovieCollection"
ItemsSource="{Binding MovieCollection}"
ItemTemplate="{StaticResource StandardPosterTemplate}"
Margin="-5,0,0,0"
ItemSize="125"
ItemSpacing="0,0,0,0"
AutoFitMode="None"
SelectionBackgroundColor="Transparent"
ItemHolding="GridMovieCollection_ItemHolding"
ItemTapped="GridMovieCollection_ItemTapped" >
</SfListView:SfListView>
</Grid>
I have no clue why rotation solves this but i guess it updates the controls width and height properties and refreshes the screen.
Any ideas how i can force refresh the screen or if there is anything wrong with my code?
Android look

textview visibility xamarin android

I have created an imageview and above it I created a textview. my aim is that I want to show my imageview if there's an image and if not I want to remove the imageview and display the textview that says "no image", this is my xml code:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Item Image: "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView9"
android:textColor="#android:color/holo_blue_dark"/>
<ImageView
android:src="#android:drawable/ic_menu_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="#+id/imageView1"
android:layout_toRightOf="#id/textView9"/>
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="No Image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView10"
android:layout_toRightOf="#id/textView9"
/>
</RelativeLayout>
and this is my code:
ImageView imgv = view.FindViewById<ImageView>(Resource.Id.imageView1);
textview10 = view.FindViewById<TextView>(Resource.Id.textView10);
textview10.Visibility = ViewStates.Invisible;
private void Ws_getimg_clrCompleted(object sender, WSitems.getimg_clrCompletedEventArgs e)
{
Byte[] data = e.Result.datab;
if (data != null)
{
MemoryStream mem = new MemoryStream(data);
Android.Graphics.Bitmap originBitmap = BitmapFactory.DecodeStream(mem);
imgv.SetImageBitmap(originBitmap);
}
else
{
imgv.Visibility = ViewStates.Gone;
textview10.Visibility = ViewStates.Visible;
}
}
I get my image from a webservice. the problem is that only the imageview is disappearing when there's no image but the textview isn't becoming visible. why? what should I do? thanks in advance.
You can use FFImageLoading to replace your webservice to load Image on the intnet.
ImageView imageView1 = FindViewById<ImageView>(Resource.Id.imageView1);
TextView textView10 = FindViewById<TextView>(Resource.Id.textView10);
textView10.Visibility = ViewStates.Invisible;
// string urlToImage = "http://www.123raw.com/includes/templates/custom/images/123raw_mainpic_01.jpg";
string urlToImage = "http://www.123raw.com/includes/templates/custom/images/12311raw_mainpic_01.jpg";
var config = new FFImageLoading.Config.Configuration()
{
ExecuteCallbacksOnUIThread = true
};
ImageService.Instance.Initialize(config);
ImageService.Instance.LoadUrl(urlToImage).Error(exception =>
{
imageView1.Visibility = ViewStates.Gone;
textView10.Visibility = ViewStates.Visible;
}).Into(imageView1);
Here is running GIF, if the image cannot be loaded.
this is my code:
Task<Stream> GetStreamFromImageByte(CancellationToken ct)
{
//Since we need to return a Task<Stream> we will use a TaskCompletionSource>
TaskCompletionSource<Stream> tcs = new TaskCompletionSource<Stream>();
if (data != null)
{
tcs.TrySetResult(new MemoryStream(data));
}
return tcs.Task;
}
private void Ws_getimg_clrCompleted(object sender, WSitems.getimg_clrCompletedEventArgs e)
{
data = e.Result.datab;
var config = new FFImageLoading.Config.Configuration()
{
ExecuteCallbacksOnUIThread = true
};
ImageService.Instance.Initialize(config);
ImageService.Instance.LoadStream(GetStreamFromImageByte).Error(exception =>
{
imgv.Visibility = ViewStates.Gone;
textview10.Visibility = ViewStates.Visible;
}).Into(imgv);

I want to add custom floating spinner

I want to add custom floating spinner. How to add like this ??
I have tried with AutoComplete textview inside TextInputLayout but it's not properly worked.
http://prntscr.com/mm8ksc
//SocietySpinnerLayout.axml
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="50"
android:id="#+id/societySpinnerLayout"
app:errorTextAppearance="#style/ErrorText"
android:theme="#style/CommonTextStyleTheme">
<AutoCompleteTextView
android:id="#+id/societySpinner"
android:paddingBottom="#dimen/padding_20"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#4C5375"
android:textSize="#dimen/textSize_14"
android:hint="SOCIETY"
android:paddingEnd="60dp"
android:textCursorDrawable="#null"
android:inputType="textPhonetic" />
</android.support.design.widget.TextInputLayout>
//SocietySpinner.cs
private void BindToMySociety()
{
//String[] arraySociety = Resources.GetStringArray(Resource.Array.arraySociety);
ArrayAdapter adapter = new SpinnerSocietyAdapter(this, Resource.Layout.PublisherSpinnerItemLayout, HelperNavigation.LstSociety);
_societySpinner.Adapter = adapter;
if (_societySpinner.HasFocus)
{
InputMethodManager imm = (InputMethodManager)GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(Window.CurrentFocus.WindowToken, 0);
}
_societySpinner.SetOnTouchListener(this);
_societySpinner.Focusable = false;
// _societySpinner.Click+=_societySpinner_Click;
_societySpinner.ItemClick += _societySpinner_ItemClick;
_societySpinner.SetOnDismissListener(this);
if(_selectedSociety!=null)
{
_societySpinner.Text = _selectedSociety.name;
}
}
private void _societySpinner_Click(object sender, EventArgs e)
{
try
{
// _societySpinner.Text = string.Empty;
if (!string.IsNullOrEmpty(_societySpinner.Text))
{
_societySpinner.Text = string.Empty;
_societySpinnerLayout.Typeface = ItalicFont;
_societySpinner.Typeface = ItalicFont;
}
((AutoCompleteTextView)_societySpinner).ShowDropDown();
}
catch (Exception ex)
{
}
}
public bool OnTouch(View v, MotionEvent e)
{
try
{
// _societySpinner.Text = string.Empty;
if (!string.IsNullOrEmpty(_societySpinner.Text))
{
_societySpinner.Text = string.Empty;
_societySpinnerLayout.Typeface = ItalicFont;
_societySpinner.Typeface = ItalicFont;
}
((AutoCompleteTextView)v).ShowDropDown();
return false;
}
catch (Exception ex)
{
return false;
}
}
public void OnDismiss()
{
if(_selectedSociety!=null)
{
if (!string.IsNullOrEmpty(_selectedSociety.name))
{
_societySpinner.Text = _selectedSociety.name;
_societySpinnerLayout.Typeface = RegularFont;
_societySpinner.Typeface = RegularFont;
}
}
else
{
_societySpinnerLayout.Typeface = ItalicFont;
_societySpinner.Typeface = ItalicFont;
}
}
I have tried with above code.But sometime it's throwing out of bound exception.and it's not properly worked.Please give me solution to how to create floating spinner.
I was thinking about this for a long while as I did a similar implementation in one of my earlier projects and then I remembered that I was using the Ganfra Material Spinner to achieve this:
There is a sample project available here
You can use it in XML like below:
<fr.ganfra.materialspinner.MaterialSpinner
android:id="#+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:ms_multiline="false"
app:ms_hint="hint"
app:ms_enableFloatingLabel="false"
app:ms_enableErrorLabel="false"
app:ms_floatingLabelText="floating label"
app:ms_baseColor="#color/base"
app:ms_highlightColor="#color/highlight"
app:ms_errorColor="#color/error"
app:ms_typeface="typeface.ttf"
app:ms_thickness="2dp"
app:ms_hintColor="#color/hint"
app:ms_arrowColor="#color/arrow"
app:ms_arrowSize="16dp"
app:ms_alignLabels="false"
app:ms_floatingLabelColor="#color/floating_label"/>
You can set a hint and a floating label text. If no floating label text is provided, the hint will be set instead.
You use it like a regular spinner, setting an adapter to it:
string[] ITEMS = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"};
var adapter = new ArrayAdapter<String>(this, Android.Resource.Layout.SimpleSpinnerItem, ITEMS);
adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
var spinner = FindViewById<MaterialSpinner>(Resource.Id.spinner1);
spinner.Adapter = adapter;
If you need to set an error message, you can do it the same way as an EditText:
// Activate
spinner.Error = "Error";
// Deactivate
spinner.Error = null;
You can choose to have a scrolling animation or to set the error message on multiple lines with the ms_multiline attribute in XML (default is true).

FindViewById<Button> is returning Null

So I am adding new button to my app but when FindViewById is called it returns null and app crashes. In my .cs file I have following function:
void fooUIButtonHandler()
{
var fooUIButton = FindViewById(Resource.Id.fooUIButton);
fooUIButton.Click += delegate
{
if (!CheckOriginalImage())
{
return;
}
Intent intent = new Intent(this, typeof(fooImageDemoActivity));
intent.PutExtra(fooImageDemoActivity.EXTRAS_ARG_IMAGE_FILE_URI,
originalImageUri.ToString());
StartActivityForResult(intent, REQUEST_SB_FOO_UI);
};
}
and my .axml file looks like this:
<Button
android:id="#+id/fooUIButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#0b8442"
style="#style/Widget.AppCompat.Button.Borderless"
android:text="foo"/>
I am setting Content View in OnCreate:
SetContentView(Resource.Layout.FooDocumentCreation);
and then calling:
fooUIButtonHandler()
But following line is throwing Null exception:
var fooUIButton = FindViewById(Resource.Id.fooUIButton);
Any ideas how to fix it?

Resources