I tried to use Zeroconf to get all the devices. When i called the ResolveAsync, the code got freezed.
I am running Xamarin Form on Android phone. It didn't produce any error or force close. It just stays there.
public async Task Update()
{
DeviceInfoStruct device;
string service = Constant.LAUNCHER_THRIFT_SERVICE + "local.";
int tried = 0;
List<DeviceInfoStruct> toDelete = new List<DeviceInfoStruct>();
foreach (var d in _devices)
{
toDelete.Add(d);
}
try
{
if (IsHotSpotIp())
{
device = LauncherClient.GetDeviceInfo(Constant.HOTSPOT_DEVICE_IP);
if (device != null)
{
device.Ip = Constant.HOTSPOT_DEVICE_IP;
if (!_devices.Any(d => d.Ip == device.Ip))
{
_devices.Add(device);
}
}
}
do
{
for (int i = 0; i < 5; i++)
{
foreach (var r in await ZeroconfResolver.ResolveAsync(service))
{
if (r.Services.ContainsKey(service))
{
device = LauncherClient.GetDeviceInfo(r.IPAddress);
if (device != null)
{
device.Ip = r.IPAddress;
if (!_devices.Any(d => d.Ip == device.Ip))
{
Debug.WriteLine("Found Device " + device.DeviceName + " # " + device.Ip);
_devices.Add(device);
toDelete.RemoveAll(d => d.Ip == device.Ip);
}
}
}
}
}
tried++;
} while ((tried < 2) && (_devices.Count == 0));
foreach (var d in toDelete)
{
if (LauncherClient.GetDeviceInfo(d.Ip) == null)
{
_devices.Remove(d);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Locks from GitHub
buttonHosting.Command = new Command( () =>
{
#if __ANDROID__
var wifi = (Android.Net.Wifi.WifiManager)Android.App.Application.Context.GetSystemService(Android.Content.Context.WifiService);
var mlock = wifi.CreateMulticastLock("Zeroconf lock");
try
{
mlock.Acquire();
var deviceModel = new DevicesViewModel();
var devices = deviceModel.GetAvailableDevicesAsync().Result;
foreach (var device in devices)
{
System.Diagnostics.Debug.WriteLine("Device Info: Name = " + device.DeviceName);
System.Diagnostics.Debug.WriteLine(" Version = " + device.DeviceVersion);
}
}
finally
{
mlock.Release();
}
#endif
//await Navigation.PushAsync(new MeetingPage(), true);
});
The code below will just print a list of devices
ILookup<string, string> domains = await ZeroconfResolver.BrowseDomainsAsync();
var responses = await ZeroconfResolver.ResolveAsync(domains.Select(g => g.Key));
foreach (var resp in responses)
Console.WriteLine(resp);
I can only see other devices' but not the one I wanted to look at...
Related
How to load RadComboBoxItemData[] from Web APi in aspx?
In Web API:
public RadComboBoxItemData[] ABC(object context)
{
List<RadComboBoxItemData> result = null;
...
return result.ToArray();
}
Following is the code that I have used with great success.
<telerik:RadComboBox runat="server" ID="comboSearch"
Width="350" Height="300"
EnableLoadOnDemand="true" ShowMoreResultsBox="true"
EnableVirtualScrolling="true"
EmptyMessage="Search Names..."
ItemsPerRequest="100">
<WebServiceSettings Method="GetNames"
Path="../../webservices/NamesWS.asmx">
</WebServiceSettings>
</telerik:RadComboBox>
Following is the custom web service I wrote for our use case.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using Telerik.Web.UI;
namespace Webservices
{
[ScriptService]
public class NamesWS : WebService
{
[WebMethod]
public RadComboBoxData GetNames(RadComboBoxContext context)
{
RadComboBoxData comboBoxData = null;
if (!string.IsNullOrEmpty(context.Text) && !string.IsNullOrWhiteSpace(context.Text))
{
using (DbConn db = new DbConn())
{
int max_ret_count = 100;
List<Users> Users = db.Users
.Where(u => u.Users.Contains(context.Text.Trim()))
.Take(max_ret_count).ToList();
if (Users == null)
{
comboBoxData = new RadComboBoxData();
List<RadComboBoxItemData> result = new List<RadComboBoxItemData>(1);
RadComboBoxItemData item = new RadComboBoxItemData();
item.Text = "";
item.Value = "";
result.Add(item);
comboBoxData.Items = result.ToArray();
}
else
{
List<RadComboBoxItemData> result = new List<RadComboBoxItemData>(context.NumberOfItems);
comboBoxData = new RadComboBoxData();
try
{
int itemsPerRequest = Convert.ToInt32(max_ret_count);
int itemOffSet = context.NumberOfItems;
int endOffSet = itemOffSet + itemsPerRequest;
if (endOffSet > Users.Count)
{
endOffSet = Users.Count;
}
if (endOffSet == Users.Count)
{
comboBoxData.EndOfItems = true;
}
else
{
comboBoxData.EndOfItems = false;
}
result = new List<RadComboBoxItemData>(endOffSet - itemOffSet);
for (int i = itemOffSet; i < endOffSet; i++)
{
RadComboBoxItemData itemData = new RadComboBoxItemData();
itemData.Text = Users[i].UserName;
itemData.Value = Users[i].UserID;
result.Add(itemData);
}
if (Users.Count > 0)
{
comboBoxData.Message = String.Format("Items <b>1</b>-<b>{0}</b> out of <b>{1}</b>"
, endOffSet.ToString()
, Users.Count.ToString());
}
else
{
comboBoxData.Message = "No matches";
}
comboBoxData.Items = result.ToArray();
}
catch (Exception ex)
{
ins_error_log err = new ins_error_log();
err.runSP(ex, false);
}
}
}
}
else
{
comboBoxData = new RadComboBoxData();
List<RadComboBoxItemData> result = new List<RadComboBoxItemData>(1);
RadComboBoxItemData item = new RadComboBoxItemData();
item.Text = "";
item.Value = "";
result.Add(item);
comboBoxData.Items = result.ToArray();
}
return comboBoxData;
}
}
}
I am trying to programmatically send a Mail/Task/Appointment to a user and I have the problem, that every time I send them the first one will get stuck in my outbox... It seems that the first one sent to Outlook has no/looses its sent-date and will stay forever in my outbox.
Here is the code for example "sending a task notification"
using (MapiSession session = new MapiSession())
{
var item = session.CreateItem(Outlook.OlItemType.olTaskItem) as RDOTaskItem;
[..]
try
{
item.Subject = "SUBJECT";
item.Body = "BODY;
item.StartDate = DateTime.Now;
item.DueDate = DateTime.Now;
item.Recipients.Add("test#mail.com");
item.Recipients.Add("test2#mail.com");
item.Recipients.ResolveAll();
item.Assign();
item.Save();
item.Send();
}
[..]
}
Thanks in advance.
So I am not really shure what is the problem so far...
If all receivers are other persons then myself this should work...
Here is my code for sendig a TaskItem
private void NotifyByTask(OutlookNotificationTypes notificationType)
{
Application app = new Application();
var item = app.CreateItem(OlItemType.olTaskItem) as TaskItem;
try
{
item.Subject = this.Subject;
item.Body = this.Body;
if (this.Start != DateTime.MinValue)
{
item.StartDate = this.Start;
item.ReminderSet = true;
item.ReminderPlaySound = true;
item.ReminderTime = this.Start.AddMinutes(-5);
}
if (this.End != DateTime.MinValue)
{
item.DueDate = this.End;
}
item.PercentComplete = this.PercentComplete;
StringBuilder categories = new StringBuilder();
foreach (String category in this.Categories)
{
categories.Append(category);
}
item.Categories = categories.ToString();
bool sendingToMyself = false;
if (this.NotificationType == OutlookNotificationTypes.TaskRequest)
{
// this will add all recipients and checks if Receiver is yourself
sendingToMyself = item.AddRecipients(this.Recipients, OlMailRecipientType.olTo);
}
if (this.NotificationType == OutlookNotificationTypes.TaskRequest
&& (!sendingToMyself))
{
item.Recipients.ResolveAll();
item.Assign();
item.Save();
item.Send();
}
else
{
item.Save();
//insert element
if (this.ItemSaved != null)
{
Microsoft.Office.Interop.Outlook.MAPIFolder folder =
item.Parent as Microsoft.Office.Interop.Outlook.MAPIFolder;
if (folder != null)
{
try
{
String storeId = folder.StoreID;
String entryId = item.EntryID;
this.ItemSaved(storeId, entryId);
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(folder);
}
}
}
}
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(item);
}
}
I have an requirement where the user should be able to load more data when the end of recycleview has reached,something like lazy loading.I am able to implement this functionality with the help of this link ,but everytime I reach the bottom and load more data the recycleview item starts from top and I Have to scroll to bottom to view the items.
Here is my code:
private async void DisplayCurrentYearData()
{
//current year
try
{
if (oStaticVariables.bIsConnected == true)
{
CurrentYear.StartIndex = 1;
CurrentYear.EndIndex = 20;
var oActCurYrData = await oWebApiService.GetCurrentYearList(oStaticVariables.MembershipID);
//var oActCurYrData = await oWebApiService.GetMembersLastYearData(new Commom.Files.Models.Member() { MembershipID = Convert.ToInt32(oStaticVariables.MembershipID) });
if (oActCurYrData != null && oActCurYrData.Count != 0)
{
this.listItems = new List<DataType>();
foreach (Commom.Files.Models.YearlyData x in oActCurYrData.ToList())
{
LogbookGroupData g1 = new LogbookGroupData(x.EventDescription, x.ActivityDescription);
if (x.Status == "1")
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Submitted");
g1.items.Add(e11);
}
else if (x.Status == "2")
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Awarded");
g1.items.Add(e11);
}
else if (x.Status == "3")
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Declined");
g1.items.Add(e11);
}
else
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Forwarded To Vetting Team");
g1.items.Add(e11);
}
listItems.Add(g1);
}
oStaticVariables.MyActivityYearlyData = oActCurYrData;
if (Activity != null)
{
this.recyclerAdapterCY = new LogbookCurrentYearRecycleViewAdaptor(Activity, listItems);
this.recyclerAdapterCY.GroupClickCurrent += OnGroupClickCurrent;
this.mLayoutManager = new LinearLayoutManager(Activity);
var onScrollListener = new RecyclerViewOnScrollListenerCY(this.mLayoutManager);
onScrollListener.LoadMoreEvent += (object sender, EventArgs e) =>
{
//Load more stuff here
LoadMoreCurrentYearData();
};
recyclerViewCY.AddOnScrollListener(onScrollListener);
this.recyclerViewCY.SetLayoutManager(mLayoutManager);
this.recyclerViewCY.SetAdapter(recyclerAdapterCY);
}
}
else {
}
}
}
catch (Exception ex)
{
}
}
private async void LoadMoreCurrentYearData()
{
CurrentYear.IsLoading = true;
CurrentYear.StartIndex = CurrentYear.EndIndex + 1;
CurrentYear.EndIndex = CurrentYear.EndIndex + 5;
//current year
try
{
txtTotalPoints.Visibility = ViewStates.Gone;
if (oStaticVariables.bIsConnected == true)
{
ShowSpinner();
var oActCurYrData = await oWebApiService.GetCurrentYearList(oStaticVariables.MembershipID);
//var oActCurYrData = await oWebApiService.GetMembersLastYearData(new Commom.Files.Models.Member() { MembershipID = Convert.ToInt32(oStaticVariables.MembershipID) });
if (oActCurYrData != null && oActCurYrData.Count != 0)
{
this.listItemsNew = new List<DataType>();
foreach (Commom.Files.Models.YearlyData x in oActCurYrData.ToList())
{
LogbookGroupData g1 = new LogbookGroupData(x.EventDescription, x.ActivityDescription);
if (x.Status == "1")
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Submitted");
g1.items.Add(e11);
}
else if (x.Status == "2")
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Awarded");
g1.items.Add(e11);
}
else if (x.Status == "3")
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Declined");
g1.items.Add(e11);
}
else
{
LogbookEntryData e11 = new LogbookEntryData(x.FormattedDate, x.Points, "Forwarded To Vetting Team");
g1.items.Add(e11);
}
listItemsNew.Add(g1);
}
listItems.AddRange(listItemsNew);
//oStaticVariables.MyActivityYearlyData = oActCurYrData;
if (Activity != null)
{
this.recyclerAdapterCY = new LogbookCurrentYearRecycleViewAdaptor(Activity, listItems);
this.recyclerAdapterCY.GroupClickCurrent += OnGroupClickCurrent;
this.recyclerViewCY.SetAdapter(recyclerAdapterCY);
HideSpinner();
CurrentYear.IsLoading = false;
}
}
else
{
HideSpinner();
CurrentYear.IsLoading = false;
}
}
}
catch (Exception ex)
{
}
}
Here is my RecyclerViewOnScrollListenerCY class:
public class RecyclerViewOnScrollListenerCY : RecyclerView.OnScrollListener
{
public delegate void LoadMoreEventHandler(object sender, EventArgs e);
public event LoadMoreEventHandler LoadMoreEvent;
private LinearLayoutManager LayoutManager;
public RecyclerViewOnScrollListenerCY(LinearLayoutManager layoutManager)
{
LayoutManager = layoutManager;
}
public override void OnScrolled(RecyclerView recyclerView, int dx, int dy)
{
base.OnScrolled(recyclerView, dx, dy);
var visibleItemCount = recyclerView.ChildCount;
var totalItemCount = recyclerView.GetAdapter().ItemCount;
var pastVisiblesItems = LayoutManager.FindFirstVisibleItemPosition();
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount && !CurrentYear.IsLoading)
{
LoadMoreEvent(this, null);
}
}
}
Can somebody point out my mistake in the code.Please help
According to your description, you want to scroll and not reset position to the top for recycleview every time.
Originally I was creating a new Adapter when the data changed. The adapter base class will automatically clear the contents of the data calling .Clear(). This causes the scroll view to go to the top each time.
To avoid the .Clear() you need to not create a new instance of the adapter and just call Adapter.NotifyDataSetChanged() and the scroll view will not refresh to top every time data refreshes.
https://developer.xamarin.com/api/member/Android.Widget.BaseAdapter.NotifyDataSetChanged/
I have an forms app where i need to pick "1 to many" images from the phone storage.
For this i use the dependency injection system.
My problem is the somewhere i get an Android.netUri that resolves to a file that do not exist... and to a file name that i have never seen before.
The kicker is that if i pick pictures that was takes within the last couple of hours this code works...
Im am at the end of my hoap, i really hope someone can point me to something that i'm doing wrong.
i start the Picker activity with:
[assembly: Dependency(typeof(ImagePickerService))]
namespace MyApp.Droid
{
public class ImagePickerService : Java.Lang.Object, IImagePickerService
{
public async Task OpenGallery()
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage))
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Need Storage permission to access to your photos.", ToastLength.Long).Show();
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Storage });
status = results[Permission.Storage];
}
if (status == PermissionStatus.Granted)
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Pick max 20 images", ToastLength.Long).Show();
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionPick);
CrossCurrentActivity.Current.Activity.StartActivityForResult(Intent.CreateChooser(imageIntent, "Pick pictures"), 100);
}
else if (status != PermissionStatus.Unknown)
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Permission Denied. Can not continue, try again.", ToastLength.Long).Show();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Error. Can not continue, try again.", ToastLength.Long).Show();
}
}
}
then in my MainActivity.cs i have the OnActivityResult
I have tried to use the ContentResolver.OpenInputStream to get the image bytes with no luck, so this is commented out atm.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
/*
var stream = ContentResolver.OpenInputStream(item.Uri); //This throws "FileNotFound"
byte[] byteArray;
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byteArray = memoryStream.ToArray();
stream.Close();
stream = null;
}
stream = ContentResolver.OpenInputStream(item.Uri);
var exif = new ExifInterface(stream);
stream.Close();
*/
Android.Net.Uri uri = item.Uri;
var path = GetActualPathFromFile(uri);
if (path != null)
{
var tmpImgPath = RotateToOriginalDimention(path);
images.Add(tmpImgPath);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetActualPathFromFile(uri);
if (path != null)
{
var tmpImgPath = RotateToOriginalDimention(path);
images.Add(tmpImgPath);
}
}
MessagingCenter.Send<App, List<string>>((App)Xamarin.Forms.Application.Current, "ImagesSelected", images);
}
}
}
And the GetActualPathFromFile (also in my MainActivity.cs)
The hole func is below but i hit this part of the code and get at "FileNotFound"
(...)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
var retval2 = getDataColumn(this, uri, null, null);
if (File.Exists(retval2)) //<----------------------- This returns "false"
{
return retval2;
}
else
{
throw new Exception("file not found " + retval2);
}
}
(...)
The Hole GetActualPathFromFile
private string GetActualPathFromFile(Android.Net.Uri uri)
{
bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;
if (isKitKat && DocumentsContract.IsDocumentUri(this, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
string docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
string[] split = docId.Split(chars);
string type = split[0];
if ("primary".Equals(type, StringComparison.OrdinalIgnoreCase))
{
var retval = Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
string id = DocumentsContract.GetDocumentId(uri);
Android.Net.Uri contentUri = ContentUris.WithAppendedId(
Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));
//System.Diagnostics.Debug.WriteLine(contentUri.ToString());
var retval = getDataColumn(this, contentUri, null, null);
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
// MediaProvider
else if (isMediaDocument(uri))
{
String docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
String[] split = docId.Split(chars);
String type = split[0];
Android.Net.Uri contentUri = null;
if ("image".Equals(type))
{
contentUri = MediaStore.Images.Media.ExternalContentUri;
}
else if ("video".Equals(type))
{
contentUri = MediaStore.Video.Media.ExternalContentUri;
}
else if ("audio".Equals(type))
{
contentUri = MediaStore.Audio.Media.ExternalContentUri;
}
String selection = "_id=?";
String[] selectionArgs = new String[]
{
split[1]
};
var retval = getDataColumn(this, contentUri, selection, selectionArgs);
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
}
// MediaStore (and general)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
// Return the remote address
if (isGooglePhotosUri(uri))
{
var retval = uri.LastPathSegment;
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
var retval2 = getDataColumn(this, uri, null, null);
if (File.Exists(retval2))
{
return retval2;
}
else
{
throw new Exception("file not found " + retval2);
}
}
// File
else if ("file".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
var retval = uri.Path;
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
throw new Exception("file not found ");
}
public static String getDataColumn(Context context, Android.Net.Uri uri, String selection, String[] selectionArgs)
{
ICursor cursor = null;
String column = "_data";
String[] projection =
{
column
};
try
{
cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.MoveToFirst())
{
int index = cursor.GetColumnIndexOrThrow(column);
return cursor.GetString(index);
}
}
finally
{
if (cursor != null)
cursor.Close();
}
return null;
}
//Whether the Uri authority is ExternalStorageProvider.
public static bool isExternalStorageDocument(Android.Net.Uri uri)
{
return "com.android.externalstorage.documents".Equals(uri.Authority);
}
//Whether the Uri authority is DownloadsProvider.
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
return "com.android.providers.downloads.documents".Equals(uri.Authority);
}
//Whether the Uri authority is MediaProvider.
public static bool isMediaDocument(Android.Net.Uri uri)
{
return "com.android.providers.media.documents".Equals(uri.Authority);
}
//Whether the Uri authority is Google Photos.
public static bool isGooglePhotosUri(Android.Net.Uri uri)
{
return "com.google.android.apps.photos.content".Equals(uri.Authority);
}
Found out that the real problem was that Google Photos App was not updating and was still showing images that were deleted.
After 2x reboot of the phone, Google Photos app finally updated.
So this looks more like a cache problem with Google Foto than a xamarin problem.
I have the following code in iOS renderer:
public class TabbedPageRenderer : TabbedRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
try
{
var tabbarController = (UITabBarController)this.ViewController;
if (null != tabbarController)
{
tabbarController.ViewControllerSelected += OnTabBarReselected;
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
void OnTabBarReselected(object sender, UITabBarSelectionEventArgs e)
{
var tabs = Element as TabbedPage;
var playTab = tabs.Children[4];
if (TabBar.SelectedItem.Title == "Play")
{
if (tabs != null)
{
playTab.Title = "Pause";
playTab.Icon = "ionicons_2_0_1_pause_outline_22.png";
}
App.pauseCard = false;
}
else
{
if (tabs != null)
{
playTab.Title = "Play";
playTab.Icon = "ionicons_2_0_1_play_outline_25.png";
}
App.pauseCard = true;
}
}
}
What this do is let the user pause/play a timer running in a page. When opening the app, Home tab will be open so the Play icon is displayed. But when switching to the Play tab, by default the timer is running so the Pause title and icon is displayed.
The code above works perfectly for iOS. But I am still lost in Android. I have tried the following code for Android:
public class MyTabbedPageRenderer: TabbedPageRenderer, TabLayout.IOnTabSelectedListener
{
void TabLayout.IOnTabSelectedListener.OnTabReselected(TabLayout.Tab tab)
{
var tabs = Element as TabbedPage;
var playTab = tabs.Children[4];
var selectedPosition = tab.Position;
if(selectedPosition == 4)
{
if (playTab.Title == "Play")
{
if (tabs != null)
{
playTab.Title = "Pause";
playTab.Icon = "ionicons_2_0_1_pause_outline_22.png";
}
App.pauseCard = false;
}
else
{
if (tabs != null)
{
playTab.Title = "Play";
playTab.Icon = "ionicons_2_0_1_play_outline_25.png";
}
App.pauseCard = true;
}
}
}
}
Obviously this would only work when reselecting the tab. Would really appreciate if someone could point me to the right direction here.
Like #G.hakim, you also need add TabLayout.IOnTabSelectedListener.OnTabSelected method, and it will be same as OnTabReselected:
void TabLayout.IOnTabSelectedListener.OnTabSelected(TabLayout.Tab tab)
{
var tabs = Element as TabbedPage;
var playTab = tabs.Children[4];
var selectedPosition = tab.Position;
if(selectedPosition == 4)
{
if (playTab.Title == "Play")
{
if (tabs != null)
{
playTab.Title = "Pause";
playTab.Icon = "ionicons_2_0_1_pause_outline_22.png";
}
App.pauseCard = false;
}
else
{
if (tabs != null)
{
playTab.Title = "Play";
playTab.Icon = "ionicons_2_0_1_play_outline_25.png";
}
App.pauseCard = true;
}
}
}