I know this question is not new, but I am really stuck on this for days, and I need your support.
My problem is:
I can't take pictures in my prism xamarin forms project using the plugin media for Android (it works for selecting images from gallery though).
The Error I get is:
unable to get file location xam plugin media site
I would love to hear from you guys, and thanks in advance for your support.
Here i my code:
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.niternational.Hope" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<application android:label="Hope.Android" android:icon="#mipmap/ic_launcher">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.niternational.Hope.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
</manifest>
file_paths file on xml folder on Resources
<?xml version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Pictures" />
<external-files-path name="my_movies" path="Movies" />
</paths>
Main Activity
[Activity(Label = "Hope", Icon = "#mipmap/ic_launcher", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
CrossCurrentActivity.Current.Init(this, bundle);
LoadApplication(new App(new AndroidInitializer()));
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry container)
{
// Register any platform specific implementations
}
}
AssemblyInfo file
I have added:
[assembly: UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]
Code Behind
private async void TakeImage()
{
var actions = await Application.Current.MainPage.DisplayActionSheet("ActionSheet: Image?", "Cancel", null, "Take Picture", "From Gallery");
switch (actions)
{
case "Take Picture":
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsPickPhotoSupported)
{
var message = "No Camera available";
//DependencyService.Get<IMessage>().ShortAlert(message);
return;
}
var mediaOptions = new StoreCameraMediaOptions
{
Directory = "UploaDoc",
Name = $"{DateTime.UtcNow}.jpg",
SaveToAlbum = true,
CompressionQuality = 75,
CustomPhotoSize = 50,
PhotoSize = PhotoSize.MaxWidthHeight,
MaxWidthHeight = 2000,
DefaultCamera = CameraDevice.Front
};
// Take a photo of the business receipt.
var file = await CrossMedia.Current.TakePhotoAsync(mediaOptions);
if (file == null)
return;
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
return stream;
});
var memoryStream = new MemoryStream();
file.GetStream().CopyTo(memoryStream);
file.Dispose();
imgAsBytes = memoryStream.ToArray();
memoryStream.Dispose();
break;
case "From Gallery":
if (!CrossMedia.Current.IsPickPhotoSupported)
{
var message = "Picking image is not supported";
//DependencyService.Get<IMessage>().ShortAlert(message);
return;
}
var files = await CrossMedia.Current.PickPhotoAsync();
if (files == null)
return;
image.Source = ImageSource.FromStream(() =>
{
var stream = files.GetStream();
return stream;
});
var ms = new MemoryStream();
files.GetStream().CopyTo(ms);
files.Dispose();
imgAsBytes = ms.ToArray();
ms.Dispose();
break;
}
Related
I'm creating a mobile application using Xamarin forms, As part of my implementation, I have a requirement to to show file chooser on clicking on camera icon which is loaded in webView and load the image to webView. currently file chooser is being shown, but image is not getting added.
public override bool OnShowFileChooser(Android.Webkit.WebView webView, Android.Webkit.IValueCallback filePathCallback, FileChooserParams fileChooserParams) {
Intent takePictureIntent = new Intent(MediaStore.ActionImageCapture);
if (takePictureIntent.ResolveActivity(mContext.PackageManager) != null) {
Java.IO.File photoFile = null;
try {
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
photoFile = new Java.IO.File(folder, "image" + DateTime.Now.Millisecond + ".png");
takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
//photoFile = createImageFile();
//takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
} catch (Exception e) {
Console.WriteLine("catch the Exception" + e);
}
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
//pictureUri = FileProvider.GetUriForFile(mContext, "asdasd", photoFile);
takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput, photoFile);
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType(file_type);
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[] {
takePictureIntent
};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, "File chooser");
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
//mContext.StartActivity(chooserIntent);
mContext.StartActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
private Java.IO.File createImageFile() {
// Create an image file name
string timeStamp = Android.OS.SystemClock.CurrentThreadTimeMillis().ToString();
string imageFileName = "JPEG_" + timeStamp + "_";
Java.IO.File storageDir;
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Gingerbread) {
storageDir = mContext.CacheDir;
} else {
storageDir = mContext.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures);
}
//new Java.IO.File(mContext.GetExternalFilesDir(null).AbsolutePath);
Java.IO.File imageFile = Java.IO.File.CreateTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
At first, please add the following code into the AndroidManifest.xml to declare the permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.Read_EXTERNAL_STORAGE" />
And then request the permission in the MainActivity's construction method.
var read = await Permissions.RequestAsync<Permissions.StorageRead>();
var write = await Permissions.RequestAsync<Permissions.StorageWrite>();
Finally, please override the OnActivityResult method of the Mainactivity:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (data != null)
{
if (requestCode == INPUT_FILE_REQUEST_CODE)// the value of the INPUT_FILE_REQUEST_CODE
{
if (null == this.message)
{
return;
}
this.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
this.message = null;
}
}
}
I have a Xamarin Forms app that needs to capture audio from a webview. I have the following set in my manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.MICROPHONE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.audio.low_latency" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-feature android:name="android.hardware.audio.pro" />
<uses-permission android:name="android.webkit.resource.AUDIO_CAPTURE" />
I have the following in the android webview custom renderer
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
Control.Download += OnDownload;
Control.Settings.JavaScriptEnabled = true;
Control.Settings.SetGeolocationEnabled(true);
Control.Settings.SetGeolocationDatabasePath(Control.Context.FilesDir.Path);
Control.Settings.SetSupportZoom(false);
Control.Settings.AllowFileAccess = true;
Control.Settings.AllowContentAccess =true;
Control.Settings.LoadWithOverviewMode = true;
Control.Settings.SetPluginState(Android.Webkit.WebSettings.PluginState.On);
if (e.OldElement == null)
{
ResetCookieManagerSettings();
var chromeClient = new ArenaWebChromeClient((uploadMsg, acceptType, capture) =>
{
var webViewClient = new WebViewClient(this);
if (App.Self.IsConnected)
{
Control.SetWebChromeClient(chromeClient);
webViewClient.PageLoadStarted += RaiseLoadStarted;
webViewClient.PageLoadFinished += RaiseLoadFinished;
Control.SetWebViewClient(webViewClient);
}
else
{
webViewClient.PageLoadStarted -= RaiseLoadStarted;
webViewClient.PageLoadFinished -= RaiseLoadFinished;
}
}
}
This is all fine. My Chrome code for checking the permissions is this
public override void OnPermissionRequest(PermissionRequest request)
{
base.OnPermissionRequest(request);
if (request != null)
{
permissionRequest = request;
var res = request.GetResources();
if (res.Length != 0)
{
foreach(var r in res)
{
if (r.Contains("AUDIO_CAPTURE"))
{
Device.BeginInvokeOnMainThread(async () =>
{
var perms = await Permissions.CheckStatusAsync<Permissions.Media>();
if (perms != Xamarin.Essentials.PermissionStatus.Granted)
{
var request = await Permissions.RequestAsync<Permissions.Media>();
if (request == Xamarin.Essentials.PermissionStatus.Granted)
{
var mod = await Permissions.CheckStatusAsync<Permissions.Microphone>();
if (mod != Xamarin.Essentials.PermissionStatus.Granted)
{
var t = await Xamarin.Essentials.PermissionRequestAsync<Permissions.Media>();
#if DEBUG
Console.WriteLine("Microphone set");
#endif
}
}
}
else
{
var mod = await Permissions.CheckStatusAsync<Permissions.Microphone>();
if (mod != Xamarin.Essentials.PermissionStatus.Granted)
{
var t = await Xamarin.Essentials.Permissions.RequestAsync<Permissions.Media>();
#if DEBUG
Console.WriteLine("Microphone set");
#endif
}
}
});
}
}
}
}
}
This all works. However. when I try to record via the webview, I'm getting the following error.
chromium] [INFO:CONSOLE(76)] "The following error occurred: NotAllowedError: Permission denied", source: https://mywebsite/myurl (76)
I'm not sure if it's on the server side or app side as when the user on the website tries to record, a recording is made.
Is it possible or is there anyway that I can access the Microphone and use it to test my code?
I have enabled all of this in the extended controls of my emulator for microphone:
I also have these permissions in my AndroidManifest.xml:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
This is the code:
using System;
using System.ComponentModel;
using Plugin.AudioRecorder;
using Xamarin.Forms;
namespace AudioDemo
{
[DesignTimeVisible(true)]
public partial class MainPage : ContentPage
{
AudioRecorderService recorder;
AudioPlayer player;
public MainPage()
{
InitializeComponent();
recorder = new AudioRecorderService
{
StopRecordingAfterTimeout = true,
TotalAudioTimeout = TimeSpan.FromSeconds(15),
AudioSilenceTimeout = TimeSpan.FromSeconds(2)
};
player = new AudioPlayer();
player.FinishedPlaying += Finaliza_Reproducao;
}
async void Record_Clicked(object sender, EventArgs e)
{
try
{
if (!recorder.IsRecording)
{
recorder.StopRecordingOnSilence = TimeoutSwitch.IsToggled;
RecordButton.IsEnabled = false;
PlayButton.IsEnabled = false;
//Start recording
var audioRecordTask = await recorder.StartRecording();
RecordButton.Text = "Parar Gravação";
RecordButton.IsEnabled = true;
await audioRecordTask;
RecordButton.Text = "Record";
PlayButton.IsEnabled = true;
}
else
{
RecordButton.IsEnabled = false;
//stop recording ...
await recorder.StopRecording();
RecordButton.IsEnabled = true;
}
}
catch (Exception ex)
{
//blow up the app!
await DisplayAlert("Erro", ex.Message, "OK");
}
}
async void Play_Clicked(object sender, EventArgs e)
{
try
{
var filePath = recorder.GetAudioFilePath();
if (filePath != null)
{
PlayButton.IsEnabled = false;
RecordButton.IsEnabled = false;
player.Play(filePath);
}
}
catch (Exception ex)
{
//blow up the app!
await DisplayAlert("Error", ex.Message, "OK");
}
}
void Finaliza_Reproducao(object sender, EventArgs e)
{
PlayButton.IsEnabled = true;
RecordButton.IsEnabled = true;
}
}
}
This code works when I use a phone to run it, but when I just use (my laptop) emulator, it does not work.
Not able to record sound in the emulator because the android emulator doesn’t support it yet. This code should only work on the phone.
Note: The Android Emulator cannot record audio. Be sure to test your
code on a real device that can record.
This is the official document
https://developer.android.com/guide/topics/media/mediarecorder?hl=en
Please find the code below for the custom renderer for Android for segmented control. I copied this from one post in stack overflow. It works fine for IOS but fails for android. Anyone has any idea? Am i missing anything.
This is the event
protected override void OnElementChanged(ElementChangedEventArgs<SegmentedControl> e)
{
base.OnElementChanged(e);
var layoutInflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
var g = new RadioGroup(Context);
g.Orientation = Orientation.Horizontal;
g.CheckedChange += (sender, eventArgs) =>
{
var rg = (RadioGroup)sender;
if (rg.CheckedRadioButtonId != -1)
{
var id = rg.CheckedRadioButtonId;
var radioButton = rg.FindViewById(id);
var radioId = rg.IndexOfChild(radioButton);
var btn = (RadioButton)rg.GetChildAt(radioId);
var selection = (String)btn.Text;
e.NewElement.SelectedValue = selection;
}
};
for (var i = 0; i < e.NewElement.Children.Count; i++)
{
var o = e.NewElement.Children[i];
var v = (SegmentedControlButton)layoutInflater.Inflate(Resource.Layout.SegmentedControl, null);
//Error at this above line
v.Text = o.Text;
if (i == 0)
v.SetBackgroundResource(Resource.Drawable.segmented_control_first_background);
else if (i == e.NewElement.Children.Count - 1)
v.SetBackgroundResource(Resource.Drawable.segmented_control_last_background);
g.AddView(v);
}
SetNativeControl(g);
}
}
Its happening at this line.
var v = (SegmentedControlButton)layoutInflater.Inflate(Resource.Layout.SegmentedControl, null);
v.Text = o.Text;
Error
Android.Views.InflateException: Binary XML file line #1: Binary XML file line #1:
Error inflating class SegmentedControl.Android.SegmentedControlButton ---> Android.Views.InflateException:
Binary XML file line #1: Error inflating class SegmentedControl.Android.SegmentedControlButton ---> Java.Lang.ClassNotFoundException:
Didn't find class "SegmentedControl.Android.SegmentedControlButton" on path: DexPathList[[zip file "/data/app/com.mytestapp.myfirstapp-1/base.apk"],
nativeLibraryDirectories=[/data/app/com.mytestapp.myfirstapp-1/lib/x86, /data/app/com.mytestapp.myfirstapp-1/base.apk!/lib/x86, /vendor/lib, /system/lib]]
Try following SegmentControlRenderer. I have added required files as well.
Use following in your xaml file
<StackLayout BackgroundColor="#0A0E3F" Padding="10" Spacing="0" Grid.Row="0">
<local:CustomSegmentedControl SelectedValue="Offices" x:Name="segmentControl" HorizontalOptions="FillAndExpand">
<local:CustomSegmentedControl.Children>
<local:CustomSegmentedControlOption Text="Control1" />
<local:CustomSegmentedControlOption Text="Control2" />
<local:CustomSegmentedControlOption Text="Control3" />
</local:CustomSegmentedControl.Children>
</local:CustomSegmentedControl>
</StackLayout>
Make sure you place all these 7 files in proper directories. Do let me if anything comes up
SegmentedControlRenderer.cs (to be placed in Droid modules)
using System;
using Xamarin.Forms.Platform.Android;
using Android.Widget;
using Android.Content;
using Android.Util;
using Android.Graphics;
using Android.Views;
using System.Collections.Generic;
[assembly: Xamarin.Forms.ExportRenderer(typeof(App.CustomSegmentedControl), typeof(App.Droid.SegmentedControlRenderer))]
namespace App.Droid
{
public class SegmentedControlRenderer : ViewRenderer<CustomSegmentedControl, RadioGroup>
{
RadioGroup g = null;
List<CustomSegmentedControlButton> listSegmentControl = new List<CustomSegmentedControlButton>();
public SegmentedControlRenderer()
{
}
protected override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
if (listSegmentControl == null)
return;
foreach (var control in listSegmentControl)
{
control.SetWidth(Resources.DisplayMetrics.WidthPixels / listSegmentControl.Count);
}
}
protected override void OnElementChanged(ElementChangedEventArgs<TPSegmentedControl> e)
{
base.OnElementChanged(e);
var layoutInflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
g = new RadioGroup(Context);
g.Orientation = Orientation.Horizontal;
g.CheckedChange += (sender, eventArgs) =>
{
var rg = (RadioGroup)sender;
if (rg.CheckedRadioButtonId != -1)
{
var id = rg.CheckedRadioButtonId;
var radioButton = rg.FindViewById(id);
var radioId = rg.IndexOfChild(radioButton);
var btn = (RadioButton)rg.GetChildAt(radioId);
for (int i = 0; i < g.ChildCount; i++)
{
g.GetChildAt(i).SetBackgroundResource(Resource.Drawable.segment_control_option_bg);
}
btn.SetBackgroundResource(btn.Checked ? Resource.Drawable.segment_control_selected_option_bg : Resource.Drawable.segment_control_option_bg);
var selection = (String)btn.Text;
e.NewElement.SelectedValue = selection;
}
};
for (var i = 0; i < e.NewElement.Children.Count; i++)
{
var o = e.NewElement.Children[i];
var v = (TPSegmentedControlButton)layoutInflater.Inflate(Resource.Layout.SegmentedControl, null);
v.Text = o.Text;
int minWidth = Resources.DisplayMetrics.WidthPixels / e.NewElement.Children.Count;
v.SetWidth(minWidth);
v.SetBackgroundResource(v.Checked ? Resource.Drawable.segment_control_selected_option_bg : Resource.Drawable.segment_control_option_bg);
g.AddView(v);
listSegmentControl.Add(v);
}
try
{
g.GetChildAt(0).PerformClick();
}
catch (Exception ex)
{
}
SetNativeControl(g);
}
}
public class CustomSegmentedControlButton : RadioButton
{
private int lineHeightSelected;
private int lineHeightUnselected;
private Paint linePaint;
public CustomSegmentedControlButton(Context context) : this(context, null)
{
}
public CustomSegmentedControlButton(Context context, IAttributeSet attributes) : this(context, attributes, Resource.Attribute.segmentedControlOptionStyle)
{
}
public CustomSegmentedControlButton(Context context, IAttributeSet attributes, int defStyle) : base(context, attributes, defStyle)
{
Initialize(attributes, defStyle);
}
private void Initialize(IAttributeSet attributes, int defStyle)
{
var a = this.Context.ObtainStyledAttributes(attributes, Resource.Styleable.SegmentedControlOption, defStyle, Resource.Style.SegmentedControlOption);
var lineColor = Color.ParseColor("#4aa3f4");
linePaint = new Paint();
linePaint.Color = lineColor;
lineHeightUnselected = a.GetDimensionPixelSize(Resource.Styleable.SegmentedControlOption_lineHeightUnselected, 0);
lineHeightSelected = a.GetDimensionPixelSize(Resource.Styleable.SegmentedControlOption_lineHeightSelected, 0);
a.Recycle();
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
if (linePaint.Color != 0 && (lineHeightSelected > 0 || lineHeightUnselected > 0))
{
var lineHeight = Checked ? lineHeightSelected : lineHeightUnselected;
if (lineHeight > 0)
{
var rect = new Rect(0, Height - lineHeight, Width, Height);
canvas.DrawRect(rect, linePaint);
}
}
}
}
}
CustomSegmentedControl.cs (To be placed in shared app module)
using System;
using Xamarin.Forms;
using System.Collections.Generic;
namespace App
{
public class CustomSegmentedControl : View, IViewContainer<CustomSegmentedControlOption>
{
public IList<CustomSegmentedControlOption> Children { get; set; }
public TPSegmentedControl()
{
Children = new List<CustomSegmentedControlOption>();
}
public event ValueChangedEventHandler ValueChanged;
public delegate void ValueChangedEventHandler(object sender, EventArgs e);
private string selectedValue;
public string SelectedValue
{
get { return selectedValue; }
set
{
selectedValue = value;
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
}
}
public class CustomSegmentedControlOption : View
{
public static readonly BindableProperty TextProperty = BindableProperty.Create<CustomSegmentedControlOption, string>(p => p.Text, "");
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public TPSegmentedControlOption()
{
}
}
}
CustomSegmentedView.cs (To be placed in share app module)
using System;
using XLabs.Forms.Controls;
namespace App
{
public class CustomSegmentedView : SegmentedControlView
{
public ISegmentedControlView Listener { get; set;}
public CustomSegmentedView()
{
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == "SelectedItem") {
if (Listener == null)
return;
Listener.SegmentedControlOnValueChanged(SelectedItem);
}
}
}
public interface ISegmentedControlView {
void SegmentedControlOnValueChanged(int selectedIndex);
}
}
SegmentedControl.axml (To be placed in Droid/Resources/layout)
<?xml version="1.0" encoding="utf-8"?>
<App.Droid.CustomSegmentedControlButton
style="#style/SegmentedControlOption" />
attrs.xml (To be placed in Droid/Resources/values)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SegmentedControlOption">
<attr name="segmentedControlOptionStyle" format="string" />
<attr name="lineColor" format="color" />
<attr name="lineHeightUnselected" format="dimension" />
<attr name="lineHeightSelected" format="dimension" />
</declare-styleable>
<declare-styleable name="ScaleImageView">
</declare-styleable>
</resources>
segment_control_option_bg.xml (To be placed in Droid/Resources/layout)
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#4aa3f4" />
<stroke
android:width="0.5dp"
android:color="#0a0e3f" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
</shape>
segment_control_selected_option_bg.xml (To be placed in Droid/Resources/layout)
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#0271d5" />
<stroke
android:width="0.5dp"
android:color="#0a0e3f" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
</shape>
The problem was in the segmented control.axml i gave the wrong namespace.
<?xml version="1.0" encoding="utf-8"?>
<*MyFirstApp*.Droid.SegmentedControlButton
style="#style/SegmentedControlOption" />
It solved everything. #Needle in the haystack#
#user12345 i already have the correct code in post whatever you mentioned. Thank you for your neat explaination.
If I try to use the AppcombatToolbar (https://developer.xamarin.com/guides/android/user_interface/toolbar/part-3-toolbar-compatibility/) in a customoverlay the items in my toolbar are not displayed. I see the space of the toolbar but without buttons and text
This is my zxing usage:
var scanner = new ZXing.Mobile.MobileBarcodeScanner();
//Tell our scanner we want to use a custom overlay instead of the default
scanner.UseCustomOverlay = true;
//Inflate our custom overlay from a resource layout
View zxingOverlay = LayoutInflater.FromContext(this).Inflate(Resource.Layout.Master, null);
//Set our custom overlay
scanner.CustomOverlay = zxingOverlay;
//Start scanning!
var result = await scanner.Scan();
This my BaseActivity
[Activity(Label = "#string/app_name", MainLauncher = false, Icon = "#drawable/icon")]
public class MasterActivity : AppCompatActivity
{
LinearLayout content;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
base.SetContentView(Resource.Layout.Master);
// Create your application here
var toolbar = FindViewById<Toolbar>(Resource.Id.maintoolbar);
SetSupportActionBar(toolbar);
SupportActionBar.Title = GetString(Resource.String.app_name);
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
SupportActionBar.SetHomeButtonEnabled(true);
content = (LinearLayout)FindViewById(Resource.Id.content);
}
public override void SetContentView(int id)
{
LayoutInflater inflater = (LayoutInflater)BaseContext.GetSystemService(Context.LayoutInflaterService);
if (content != null)
{
inflater.Inflate(id, content);
}
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.topmenus, menu);
return base.OnCreateOptionsMenu(menu);
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
if(item.ItemId == Resource.Id.menu_logout)
{
Settings.UserName = null;
Settings.Password = null;
StartActivity(typeof(LoginActivity));
}
Toast.MakeText(this, "Action selected: " + item.TitleFormatted,
ToastLength.Short).Show();
return base.OnOptionsItemSelected(item);
}
}
And this my Base Layout:
<?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"
android:minWidth="25px"
android:minHeight="25px"
android:weightSum="1">
<include
android:id="#+id/maintoolbar"
layout="#layout/toolbar" />
<LinearLayout
android:id="#+id/content"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#android:color/transparent"/>
</LinearLayout>
Page with working Toolbar
Scanpage with no working toolbar