In my XAML file, I used scroll view for scroll down but it does not work I can not find any issue where I did a couple of extra things here one is I add pull to refresh nuget and use it and I create a theme content class and I inherited it with default content page. another command in content page is working but scroll view does not support
Here my Xaml file
<views:BaseContentPage.Content>
<ScrollView BackgroundColor="White">
<controls:PullToRefreshLayout x:Name="PullToRefreshLayout" IsPullToRefreshEnabled="True" RefreshCommand="RefreshPatientDetailsPage">
<StackLayout>
// some code
</StackLayout>
</controls:PullToRefreshLayout>
</ScrollView>
</views:BaseContentPage.Content>
this is the Base content page I create
public abstract class BaseContentPage : ContentPage
{
public readonly BaseViewModel BaseViewModel;
protected bool IsNavigated;
public BaseContentPage(BaseViewModel baseViewModel)
{
BaseViewModel = baseViewModel;
}
protected abstract override void OnAppearing();
protected override void OnDisappearing()
{
IsNavigated = true;
}
}
I think this scroll view does not work because of the NuGet I put or it's the base content page
for android, I used this customer render
public class SortPaneListViewRendererAndroid : ListViewRenderer
{
public SortPaneListViewRendererAndroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.VerticalScrollBarEnabled = false;
var listView = Control as Android.Widget.ListView;
listView.DividerHeight = 1;
}
}
}
The reason this was happening is because you are nesting scrollable controls, Removing one of them will solve the issue
Related
I have a xamarin forms application and I have inserted a webview inside the layout stack, the problem is that I have multiple pages and in each page the length of the content is different from the others.
I wanted to ask if there was a way to have the webview automatically adjust the height.
I have read other similar questions on the site, but I admit they seemed confusing to me.
This is my code xaml
<ContentPage.Content>
<StackLayout Padding="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Spacing="0" BackgroundColor="White">
<WebView
x:Name="wvSite"
VerticalOptions="FillAndExpand"
HeightRequest="2300" />
</StackLayout>
</ContentPage.Content>
You could reset the webview height according to the content height when loading page finished via custom renderer.
Android:
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))]
namespace App1.Droid
{
public class CustomWebViewRenderer : WebViewRenderer
{
public CustomWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
Control.SetWebViewClient(new CustomWebViewClient(e.NewElement));
}
}
internal class CustomWebViewClient : Android.Webkit.WebViewClient
{
private WebView webView;
public CustomWebViewClient(WebView webView)
{
this.webView = webView;
}
public async override void OnPageFinished(Android.Webkit.WebView view, string url)
{
if (webView != null)
{
int i = 10;
while (view.ContentHeight == 0 && i-- > 0)
await System.Threading.Tasks.Task.Delay(100);
webView.HeightRequest = view.ContentHeight;
}
base.OnPageFinished(view, url);
}
}
}
iOS:
[assembly: ExportRenderer(typeof(WebView),
typeof(CustomWebviewRenderer))]
namespace App1.iOS
{
public class CustomWebviewRenderer : WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
NavigationDelegate = new CustomWebviewNavigationDelegate();
}
}
internal class CustomWebviewNavigationDelegate : WKNavigationDelegate
{
[Export("webview:didFinishNavigation:")]
public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
//base.DidFinishNavigation(webView, navigation);
webView.Frame = new CoreGraphics.CGRect(0, 0, webView.ScrollView.ContentSize.Width, webView.ScrollView.ContentSize.Height);
}
}
}
I cant find solution about this orange color? Do i need to write a renderer or can change from resources in Android and IOS?
Yes,if you want to change ListView selecteditem background color, need to use custom render to do this in Xamarin.Forms.
In the PCL, create a class name is ExtendedViewCell which should inherit any ViewCell.
public class ExtendedViewCell : ViewCell
{
public static readonly BindableProperty SelectedBackgroundColorProperty =
BindableProperty.Create("SelectedBackgroundColor",
typeof(Color),
typeof(ExtendedViewCell),
Color.Default);
public Color SelectedBackgroundColor
{
get { return (Color)GetValue(SelectedBackgroundColorProperty); }
set { SetValue(SelectedBackgroundColorProperty, value); }
}
}
In Android project, create a class name as ExtendedViewCellRenderer and make sure to add renderer registration for our ExtendedViewCell class above the namespace.
[assembly: ExportRenderer(typeof(ExtendedViewCell), typeof(ExtendedViewCellRenderer))]
namespace demo3.Droid
{
public class ExtendedViewCellRenderer : ViewCellRenderer
{
private Android.Views.View _cellCore;
private Drawable _unselectedBackground;
private bool _selected;
protected override Android.Views.View GetCellCore(Cell item,
Android.Views.View convertView,
ViewGroup parent,
Context context)
{
_cellCore = base.GetCellCore(item, convertView, parent, context);
_selected = false;
_unselectedBackground = _cellCore.Background;
return _cellCore;
}
protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnCellPropertyChanged(sender, args);
if (args.PropertyName == "IsSelected")
{
_selected = !_selected;
if (_selected)
{
var extendedViewCell = sender as ExtendedViewCell;
_cellCore.SetBackgroundColor(extendedViewCell.SelectedBackgroundColor.ToAndroid());
}
else
{
_cellCore.SetBackground(_unselectedBackground);
}
}
}
}
}
Then you can set color for listview SelectedBackgroundColor.
<ListView ItemsSource="{Binding students}">
<ListView.ItemTemplate>
<DataTemplate>
<local:ExtendedViewCell SelectedBackgroundColor="White">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Username}" TextColor="Yellow" />
<Label Text="{Binding Age}" TextColor="Blue" />
</StackLayout>
</local:ExtendedViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
More detail info and steps in ios platform, you can take a look:
https://blog.wislon.io/posts/2017/04/11/xamforms-listview-selected-colour
Update:
In ios project, create a class name as ExtendedViewCellRenderer and make sure to add renderer registration for our ExtendedViewCell class above the namespace.
[assembly: ExportRenderer(typeof(ExtendedViewCell), typeof(ExtendedViewCellRenderer))]
namespace xamformsdemo.iOS
{
public class ExtendedViewCellRenderer : ViewCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
var view = item as ExtendedViewCell;
cell.SelectedBackgroundView = new UIView
{
BackgroundColor = view.SelectedBackgroundColor.ToUIColor(),
};
return cell;
}
}
}
I am working on a Xamarin.Forms application, and I want to set the height of a webview dynamically as pet text in uwp platform.
Define a Custom Renderer for your webview and then inject a javascript to calculate the content's size:
[assembly: ExportRenderer(typeof(CustomWebView), typeof(MyWebViewRenderer))]
namespace Demo.UWP
{
public class MyWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.NavigationCompleted += Control_NavigationCompleted;
}
}
private async void Control_NavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, Windows.UI.Xaml.Controls.WebViewNavigationCompletedEventArgs args)
{
var heightString = await Control.InvokeScriptAsync("eval", new[] { "document.body.scrollHeight.toString()" });
int height;
if (int.TryParse(heightString, out height))
{
Element.HeightRequest = height;
}
}
}
}
Your Forms page's Xaml could be like:
<ScrollView>
<StackLayout>
<local:CustomWebView Source="https://www.microsoft.com"/>
<!--Other controls-->
</StackLayout>
</ScrollView>
There is something different between the default WebViewRenderer and my custom ViewRenderer and I have to find out why. Basically, the web page isn't displayed if I use my custom ViewRenderer.
The ViewRenderer has some issues with height: 100%; and interprets this CSS wrong. As result the height is 0px, despite it should use the full height. On the other side it works with exact sizes (e.g. 400px).
Code for WebViewRenderer:
<local:CustomWebView x:Name="webView"
Source="http://somesite"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="1000"
WidthRequest="1000"/>
public class CustomWebView : WebView
{
}
public class CustomWebViewRenderer : WebViewRenderer
{
public CustomWebViewRenderer(Context context) : base(context)
{
}
}
Code for ViewRenderer:
<local:HybridWebView x:Name="webView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="1000"
WidthRequest="1000"/>
public class HybridWebView : View
{
}
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
private Context context;
public HybridWebViewRenderer(Context context) : base(context)
{
this.context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new Android.Webkit.WebView(this.context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new CustomWebViewClient());
SetNativeControl(webView);
}
if (e.OldElement != null)
{
}
if (e.NewElement != null)
{
Control.LoadUrl("http://somesite");
}
}
}
public class CustomWebViewClient : WebViewClient
{
}
One assumption is that the responsive website adapts to its WebView size, and since the rendering process takes place in background it somehow has a height of zero at this time.
I don't know why, but this solves the issue for me:
webView.LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
If anyone has a clue, please comment.
Xamarin.Forms: 3.0.0.550
Prism: 7.0.0.396
Here is my code snippet in App.xaml.cs :
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("NavigationPage/CoursesPage");
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<CoursesPage>();
containerRegistry.RegisterForNavigation<MainPage>();
containerRegistry.RegisterForNavigation<Content>();
}
After running I do not see NavigationBar on CoursesPage even if is set NavigationPage.HasBackButton="True" in xaml file.
Any idea what can be wrong?