如您所知,选择文本时,它会出现一个弹出菜单。
当我单击菜单上的“复制”时,无法选择/复制文本,但事件被触发。 (在MyMenuItemOnMenuItemClickListener类中> OnMenuItemClick方法中)
-
如果使用“共享>复制到剪贴板”菜单将其复制,则可以获取它。该事件未触发。 (这不是我们的目标。只是为了比较。)
如果我复制WebView以外的任何文本,然后单击“复制”按钮(而不是“复制到剪贴板”),则可以获得上次复制的文本。 Webview的复制按钮有什么问题?为什么我无法选择文本?
iOS没问题。
-
Xaml;
CustomWebView类;
public class CustomWebView : WebView
{
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(CustomWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
}
自定义渲染器;
[assembly: ExportRenderer(typeof(CustomWebView), typeof(WebViewRendererDroid))]
namespace TApp.Droid
{
public class WebViewRendererDroid : ViewRenderer<CustomWebView, Android.Webkit.WebView>, IOnPrimaryClipChangedListener /* ViewRenderer<CustomWebView, Android.Webkit.WebView>*/
{
Context _context;
public WebViewRendererDroid(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<CustomWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.AllowContentAccess = true;
webView.LoadUrl("https://docs.microsoft.com/en-us/xamarin/ios/");
SetNativeControl(webView);
}
if (e.NewElement != null)
{
Control.LoadUrl("https://docs.microsoft.com/en-us/xamarin/ios/");
}
}
ClipboardManager myClipBoard;
public void OnPrimaryClipChanged()
{
ClipData clipData = myClipBoard.PrimaryClip;
ClipData.Item item = clipData.GetItemAt(0);
MessagingCenter.Send<object, string>(this, "Hi", item.Text);
}
}
}
MainActivity.cs;
namespace TApp.Droid
{
[Activity(Label = "TApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnActionModeStarted(ActionMode mode)
{
IMenu menu = mode.Menu;
menu.GetItem(0).SetOnMenuItemClickListener(new MyMenuItemOnMenuItemClickListener(this));
base.OnActionModeStarted(mode);
}
}
public class MyMenuItemOnMenuItemClickListener : Java.Lang.Object, IMenuItemOnMenuItemClickListener
{
private MainActivity mContext;
public MyMenuItemOnMenuItemClickListener(MainActivity activity)
{
this.mContext = activity;
}
public bool OnMenuItemClick(IMenuItem item)
{
var clipboard = (ClipboardManager)mContext.GetSystemService(Context.ClipboardService);
var clipboard2 = (Android.Text.ClipboardManager)Android.App.Application.Context.GetSystemService(Context.ClipboardService);
var pasteData = "";
string aaa = clipboard.Text;
if (!(clipboard.HasPrimaryClip))
{
// If it does contain data, decide if you can handle the data.
}
else if (!(clipboard.PrimaryClipDescription.HasMimeType(ClipDescription.MimetypeTextPlain)))
{
// since the clipboard has data but it is not plain text
}
else
{
//since the clipboard contains plain text
var copiedText = clipboard.PrimaryClip.GetItemAt(0);
// Gets the clipboard as text
pasteData = copiedText.Text;
}
Toast.MakeText(mContext, pasteData, ToastLength.Short).Show();
return true;
}
}
}
答案 0 :(得分:0)
我写了一个简单的示例,您可以检查一下:
1。在Android.Project中定义接口 ActionSelectListener
:
public interface ActionSelectListener
{
void onClick(string selectText);
}
2。在Android.Project中自定义 WebView CustomActionWebView
:
class CustomActionWebView:WebView,IMenuItemOnMenuItemClickListener
{
public CustomActionWebView(Context context):base(context)
{
_context = context;
}
public CustomActionWebView(Context context, IAttributeSet attrs):base(context,attrs)
{
_context = context;
}
public CustomActionWebView(Context context, IAttributeSet attrs, int defStyleAttr):base(context,attrs,defStyleAttr)
{
_context = context;
}
private Context _context;
ActionMode mActionMode;
static ActionSelectListener mActionSelectListener;
private ActionMode resolveActionMode(ActionMode actionMode)
{
if (actionMode != null)
{
IMenu menu = actionMode.Menu;
mActionMode = actionMode;
IMenuItem menuItem = menu.GetItem(0);//here only handle the copy button
menuItem.SetOnMenuItemClickListener(this);
}
mActionMode = actionMode;
return actionMode;
}
public override ActionMode StartActionMode(ActionMode.ICallback callback)
{
ActionMode actionMode = base.StartActionMode(callback);
return resolveActionMode(actionMode);
}
public override ActionMode StartActionMode(ActionMode.ICallback callback, [GeneratedEnum] ActionModeType type)
{
ActionMode actionMode = base.StartActionMode(callback, type);
return resolveActionMode(actionMode);
}
private void releaseAction()
{
if (mActionMode != null)
{
mActionMode.Finish();
mActionMode = null;
}
}
/**
* When you click, get the selected text from the page and drop it back to the native js interface
* @param passes in the text of the clicked item, which is returned to the native interface via js
*/
private void getSelectedData()
{
String js = "(function getSelectedText() {" +
"var txt;" +
"if (window.getSelection) {" +
"txt = window.getSelection().toString();" +
"} else if (window.document.getSelection) {" +
"txt = window.document.getSelection().toString();" +
"} else if (window.document.selection) {" +
"txt = window.document.selection.createRange().text;" +
"}" +
"JSInterface.callback(txt);" +
"})()";
if (Build.VERSION.SdkInt >= Build.VERSION_CODES.Kitkat)
{
EvaluateJavascript( js, null);
}
else
{
LoadUrl("javascript:" + js);
}
}
public void linkJSInterface()
{
AddJavascriptInterface(new ActionSelectInterface(_context), "JSInterface");
}
/**
* click call back
* @param actionSelectListener
*/
public void setActionSelectListener(ActionSelectListener actionSelectListener)
{
mActionSelectListener = actionSelectListener;
}
public bool OnMenuItemClick(IMenuItem item)
{
getSelectedData();
releaseAction();
return true;
}
/**
* js call back interface
*/
class ActionSelectInterface : Java.Lang.Object
{
Context mContext;
public ActionSelectInterface(Context c)
{
mContext = c;
}
[JavascriptInterface]
[Export]
public void callback(string value)
{
if (mActionSelectListener != null)
{
mActionSelectListener.onClick(value);
}
}
}
}
3。在您的 CustomRenderer 中使用:
[assembly: ExportRenderer(typeof(CustomWebView), typeof(WebViewRendererDroid))]
namespace TApp.Droid
{
public class WebViewRendererDroid : ViewRenderer<CustomWebView, Android.Webkit.WebView>, ActionSelectListenerr /* ViewRenderer<CustomWebView, Android.Webkit.WebView>*/
{
Context _context;
public WebViewRendererDroid(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<CustomWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new CustomActionWebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.AllowContentAccess = true;
webView.linkJSInterface();
webView.LoadUrl("https://docs.microsoft.com/en-us/xamarin/ios/");
SetNativeControl(webView);
}
}
public void onClick(string selectText)
{
ClipboardManager cm = (ClipboardManager)_context.GetSystemService(Context.ClipboardService);
// Place the text in the system clipboard.
ClipData clipData = ClipData.NewPlainText(null, selectText);
// Set (copy) the dataset to the clipboard
cm.PrimaryClip = clipData;
}
}