i am making an android that runs a fullscreen webview but the problem is the index page appears after a 2 sec delay so i want to implement a splash screen to be displayed until the webview loads the website in the background .please if you could he me with complete code of this splash screen because i am completely new to it .
main activity is :
public class MainActivity extends Activity {
WebView website;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
website = (WebView) findViewById(R.id.website);
website.setWebViewClient(new WebViewClient());
WebSettings webSettings = website.getSettings();
webSettings.setJavaScriptEnabled(true);
website.loadUrl("http://www.fitanity.com/index2.jsp");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && website.canGoBack()) {
website.goBack();
return true;
}
else
{
finish();
}
return super.onKeyDown(keyCode, event);
}
}
you can initially show ImageView, once webview get loaded in public void onPageFinished() change their visibility.
public class MainActivity1 extends Activity {
WebView website;
ImageView imgLoading;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setContentView(R.layout.activity_main);
website = (WebView) findViewById(R.id.website);
imgLoading = (ImageView)findViewById(R.id.imgloader);
WebSettings webSettings = website.getSettings();
webSettings.setJavaScriptEnabled(true);
website.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
//hide loading image
imgLoading.setVisibility(View.GONE);
//show webview
website.setVisibility(View.VISIBLE);
}
});
website.loadUrl("http://www.fitanity.com/index2.jsp");
}
your xml will looks like :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imgloader"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/loader"
android:visibility="visible" />
<WebView
android:id="#+id/website"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone" />
</LinearLayout>
To do this, You have to make a class which extends WebViewClient class.
in this class, There are some method you can or you have to override,
1.onPageStarted -- This will call when webview will start loading Page. (SHOW YOU SPALSH)
2.shouldOverrideUrlLoading -- This method you have to override
3.onPageFinished -- This will call when webview will stop loading Page. (HIDE YOUR SPLASH)
Now into you webview, use you own class of Webview like this,
web.setWebViewClient(new mywebclient());
Hope It Helps you,
Cheers
-Aman
Dhwanik's solution worked for me too but I wanted to show come text with backgrount and loading gif as a splash screen so I replaced image with a new layout and placed all my contents in it.
Here is the link which which could be useful for everyone who need the same like me
http://www.codewithasp.net/2016/01/show-splash-screen-while-android.html
Related
I am trying to display an external website in a fragment on a webview. Although when i open the fragment, i get a blank screen. Kindly help me with the same.
public class one extends android.support.v4.app.Fragment {
public one() {
// Required empty public constructor
}
private WebView mWebview ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
FrameLayout framelayout = (FrameLayout) inflater.inflate(R.layout.fragment_one, container, false);
mWebview = (WebView) framelayout.findViewById(R.id.web);
WebSettings setting =mWebview.getSettings();
mWebview.getSettings().setJavaScriptEnabled(true);
mWebview.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
});
//webView.loadUrl("http://www.cleankutz.appointy.com");
mWebview.loadUrl("https://www.cleankutz.appointy.com");
return framelayout;
}
}
You need the following in the manifest:
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
Here are some things you can try:
Make sure that internet is enabled in your device when testing
Enable java script:
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
Also, I find this code quite useless:
mWebview.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
});
That just overrides any link clicks. And if you want to do that, you should just not set the web view client. Also, just a bonus, if you want your webview to go back on back press, do this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
Please accept my answer by pressing the checkmark if this helped. If you have more questions, feel free to ask me.
I have the HTML file in the assets folder and trying to load that in android webview. The css style is not getting applied also javascript isnt getting applied and images are not getting loaded.
Here is the activity code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView ctWebView = (WebView) findViewById(R.id.ctWebview);
ctWebView.getSettings().setDomStorageEnabled(true);
ctWebView.getSettings().setJavaScriptEnabled(true);
ctWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
ctWebView.setWebChromeClient(new WebChromeClient());
ctWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
Log.e("resource",url);
}
});
ctWebView.loadUrl("file:///android_asset/creditrackerhtml.html");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
Here is the layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="#+id/ctWebview"></WebView>
</RelativeLayout>
The HTML file is too big to paste here, but I have put the logs in public void onLoadResource(WebView view, String url) and have seen that proper resource urls are being hit at.
Is it that webview is being loaded before the resources are downloaded? Not sure how to fix this problem
Have you tried loadDataWithBaseURL()?
webView.loadDataWithBaseURL(url,
data,
"text/html",
"utf-8",
null);
Because according to official documentation,
loadDataWithBaseURL()
loads the given data into this WebView, using baseUrl as the base URL
for the content. The base URL is used both to resolve relative URLs
and when applying JavaScript's same origin policy. The historyUrl is
used for the history entry.
Put your files in assets folder.
Go to Project > app > src > main > right click > New > Folder > Assets Folder. Name it assets.
To access file use getAssets().open(filename.txt)
To make file to URL use file.toURI() or file.toURI().toURL().
Also, you do not need much to load url. Just use webView.loadUrl(url);
If you have links use :
//So links stay inside webview
webview.setWebViewClient(new WebViewClient());
webview.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
WebView webView = (WebView) v;
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (webView.canGoBack()) {
webView.goBack();
return true;
}
break;
}
}
return false;
}
});
The CSS and images in the HTML should use URLs relative to the assets directory or use absolute paths on the web.
I have used this guide from Google and this tutorial to produce my own contextual action bar.
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.annotation_menu, menu);
return true;
}
// Called each time the action mode is shown.
// Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.custom_button:
// do some stuff
break;
case R.id.custom_button2:
// do some other stuff
break;
default:
// This essentially acts as a catch statement
// If none of the other cases are true, return false
// because the action was not handled
return false;
}
finish(); // An action was handled, so close the CAB
return true;
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
This menu is designed to appear when the user selects text, so it overrides the native copy/paste menu. Now I get to my issue.
Because I am overriding functions for text selection, I also added a LongClickListener to a WebView and implemented the onLongClick(View v) method so I can detect when users make the selection.
myWebView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mActionMode != null) {
return false;
}
mActionMode = startActionMode(mActionModeCallback);
v.setSelected(true);
return true;
}
});
When I long click, I see my custom menu appear, but no text is highlighted.I need to have the text selection functionality; without it, my menu is pointless.
How do I override onLongClick(View v), but maintain the text selection provided by Android?If that is not possible, can I make the call to startActionMode(mActionModeCallback) somewhere else so that text will be selected as normal, but my custom menu will also appear?If neither of those are possible... help.
THERE IS AN EASIER WAY! See update below :D
For the sake of completeness, here is how I fixed the problem:
I followed the suggestion according to this answer, with a little more tweaking to more closely match the overridden code:
public class MyWebView extends WebView {
private ActionMode mActionMode;
private mActionMode.Callback mActionModeCallback;
#Override
public ActionMode startActionMode(Callback callback) {
ViewParent parent = getParent();
if (parent == null) {
return null;
}
mActionModeCallback = new CustomActionModeCallback();
return parent.startActionModeForChild(this, mActionModeCallback);
}
}
Essentially, this forces your customized CAB to appear instead of the Android CAB. Now you have to modify your callback so that the text highlight will go away along with the CAB:
public class MyWebView extends WebView {
...
private class CustomActionModeCallback implements ActionMode.Callback {
...
// Everything up to this point is the same as in the question
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
clearFocus(); // This is the new code to remove the text highlight
mActionMode = null;
}
}
}
That's all there is to it. Be aware that as long as you are using MyWebView with the overridden startActionMode there is NO WAY to get the native CAB (the copy/paste menu, in the case of a WebView). It may be possible to implement that sort of behavior, but that is not the way this code works.
UPDATE: There is a much easier way to do this! The above solution works well, but here is an alternative, easier way.
This solution provides less control over the ActionMode, but it requires far less code than the above solution.
public class MyActivity extends Activity {
private ActionMode mActionMode = null;
#Override
public void onActionModeStarted(ActionMode mode) {
if (mActionMode == null) {
mActionMode = mode;
Menu menu = mode.getMenu();
// Remove the default menu items (select all, copy, paste, search)
menu.clear();
// If you want to keep any of the defaults,
// remove the items you don't want individually:
// menu.removeItem(android.R.id.[id_of_item_to_remove])
// Inflate your own menu items
mode.getMenuInflater().inflate(R.menu.my_custom_menu, menu);
}
super.onActionModeStarted(mode);
}
// This method is what you should set as your item's onClick
// <item android:onClick="onContextualMenuItemClicked" />
public void onContextualMenuItemClicked(MenuItem item) {
switch (item.getItemId()) {
case R.id.example_item_1:
// do some stuff
break;
case R.id.example_item_2:
// do some different stuff
break;
default:
// ...
break;
}
// This will likely always be true, but check it anyway, just in case
if (mActionMode != null) {
mActionMode.finish();
}
}
#Override
public void onActionModeFinished(ActionMode mode) {
mActionMode = null;
super.onActionModeFinished(mode);
}
}
Here is an example Menu to get you started:
<!-- my_custom_menu.xml -->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/example_item_1"
android:icon="#drawable/ic_menu_example_1"
android:showAsAction="always"
android:onClick="onContextualMenuItemClicked"
android:title="#string/example_1">
</item>
<item
android:id="#+id/example_item_2"
android:icon="#drawable/ic_menu_example_2"
android:showAsAction="ifRoom"
android:onClick="onContextualMenuItemClicked"
android:title="#string/example_2">
</item>
</menu>
That's it! You're done! Now your custom menu will show up, you don't have to worry about the selection, and you barely have to concern yourself with the ActionMode lifecycle.
This works nearly flawlessly with a WebView that occupies its entire parent Activity. I am not sure how well it will work if there are multiple Views within your Activity at one time. It will likely require some tweaking in that case.
The way I did something similar was to only override the onTouchListener and to invoke a GestureDetector to detect when the WebView was long-pressed and do what I wanted from there. Here's some sample code that allows you to catch long-press events without sacrificing text-selection in the WebView. Hopefully this helps.
#Override
protected void onCreate(Bundle savedInstanceState) {
WebView mWebView = (WebView) findViewById(R.id.myWebView);
GestureDetector mGestureDetector = new GestureDetector(this, new CustomGestureListener());
mWebView.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View view, MotionEvent arg1) {
//Suggestion #1 - this just lets the touch to be handled by the system but allows you to detect long presses
mGestureDetector.onTouchEvent(arg1);
return false;
//Suggestion #2 - this code will only let the touch be handled by the system if you don't detect a long press
return mGestureDetector.onTouchEvent(arg1);
}
});
}
private class CustomGestureListener extends SimpleOnGestureListener {
#Override
public void onLongPress(MotionEvent e) {
//do stuff
}
}
I have an item in my actionbar that shows a progressbar when clicked. However, when the user clicks the progressbar, I want the progress bar to stop, and show the normal "refresh" button again. Currently the progressbar become unclickable. Here's my code:
case R.id.id_Refresh:;
menuItem = item;
if(btnRefreshPressed == true){
menuItem.setActionView(R.layout.progressbar);
menuItem.expandActionView();
btnRefreshPressed = false;
mUpdateMap.run();
return true;
}else if(btnRefreshPressed == false){
menuItem.collapseActionView();
menuItem.setActionView(null);
mHandler.removeCallbacks(mUpdateMap);
btnRefreshPressed = true;
return true;
}
progressbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/progressbar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true" >
</ProgressBar>
when you use your own actionView, you need to handle the clicking on the view itself:
menuItem.getActionView().setOnClickListener(...);
also, instead of having 2 modes , one with actionView and another without, you can use viewSwitcher as the actionView , and just toggle it when you want , by using showNext().
EDIT: for easiest way to support clicking on action bar items, no matter if they contain an actionView or not, you can use this code:
public static void setOnMenuItemSelected(final MenuItem menuItem, final Runnable runnable) {
final View view = menuItem.getActionView();
if (view != null)
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
runnable.run();
}
});
else
menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(final MenuItem item) {
runnable.run();
return true;
}
});
}
You are not passing in the ID:
findViewById(com.example.androidbasic12.R.layout.progressbar);
it should be R.id.YourID not R.layout.progressbar
That's why you get a NullPointerException
I have a MenuItem in my ActionBar that is a "reload" icon. My Activity has a WebView and I'd like the icon to start animating when the WebView starts loading a webpage and stop when it's finished. This includes when clicking on links in the site that is loaded. What I have so far, works the first time I bring up a webpage, but if I leave the Activity and load another webpage, the "reload" icon seems to double up, or I will get NullReference exception thrown on refreshItem.setActionView(ivRefresh);
Here is my code:
public class Browser extends SherlockFragmentActivity {
private MenuItem refreshItem;
private WebView mWebView;
#Override
public void onCreate(final Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.browser);
mWebView = (WebView)findViewById(R.id.webview);
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.loadUrl("http://www.google.com");
mWebView.setWebViewClient(new WebBrowserClient());
mWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
//if (!isFinishing() && progress == 100 && refreshItem != null && refreshItem.getActionView() != null)
//{
//refreshItem.getActionView().clearAnimation();
//refreshItem.setActionView(null);
//}
}
});
}
private class WebBrowserClient extends WebViewClient {
#Override
public void onLoadResource(WebView view, String url) {
//StartAnimation();
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
StartAnimation();
}
#Override
public void onPageFinished(WebView view, String url) {
if (refreshItem != null && refreshItem.getActionView() != null)
{
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
private void StartAnimation() {
final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null);
final Animation rotation = AnimationUtils.loadAnimation(this, R.anim.refresh);
ivRefresh.startAnimation(rotation);
refreshItem.setActionView(ivRefresh);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.menu, menu);
refreshItem = menu.findItem(R.id.refresh);
return super.onCreateOptionsMenu(menu);
}
}
The commented out code is different ways I tried to get it to work.
UPDATE:
After debugging this more, I put a breakpoint in the StartAnimation function and sometimes it's hit up to 7 times in a row and other times it's not. This makes no sense, as, to me, this should be working. Perplexing...
SOLUTION (SORT OF):
Updating the StartAnimation() function to this, seems to fix this issue, but seems more of a duct tape solution:
private void StartAnimation() {
if (refreshItem != null && refreshItem.getActionView() == null)
{
final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null);
final Animation rotation = AnimationUtils.loadAnimation(this, R.anim.refresh);
ivRefresh.startAnimation(rotation);
refreshItem.setActionView(ivRefresh);
}
}
To create a smooth ui-experience, your 'loading wheel' animation should probably start when the user clicks the link - rather than when the new page starts loading - and end when the new page has loaded. This makes the app seem more responsive to the user, and is the behaviour implemented in Dolphin Browser, as an example.
To implement this, you need to listen for the user's link clicks in the WebView. How to do this has already been covered in this answer here on SO:
Detect click on HTML button through javascript in Android WebView
You have to validate that the click is in fact on a link to a new page. You can find the clicked HTML element via WebView's HitTestResult class. This answer on SO gives you the details on how to validate the HitTestResult value:
Get the click event from webpage in my android application
You start your animation from your onClick() method and end it from your WebViewClient's onPageFinished() method and, in case the new page doesn't load, also in onReceivedError().
Make the Animation variable the member of your Browser class and make sure you stop the animation before leaving the activity.
You can use the concept of threads.
Till the URL in Web View loads, you show the loading animation
and when URL is loaded stop the animation.
You need to use two threads, one for progress indicator (i.e URL Loading) and the other UI thread for your animation.
Search for it!