Progressbar while loading webview in xamarin android - c#

I want to show a progressbar while the webview gets loaded and hide the progessbar when the webview gets loaded completely.
Here is my Activity.cs
progress = new ProgressDialog(this);
progress.Indeterminate = true;
progress.SetProgressStyle(Android.App.ProgressDialogStyle.Spinner);
progress.SetMessage("Loading... Please wait...");
progress.SetCancelable(false);
progress.Show();
_faq = FindViewById<Android.Webkit.WebView>(Resource.Id.wv_FAQ);
_web.AppWebViewClients(progress);
_web.ShouldOverrideUrlLoading(_faq, _url);
_web.OnPageFinished(_faq, _url);
here is my ResourceWebView.cs
public class ResourceWebView: WebViewClient
{
Android.App.ProgressDialog progress;
public void AppWebViewClients(ProgressDialog progressBar)
{
this.progress = progressBar;
progress.Show();
}
public bool ShouldOverrideUrlLoading(WebView view, String url)
{
view.LoadUrl(url);
progress.Show();
return true;
}
public void OnPageFinished(WebView view, String url)
{
OnPageFinished(view, url);
progress.Hide();
}
}
But this code is not work for me..

Try this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
urlEditText = (EditText) findViewById(R.id.urlField);
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new MyWebViewClient());
progress = (ProgressBar) findViewById(R.id.progressBar);
progress.setVisibility(View.GONE);
Button openUrl = (Button) findViewById(R.id.goButton);
openUrl.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
String url = urlEditText.getText().toString();
if (validateUrl(url)) {
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(url);
}
}
private boolean validateUrl(String url) {
return true;
}
});
}
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
progress.setVisibility(View.GONE);
WebViewActivity.this.progress.setProgress(100);
super.onPageFinished(view, url);
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
progress.setVisibility(View.VISIBLE);
WebViewActivity.this.progress.setProgress(0);
super.onPageStarted(view, url, favicon);
}
}
Reference this for more reference : http://stacktips.com/tutorials/android/progressbar-while-loading-webview

Related

OnClickListeners for Recyclerviews -Xamarin.Droid

I have tried to look out for an answer to the behavior of my views but I seem not find any question or solution related to it. My recycler views seemed to be set up well. I just realized that my app is not responding in the right way to the OnClickListeners.
I have set up toasts in my adapter for the recycler view click events. When i have 10 views. When i click on a view, it gives a text of another view. It seems it randomly gives me the text of another view amongst the 9 remaining views. What could be the cause of this?
Activity
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
FrameLayout content = (FrameLayout)FindViewById(Resource.Id.content_frame);
LayoutInflater.Inflate(Resource.Layout.Main, content);
setUpRecyclerView();
}
public void setUpRecyclerView(){
rv = FindViewById<RecyclerView>(Resource.Id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.Orientation = LinearLayoutManager.Vertical;
layoutManager.ReverseLayout = true;
layoutManager.StackFromEnd = true;
rv.HasFixedSize = true;
rv.SetLayoutManager(layoutManager);
}
Adapter
public class FeedViewHolder : RecyclerView.ViewHolder, View.IOnClickListener, View.IOnLongClickListener
{
public FeedViewHolder(View itemView):base(itemView)
{
//binding of variables here
itemView.SetOnClickListener(this);
itemView.SetOnLongClickListener(this);
}
public void OnClick(View v)
{
itemClickListener.OnClick(v, AdapterPosition, false);
}
public bool OnLongClick(View v)
{
itemClickListener.OnClick(v, AdapterPosition, true);
return true;
}
public class FeedAdapter : RecyclerView.Adapter, ItemClickListener
{
public FeedAdapter(RssObject rssObject, Context mContext)
{
this.mContext = mContext;
this.inflater = LayoutInflater.From(mContext);
activity = (MainActivity)mContext;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
hold = holder as FeedViewHolder;
//binding
hold.itemClickListener = this;
}
public void OnClick(View view, int position, bool isLongClick)
{
Toast.MakeText(activity, "Main text : " + hold.txtContent.Text, ToastLength.Long).Show();
}
public override int ItemCount
{
get { return rssObject.items.Count; }
}
}
}
}

Swipe Refresh not working in xamarin.android webview

I am trying to implement SwipeRefreshLayout in a webview in Xamarin.android but the layout keeps loading infinitely only works well as a progress bar but when swiping to refresh it doesn't work. Please help me fix it.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.gameofthrones);
myWebClient = new WebClient();
myWebView = FindViewById<WebView>(Resource.Id.webView);
myProgressBar = FindViewById<ProgressBar>(Resource.Id.progressBar);
myswipeRefreshLayout = FindViewById<SwipeRefreshLayout>(Resource.Id.refresher);
myswipeRefreshLayout.SetColorScheme(Resource.Color.Red, Resource.Color.Orange,
Resource.Color.Yellow, Resource.Color.Green,
Resource.Color.Blue, Resource.Color.Indigo,
Resource.Color.Violet);
var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
myWebView.Settings.JavaScriptEnabled = true;
myWebView.LoadUrl("http://www.google.com");
myWebView.SetWebViewClient(myWebClient);
//Toolbar will now take on default actionbar characteristics
SetSupportActionBar(toolbar);
SupportActionBar.Title = "GAME OF THRONES";
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
SupportActionBar.SetHomeButtonEnabled(true);
myswipeRefreshLayout.Refresh += MyswipeRefreshLayout_Refresh;
}
private void MyswipeRefreshLayout_Refresh(object sender, EventArgs e)
{
myWebClient.myOnProgressChanged += (int state) =>
{
if (state == 0)
{
(sender as SwipeRefreshLayout).Refreshing = false;
myswipeRefreshLayout.Refreshing = false;
//page loaded no progress bar visible
//myProgressBar.Visibility = ViewStates.Invisible;
}
else
{
(sender as SwipeRefreshLayout).Refreshing = true;
myswipeRefreshLayout.Refreshing = true;
//myProgressBar.Visibility = ViewStates.Visible;
}
};
}
public override bool OnKeyDown(Android.Views.Keycode keyCode, Android.Views.KeyEvent e)
{
if (keyCode == Keycode.Back && myWebView.CanGoBack())
{
myWebView.GoBack();
return true;
}
return base.OnKeyDown(keyCode, e);
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
if (item.ItemId == Android.Resource.Id.Home)
Finish();
return base.OnOptionsItemSelected(item);
}
}
public class WebClient : WebViewClient
{
public delegate void ToggleProgreeBar(int state);
public ToggleProgreeBar myOnProgressChanged;
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
view.LoadUrl(url);
return true;
}
public override void OnPageStarted(WebView view, string url, Bitmap favicon)
{
if (myOnProgressChanged != null)
{
myOnProgressChanged.Invoke(1);
}
base.OnPageStarted(view, url, favicon);
}
public override void OnPageFinished(WebView view, string url)
{
if (myOnProgressChanged != null)
{
myOnProgressChanged.Invoke(0);
}
base.OnPageFinished(view, url);
}
SwipeRefreshLayout.Refresh get triggered when user down swipes. According to your requirement, when user swipes, you need to manually refresh the webview:
private void SwipeRefresh_Refresh(object sender, System.EventArgs e)
{
webview.LoadUrl(webview.Url);
}
And register myWebClient.myOnProgressChanged event inside OnCreate. So codes should looks like below:
public class MainActivity : Activity
{
WebView webview;
SwipeRefreshLayout mySwipeRefresh;
WebClient myWebClient;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
webview = FindViewById<WebView>(Resource.Id.webview);
webview.Settings.JavaScriptEnabled = true;
webview.LoadUrl("http://www.google.com");
mySwipeRefresh = FindViewById<SwipeRefreshLayout>(Resource.Id.swiperefresh);
myWebClient = new WebClient();
//register myOnProgressChanged here
myWebClient.myOnProgressChanged += (int state) =>
{
if (state == 0)
{
mySwipeRefresh.Refreshing = false;
}
else
{
mySwipeRefresh.Refreshing = true;
}
};
webview.SetWebViewClient(myWebClient);
mySwipeRefresh.Refresh += SwipeRefresh_Refresh;
}
private void SwipeRefresh_Refresh(object sender, System.EventArgs e)
{
//refresh the webview when user swipes.
webview.LoadUrl(webview.Url);
}
}

Android C# WebView OnPageStart Toast

I am trying to complete an action of some sort while the the WebView is starting, like a loading spinning wheel or a toast message...
What I have done crashes the app. (I'm new to C#, so simple answers are appreciated).
public class MainActivity : Activity
{
private static Context context;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
WebView mWebView = FindViewById<WebView>(Resource.Id.webView);
mWebView.Settings.JavaScriptEnabled = true;
mWebView.SetWebViewClient(new MyWebViewClient());
//Load url to be randered on WebView
mWebView.LoadUrl("https://google.com");
}
public class MyWebViewClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
view.LoadUrl(url);
return true;
}
public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
Toast.MakeText(context, "Loading...", ToastLength.Short).Show();
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
}
public override void OnReceivedError(WebView view, ClientError errorCode, string description, string failingUrl)
{
base.OnReceivedError(view, errorCode, description, failingUrl);
}
}
}
The private static Context context; field in MainActivity never gets assigned; using it in the Toast.MakeText(context ... ) call will result in a null exception. Fix this by using the global context:
Toast.MakeText(Android.App.Application.Context, "Loading...", ToastLength.Short).Show();

How to refresh / reinitialize CefSharp

I'm using CefSharp Offscreen in my wpf application to generate screenshot of website. It works well but I need to check if there is some certificate errors on page and it should be configurable while application is running.
I added checkbox: "Ignore certificate errors" to form. Then I implemented MyRequestHandler for ChrominiumWebBrowser IRequestHandler.
private class MyRequestHandler : IRequestHandler
{
public event EventHandler<LoadErrorEventArgs> CertificateError;
public bool IgnoreCertErrors { get; set; }
public bool OnBeforeBrowse(IWebBrowser browser, IRequest request, bool isRedirect, bool isMainFrame)
{
return false;
}
public bool OnCertificateError(IWebBrowser browser, CefErrorCode errorCode, string requestUrl)
{
if (IgnoreCertErrors)
{
return true;
}
var handler = CertificateError;
if (handler != null)
{
handler(browser, new LoadErrorEventArgs(requestUrl, errorCode, Resources.InvalidCert));
}
return false;
}
public void OnPluginCrashed(IWebBrowser browser, string pluginPath)
{
}
public CefReturnValue OnBeforeResourceLoad(IWebBrowser browser, IRequest request, bool isMainFrame)
{
return CefReturnValue.Continue;
}
public bool GetAuthCredentials(IWebBrowser browser, bool isProxy, string host, int port, string realm, string scheme, ref string username, ref string password)
{
return true;
}
public bool OnBeforePluginLoad(IWebBrowser browser, string url, string policyUrl, WebPluginInfo info)
{
return false;
}
public void OnRenderProcessTerminated(IWebBrowser browser, CefTerminationStatus status)
{
}
}
Browser Initialization:
browser = new ChromiumWebBrowser();
browser.LoadError += BrowserLoadError;
requestHandler = new MyRequestHandler() { IgnoreCertErrors = ignoreCertErrors };
requestHandler.CertificateError += BrowserLoadError;
browser.RequestHandler = requestHandler;
If I start application with IgnoreCertErrors = true it works ok and certificate errors are ignored.
If I start with IgnoreCertErrors = false it also works ok and CertificateError is raised.
Problem is when I try to change IgnoreCertErrors when application is running. When I start app with false and then switch from false --> true it is ok, but when I try change it from true to false the OnCertificateError method is not raised so I have no chance to check my parameter.
Is there caching or something? Maybe whole my approach is wrong?
Is there any possibility to reinitialize CefSharp?
Better example:
Xaml:
<Window x:Class="ceftest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Closed="Window_Closed">
<Grid>
<StackPanel>
<Button Grid.Column="1" Click="Button_Click">Generate Screenshot</Button>
<CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked">Ignore cert errors</CheckBox>
</StackPanel>
</Grid>
</Window>
Code-behind:
public partial class MainWindow : Window
{
ChromiumWebBrowser browser;
bool ignoreCertErrors = false;
string url = ""; // some page with invalid certificate
public MainWindow()
{
Cef.Initialize(new CefSettings());
InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (browser != null && browser.IsBrowserInitialized)
{
browser.Dispose();
}
browser = new ChromiumWebBrowser();
browser.LoadError += BrowserLoadError;
var requestHandler = new RequestHandler() { IgnoreCertErrors = ignoreCertErrors };
requestHandler.CertificateError += BrowserLoadError;
browser.RequestHandler = requestHandler;
System.Threading.Thread.Sleep(100);
browser.Size = new System.Drawing.Size(1000, 700);
browser.NewScreenshot += ScreenshotGenerated;
browser.Load(url);
}
private void ScreenshotGenerated(object sender, System.EventArgs e)
{
// I get here screenshot from browser.ScreenshotAsync and put it into Image control
}
private void BrowserLoadError(object sender, LoadErrorEventArgs e)
{
MessageBox.Show(e.ErrorCode + " " + e.ErrorText);
}
private void CheckBox_Checked(object sender, System.Windows.RoutedEventArgs e)
{
ignoreCertErrors = true;
}
private void CheckBox_Unchecked(object sender, System.Windows.RoutedEventArgs e)
{
ignoreCertErrors = false;
}
private void Window_Closed(object sender, EventArgs e)
{
Cef.Shutdown();
}
}
class RequestHandler : IRequestHandler
{
public event EventHandler<LoadErrorEventArgs> CertificateError;
public bool IgnoreCertErrors { get; set; }
public bool GetAuthCredentials(IWebBrowser browser, bool isProxy, string host, int port, string realm, string scheme, ref string username, ref string password)
{
return true;
}
public bool OnBeforeBrowse(IWebBrowser browser, IRequest request, bool isRedirect, bool isMainFrame)
{
return false;
}
public bool OnBeforePluginLoad(IWebBrowser browser, string url, string policyUrl, WebPluginInfo info)
{
return false;
}
public CefReturnValue OnBeforeResourceLoad(IWebBrowser browser, IRequest request, bool isMainFrame)
{
return CefReturnValue.Continue;
}
public bool OnCertificateError(IWebBrowser browser, CefErrorCode errorCode, string requestUrl)
{
if (IgnoreCertErrors)
{
return true;
}
var handler = CertificateError;
if (handler != null)
{
handler(browser, new LoadErrorEventArgs(requestUrl, errorCode, "certificate error"));
}
return false;
}
public void OnPluginCrashed(IWebBrowser browser, string pluginPath)
{
}
public void OnRenderProcessTerminated(IWebBrowser browser, CefTerminationStatus status)
{
}
}
CefSharp Offscreen version 41.0.1.0

Passing strings from an Activity to a DialogFragment

in my activity I have this:
public class MainActivity : Activity
{
RelativeLayout mRelativeLayout;
Button mButton;
private Button mBtnSignUp;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
mRelativeLayout = FindViewById<RelativeLayout>(Resource.Id.mainView);
mButton = FindViewById<Button>(Resource.Id.btnLogin);
mButton.Click += mButton_Click;
mRelativeLayout.Click += mRelativeLayout_Click;
mBtnSignUp = FindViewById<Button> (Resource.Id.button1);
mBtnSignUp.Click += (object sender, EventArgs e) =>
{
//Pull up dialog
FragmentTransaction transaction = FragmentManager.BeginTransaction();
dialog_SignUp signUpDialog = new dialog_SignUp();
signUpDialog.Show(transaction, "dialog fragment");
signUpDialog.mOnSignUpComplete += signUpDialog_mOnSignUpComplete;
};
void signUpDialog_mOnSignUpComplete (object sender, OnSignUpEventArgs e)
{
Thread thread = new Thread (ActLikeARequest);
thread.Start ();
}
private void ActLikeARequest()
{
Thread.Sleep (3000);
}
And in the dialog I have:
public class OnSignUpEventArgs : EventArgs
{
private string mFirstName;
private string mEmail;
private string mPassword;
public string FirstName
{
get{ return mFirstName; }
set{ mFirstName=value;}
}
public string Email
{
get{ return mEmail; }
set{ mEmail=value;}
}
public string Password
{
get{ return mPassword; }
set{ mPassword=value;}
}
public OnSignUpEventArgs (string firstName, string email, string password) : base()
{
FirstName = firstName;
Email = email;
Password = password;
}
}
class dialog_SignUp:DialogFragment
{
private Button mBtnSignUp;
private EditText mFirstName;
private EditText mEmail;
private EditText mPassword;
public event EventHandler<OnSignUpEventArgs> mOnSignUpComplete;
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView (inflater, container, savedInstanceState);
var view = inflater.Inflate (Resource.Layout.dialog_sign_up, container, false);
mBtnSignUp = view.FindViewById<Button> (Resource.Id.btnDialogEmail);
mFirstName = view.FindViewById<EditText> (Resource.Id.txtFirstName);
mEmail = view.FindViewById<EditText> (Resource.Id.txtEmail);
mPassword = view.FindViewById<EditText> (Resource.Id.txtPassword);
mBtnSignUp.Click += mBtnSignUp_Click;
return view;
}
void mBtnSignUp_Click (object sender, EventArgs e)
{
//User has clicked the sign up button
mOnSignUpComplete.Invoke (this, new OnSignUpEventArgs(mFirstName.Text, mEmail.Text, mPassword.Text));
this.Dismiss ();
}
public override void OnActivityCreated (Bundle savedInstanceState)
{
Dialog.Window.RequestFeature (WindowFeatures.NoTitle); //Sets the title bar to invisible
base.OnActivityCreated (savedInstanceState);
Dialog.Window.Attributes.WindowAnimations = Resource.Style.dialog_animation; //Set the animation
}
}
The question is, how can I pass data(strings) from the activity into the dialog, so that when it is called, the TextViews get the data I'm passing?
Is it something to add in the actitity, but what?
i think you need to be able to accept a parameter in your dialog_signup.
class dialog_SignUp:DialogFragment
{
private Button mBtnSignUp;
private EditText mFirstName;
private EditText mEmail;
private EditText mPassword;
String parameter="";
public event EventHandler<OnSignUpEventArgs> mOnSignUpComplete;
public dialog_SignUp(String parameterIn){
parameter=parameterIn;
}
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView (inflater, container, savedInstanceState);
var view = inflater.Inflate (Resource.Layout.dialog_sign_up, container, false);
mBtnSignUp = view.FindViewById<Button> (Resource.Id.btnDialogEmail);
mFirstName = view.FindViewById<EditText> (Resource.Id.txtFirstName);
mFirstName.setText(parameter);
mEmail = view.FindViewById<EditText> (Resource.Id.txtEmail);
mPassword = view.FindViewById<EditText> (Resource.Id.txtPassword);
mBtnSignUp.Click += mBtnSignUp_Click;
return view;
}
then replace dialog_SignUp signUpDialog = new dialog_SignUp(); with dialog_SignUp signUpDialog = new dialog_SignUp(stringToSend);
Keep in mind that you can always use The Application class to define a variable there.
namespace YourNamespace
{
[Application]
public class App : Application
{
public ParseObject currentBusiness { get; set;}
public App (IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void OnCreate ()
{
base.OnCreate ();
currentBusiness = new ParseObject ("Business");
}
}
}
Then you can access it from evewhere in that way:
App _app = (App)Application.Context;
var curentBusiness = _app.currentBusiness;
You can use Property feature of Class.
Dialog Fragment Code
class Error : DialogFragment
{
public string getErrorMsg { get; set; } // this gets the message
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.Error, container, false);
TextView text = view.FindViewById<TextView>(Resource.Id.txtError);
text.Text = getErrorMsg; //here the message is set to the TextView
return view;
}
}
Calling Method
FragmentTransaction transaction = FragmentManager.BeginTransaction();
Error obj = new Error();
obj.Cancelable = false;
obj.getErrorMsg = passMyString; // in this line you send message to The Class
obj.Show(transaction, "error");

Categories