There is a rather specific webpage loaded into WebView which URL is like http://www.site.com/mob/ (basically a mobile-optimized web page). This webpage display 25 articles only and on the bottom is a button "More articles".
When a user presses it, I catch URL http://www.site.com/Web/MobHomeItems.aspx?page=N (where N is 2, 3, 4...) and after that another 25 items have been loaded on the same screen.
Now, when I click on some article and go to article details, and later return to the page via the Back key, the WebView forgets how many articles have been loaded and simply loads the default page with 25 displayed articles. Imagine how frustrating this would be to a user if he came to 100th article.
I tried overriding many methods in WebClient and in WebChromeClient, but so far I have been unable to load N number of pages loaded via "More Articles" button. For example, I first thought this would help, but it did not.
#Override
public void onLoadResource(WebView view, String url) {
//http://www.site.com/Web/MobHomeItems.aspx?page=2
if (url.contains("?page=")) {
//save this URL for later and on return from
// article details, pass it to LoadResource()
super.onLoadResource(view, url);
}
Then I tried similar approach with other method - basically remembering how many pages have been loaded on the main page, and then on return from article details, simply tell webview to load this URL.
Can anyone help me? How to append loaded pages to the main page? Should I use JavaScript here maybe?
PS. Loading mentioned URL http://www.site.com/Web/MobHomeItems.aspx?page=N does not help as it loads this concrete page into the WebView only, and it does not append this Nth page to the main page.
EDIT
As #Raghunandan asked, I do not have problems loading back to 1st page (?page=1). This is default when user presses Back button on article details. I want to load to the page where a user was before pressing article details. If he was on ?page=100, I want to load back to that page e.g. I want to have 25x100 articles open. Again, default is always "open 25 articles or ?page=1 or http://www.site.com".
Override the method shouldOverrideUrlLoading of WebViewClient.
like this:
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if (url is kind of article detail) {
WebView newOne = new WebView(); // create a new Webview for displaying the details.
view.setVisibility(View.INVISIBLE); // hiding current page (article list)
return true; // To tell the WebView we have process this url.
}
return false;
}
The user click one link of article's detail.
shouldOverriderUrlLoading would be triggered.
We created one new WebView to open the url.
Hiding current page
The user reading artical
The user click back key, close the newOne WebView then make the
previous WebView visible.The article list will show up immediately and remained the old statement
.
There is a another way to do this.
The WebSettings has a private method "setPageCacheCapacity" , the default value is 0 , you could enlarge it (may be 5).
You can access this method by using reflection of java.
The method can enable WebView to cache more than one document. In the other word. when user press the back key, the WebView will go back to the older document.
Related
I have a list of web urls. I need to open them all at once in an external browser where each link's page results in a new tab. So for example, if the list has a link to google.com and yahoo.com they should both be opened in the browser in their own separate tabs.
To open a single link within an external browser is pretty straight forward - create an ACTION_VIEW intent, set the url and call startActivity. But how can I do this with multiple urls? Doing multiple startActivity calls won't work. Any ideas?
Thank you for your time!
My answer is based on a little research so I am not sure about the exact code but I will suggest an approach here
First you can have a Fragment or Activity with the WebView view type in the layout file respectively and depending on your use case, get the reference for the WebView. We will pass your list of urls to the activity containing the Webview
Say, we do it like so
val arrayList = getIntent().getArrayListExtra("urls")
val webView = findViewById<WebView>(R.id.myWebview)
Now we can listen to scroll changes of the WebView and wait for the user to reach the end of the WebView page as given in the following link
How to check the scrollend of WebView
And then when the scroll end is reached, we can load the next url from the array
webView.setOnScrollChangeListener((view, i, i1, i2, i3) -> {
int r1 = webView.computeVerticalScrollRange();
int r2 = webView.computeVerticalScrollExtent();
if (i1 == (r1 - r2)) {
webView.loadUrl(arrayList.get(1) // Or Whatever your next
index is
// Maybe maintain a global variable for which url is currently
loaded
}
});
To make the experience nice for the user you can consider setting a WebViewClient for your WebView and override onProgressChanged to show the progress to the user, just in case he doesn't feel lost
I have a problem with WebView. My app has build in help files made with html in local assets. And I show html file with WebView.
My problem is, WebView's goBack() function can't go back to previous page when it tries to return to bookmarked position.
For example:
Page1 has link to bookmark1 in Page1.
And Page1 has link to Page2.
Showing Page1 and hit link to Page2, then goBack() can go back to Page1. Fine.
Showing Page1 and hit link to bookmark1, and then hit link to Page2, then goBack() can't go back to page1. WebView shows error like it can't find url with #bookmark1.
I suspect WebView is not handing viewing history for local files. I'm using OS 4.0.3.
Any solutions?
I have found a (compromising) solution for this issue. This issue was discussed here and one solution can be found here (Japanese page, sorry). In my case, after knowing it's a bug in some range of Android OS, going back to previous page (not to exact anchor position) is fine. So I ended up with next code.
webView = (WebView)findViewById(R.id.webview);
webView.setWebViewClient(new WebViewClient()
{
// https://stackoverflow.com/questions/6542702/basic-internal-links-dont-work-in-honeycomb-app
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
super.onReceivedError(view, errorCode, description, failingUrl);
String url = failingUrl;
int index = url.indexOf("#");
if (index != -1)
{
url = url.substring(0, index);
}
webView.loadUrl(url);
}
});
With this code when it can't go back to previous page with anchor, it goes back to previous page without anchor. I compromised with it. I tried to make it better with other solutions using Java Script but did not work.
I have an app with a previously-existing, web-based registration process that I am trying to use inside a WebView. I need to add some style tags to the html in order to hide some elements for better displaying the content inside my app. I can get it to work on initial load, but I cannot figure out how to do it from one page to the next inside the WebView. Here is what I have working:
On initial load of the site, I am getting the raw html and appending "<style>MY STYLES HERE</style>" to the string before calling
wv.loadDataWithBaseURL(url, rawHtml, null, "UTF-8", url);
This works perfectly, but if a user clicks a link on the page and it loads another page into the WebView, then this code does not get called and the style tag is lost.
I assume I need to override "shouldOverrideUrlLoading" in the WebViewClient, but I don't know how to intercept the html from here. I thought I would try something like:
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String rawHtml = getRawHtml(url) + "<style>...</style>";
wv.loadDataWithBaseURL(url, rawHtml, null, "UTF-8", url);
}
But this obviously sends it into an endless loop of intercepting the load to start a new load.
I have also tried overriding onPageFinished and doing:
wv.loadUrl("javascript:(function() { ... })()");
which works, except that it waits until the entire page is loaded before executing. This causes the page to appear loaded with all of the UI elements in tact, and then all of the ones I am trying to hide suddenly disappear. My ultimate goal is to enhance the look and feel of the site on a mobile device, so this is not an option.
Is there something else I can do in "shouldOverrideUrlLoading" to inject style tags? Or if not, what else can I try?
I've run into this problem, and depending on the number of redirects, etc, we have not been able to make the injected JavaScript available all the time.
At minimum, you should use the wv.loadUrl("javascript:(function() { ... })()"); approach, but call it in both onPageStarted() and onPageFinished().
Depending on the complexity of your pages, you might need to inject the JavaScript in onLoadResource() as well.
I am working on an android project right now and have a question about how to do callbacks in different webviews. I used JSInterface for my project too. Here I have 2 webviews. One has an index page, anther is a overlay(still a html page though.) What I want to do is if any user clicks on some links on the overlay, it should fire a callback function which is written in the java file where the index page was connected to through JSInterface. It might sound confusing, but I have draw something to help make it clear!
Thanks!
You can use a custom URL scheme like myurl://function for your functionality links. Then write an event handler for the WebView's shouldOverrideUrlLoading event in which you decide how to process the URL: either instruct the webview to load it, or do some custom action.
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if (url.startsWith("myurl://"))
{
// Parse further to extract function and do custom action
}
else
{
// Load the page via the webview
view.loadUrl(url);
}
return true;
}
I used startsWith to check the URL for this quick and dirty example, but you should consider using android.net.Uri.parse for parsing URLs.
This should allow you to call the Java function foo() without having to go through the first WebView.
If you want to go through the first webview, then you can call a function on the JSInterface like this (where webView1 is the first WebView retrieved through findViewById):
webView1.loadUrl("javascript:myjsinterface.myjsfunc();")
I am trying to launch a websearch using data input from a user. The data is input through TextEdit boxes. Upon submission of the data, i would like my program to: 1) search for a specific webpage based on the user input 2)Find specific elements at the webpage 3) Display the webpage.
Here is an example:
User Input (in a non browser/webview page)
1) Store Name: Macey's 2)Zip Code: 77471
In the background my program will:
1) Find the Macey's website
2) Find the store nearest zip code 77471
3) Load the Web page for the store nearest zip code 77471
Obviously there is a lot of error handeling, exceptions, ect that would go along with this. For the sake of making this example "easy" lets pretend that 1) A the Macey's main page exists 2)A sperate page for the 77471 store exists. 3)There is a link to the 77471 store on the Macey's main page.
I have the code for getting the user input variables and i know how to launch the webview. What i dont know how to do is to search for the Macy's home page, then find the link i am looking for on the homepage and navigate to it. Loading the webview is not the problem. Find the data is.
Below is my current code. Right now i am setup so that the user will navigate to the webpage they are looking for but i would rather handle the searching for them, if it is possible.
public void InitializeWebView(){
portal = (WebView)findViewById(R.id.web_Portal);
WebSettings Settings = portal.getSettings();
Settings.setSavePassword(false);
Settings.setSaveFormData(false);
Settings.setJavaScriptEnabled(true);
Settings.setSupportZoom(true);
Settings.supportZoom();
portal.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
}
public void searchAndShow(String Store, String zip){
portal.loadUrl("http://www.google.com");
}
You can get search result in JSON format from google using their API. Here is a nice example in JAVA. Just don't use key parameter until you do not have a vlid key.