Xamarin.Forms HybridWebView zoom (Android) - android

I created a WebViewPage class that inherits from HybridWebView
Now I need to implement the zoom but I can not find the string that allows to do
code:
public class WebViewPage : HybridWebView
{
...code
}
protected override void OnStart()
{
var webView = Container.GetInstance<WebViewPage>();
webView.LoadFromContent("index.html");
...code
}
how I enable pinch to zoom?

You will need to modify the source and set the appropriate WebKit zoom settings.
re: setBuiltInZoomControls
In the HybridWebViewRenderer.cs you need to turn on BuiltInZoomControls
and turn the visual zoom controls (DisplayZoomControls) off (if not desired).
webView.Settings.BuiltInZoomControls = true;
webView.Settings.DisplayZoomControls = false;

Related

ScrollView Custom renderer no longer working on Xamarin Forms 2.x

Want to add simple paging to ScrollView.
On iOS it was easy adding a customer renderer like this:
[assembly:ExportRenderer (typeof(ScrollView), typeof(JustEat.Ordertracker.Touch.Renderers.ExtendedScrollViewRenderer))]
namespace JustEat.Ordertracker.Touch.Renderers
{
public class ExtendedScrollViewRenderer : ScrollViewRenderer
{
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
base.OnElementChanged (e);
UIScrollView iosScrollView = (UIScrollView)NativeView;
iosScrollView.PagingEnabled = true;
iosScrollView.ShowsHorizontalScrollIndicator = false;
}
}
}
So doesn't look like android has paging flag so was going to implement with touch events or similar, but can't get any events to trigger on Android side. So have tried hooking up events and overriding:
[assembly:ExportRenderer (typeof(ScrollView), typeof(JustEat.Ordertracker.Touch.Renderers.ExtendedScrollViewRenderer))]
namespace JustEat.Ordertracker.Touch.Renderers
{
public class ExtendedScrollViewRenderer : ScrollViewRenderer
{
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
base.OnElementChanged (e);
global::Android.Widget.ScrollView droidScrollView = (global::Android.Widget.ScrollView)this;
droidScrollView.HorizontalScrollBarEnabled = false;
droidScrollView.Drag += delegate
{
Console.WriteLine("Drag");
};
}
public override bool OnTouchEvent(global::Android.Views.MotionEvent ev)
{
Console.WriteLine("OnTouchEvent");
return base.OnTouchEvent(ev);
}
}
}
The OnElementChanged definitely gets called as I hit a breakpoint, but the events do nothing, neither does setting HorizontalScrollBarEnabled to false, or even setting .Enabled to false. It's like I have access to a different object?
Found an excellent git repo using same technique to do same thing
https://github.com/chrisriesgo/xamarin-forms-carouselview/issues/24
which works great with 1.x version of forms it uses, but upgrade it to 2.x and it no longer works for above reason.

Getting "Link text" of the link displayed in WebView

I have Android WebView which displays some links as: Link1TextLink2Text Now I would like to retrieve Link1Text and Link2Text when I long press these links. I have contextMenu implemented in the code and I could successfully get the link urls (http://link1.html, http://link2.html) using HitTestResult getExtra() method but how ccan I get those link texts ?FYI, I require those link texts for implementing "Copy link text" option in the contextMenu.
To get the text of an achor link:
I. Hook a touchstart listener to every web pages in the onPageFinished() callback of WebViewClient via evaluateJavascript. like:
//Javascripts to evaluate in onPageFinished
const w=window;
w.addEventListener('touchstart',wrappedOnDownFunc);
function wrappedOnDownFunc(e){
if(e.touches.length==1){
w._touchtarget = e.touches[0].target;
}
console.log('hey touched something ' +w._touchtarget);
}
note we've saved the touch target.
II. Then implement OnLongClicklisenter for webview. use evaluateJavascript again when you long pressed on a link object:
#Override
public boolean onLongClick(View v) {
WebView.HitTestResult result = ((WebView)v).getHitTestResult();
if (null == result) return false;
int type = result.getType();
switch (type) {
case WebView.HitTestResult.SRC_ANCHOR_TYPE:
if(result.getExtra()!=null){
((WebView)v).evaluateJavascript("window._touchtarget?window._touchtarget.innerText:''", new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
System.out.println("hey received link text : "+value);
}
});
}
return true;
}
return false;
}
What's more, we can even choose to select the text of the anchor element! Actually this is one of the options that samsung browser offers when you long-pressed an tag .
To achieve this, we still need that recorded touch target. Besides we need 2 new javascript methods:
function selectTouchtarget(){
var tt = w._touchtarget;
if(tt){
w._touchtarget_href = tt.getAttribute("href");
tt.removeAttribute("href");
var sel = w.getSelection();
var range = document.createRange();
range.selectNodeContents(tt);
sel.removeAllRanges();
sel.addRange(range);
}
}
function restoreTouchtarget(){
var tt = w._touchtarget;
if(tt){
tt.setAttribute("href", w._touchtarget_href);
}
}
Finnaly in the onLongClick listener, instead of just fetch the innerText, we programmatically set the selection, trigger the action menu bar, and restore the removed href attribute of our touch target.
case WebViewmy.HitTestResult.SRC_ANCHOR_TYPE:
if(result.getExtra()!=null){
WebViewmy mWebView = ((WebViewmy)v);
mWebView.evaluateJavascript("selectTouchtarget()", new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
/* bring in action mode by a fake click on the programmatically selected text. */
MotionEvent te = MotionEvent.obtain(0,0,KeyEvent.ACTION_DOWN,mWebView.lastX,mWebView.lastY,0);
mWebView.dispatchTouchEvent(te);
te.setAction(KeyEvent.ACTION_UP);
mWebView.dispatchTouchEvent(te);
te.recycle();
//if it's not delayed for a while or the href attribute is not removed, then the above code would click into
// the anchor element instead of select it's text.
/* restore href attribute */
mWebView.postDelayed(() -> mWebView.evaluateJavascript("restoreTouchtarget()", null), 100);
}
});
}
return true;
In my case, I've extended the WebView as WebViewmy to record last touched positions, lastX and lastY, in the onTouchEvent method.
Unfortunately, a clear, official way to do this is not available. Although, there are two APIs (selectText and copySelection) which are pending API council approval, that may help to do this, but they are not available at the moment.

Disable Panning and Zooming on Teechart Monodroid

I have created a class that inherits from Steema.TeeChart.TChart I am trying to disable panning and zooming, I have the below code but it still allows the user to pan and zoom on the device.
public class BaseChart : TChart
{
public BaseChart(Context context, string headerTitle)
: base(context)
{
_headerTitle = headerTitle;
SetDefaults();
}
private void SetDefaults()
{
Chart.Zoom.Allow = false;
Chart.Panning.Allow = ScrollModes.None;
Zoom.Allow = false;
Panning.Allow = ScrollModes.None;
}
}
TeeChart .NET standard zoom & scrolling is not working at the present moment in the Mono for Android version. We plan supporting it in future releases feature request being TM63016321 in our issue tracking system. Recently we implemented a new feature for MfA which disables both zooming and scrolling:
tChart1.Zoom.Style = Steema.TeeChart.ZoomStyles.None;
UPDATE: A new Zoom.Style option has been implemented: ZoomStyles.Classic. Now you can choose if you want to toggle zooming, panning and which directions are supported for both. A maintenance release has been published supporting that. The new version explains how to use ZoomStyles.Classic in the zooming/panning tutorial included, for example:
tChart1.Zoom.Allow = true;
tChart1.Zoom.Direction = Steema.TeeChart.ZoomDirections.Both;
tChart1.Panning.Allow = Steema.TeeChart.ScrollModes.Horizontal;

touch the screen and add a marker in android

I want add a marker when I touch the screen. I use osmdroid and no google map.
Moreover, I want get back coordinate of this marker.
for the moment, I can display the osm map and display the location of the user.
thanks !
You can use MapEventsReceiver.
First make sure you have
implementation 'org.osmdroid:osmdroid-mapsforge:6.1.6'
in your build gradle (or newer version).
Then you make you OSMDroid class implement it
public class OSMapClass implements MapEventsReceiver {
// Your map implementation here
#Override
public boolean singleTapConfirmedHelper(GeoPoint p) {
// Here implement single click behaviour
return false;
}
#Override
public boolean longPressHelper(GeoPoint p) {
// Here implement long click behaviour
return false;
}
}

Android: Disable text selection in a webview

I am using a webview to present some formatted stuff in my app. For some interaction (which are specific to certain dom elements) I use javascript and WebView.addJavascriptInterface(). Now, I want to recognize a long touch. Unfortunately, onLongTouch, in Android 2.3 the handles for text selection are displayed.
How can I turn off this text selection without setting the onTouchListener and return true? (Then, the interaction with the "website" doesn't work anymore.
This worked for me
mWebView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return true;
}
});
mWebView.setLongClickable(false);
I have not tested, if you don't want the vibration caused by the long click, you can try this:
mWebView.setHapticFeedbackEnabled(false);
Setting webkit css property -webkit-user-select to none would solve the problem.
Example CSS to disable selection:
* {
-webkit-user-select: none;
}
I figured it out!! This is how you can implement your own longtouchlistener. In the function longTouch you can make a call to your javascript interface.
var touching = null;
$('selector').each(function() {
this.addEventListener("touchstart", function(e) {
e.preventDefault();
touching = window.setTimeout(longTouch, 500, true);
}, false);
this.addEventListener("touchend", function(e) {
e.preventDefault();
window.clearTimeout(touching);
}, false);
});
function longTouch(e) {
// do something!
}
This works.
It appears that cut/paste via long press is turned off if you used
articleView.setWebChromeClient(new WebChromeClient(){...})
See https://bugzilla.wikimedia.org/show_bug.cgi?id=31484
So if you are using setChromeClient and you WANT to have long click to start copy/paste, the do the following:
webView.setWebChromeClient(new WebChromeClient(){
[.... other overrides....]
// #Override
// https://bugzilla.wikimedia.org/show_bug.cgi?id=31484
// If you DO NOT want to start selection by long click,
// the remove this function
// (All this is undocumented stuff...)
public void onSelectionStart(WebView view) {
// By default we cancel the selection again, thus disabling
// text selection unless the chrome client supports it.
// view.notifySelectDialogDismissed();
}
});
An alternative solution is to subclass WebView and Override performLongClick as bellow:
public class AdvanceWebView extends WebView {
//Add constructors...
#Override
public boolean performLongClick() {
return true;
}
}
It seems that the only option is to set onTouchListener and write your own code to detect long-click. Then return true if it's a long-click and false otherwise.
For kotlin i found the following to work:
webView.isLongClickable = false

Categories

Resources