I have a List and I need to Display all websites from this list in a Loop one after each other in a WebView. Between switching from one website to the other one I have also a individual time which is also in a other list with the same size.
But if I try to display the site in a WebView it sometimes skips a website and the times are not accurate. Can someone improve my code please and tell me where the misstake is?
public class WebshowActivity extends AppCompatActivity {
private List<String> htmlSites = new ArrayList<>();
private List<Integer> timeForSite = new ArrayList<>();
private int counter = 0;
WebView webView;
boolean firstCall = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webshow);
//Fullscreen settings
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
//implement list from utils
timeForSite.add(10);//this is the 0th index and it's needed for the first URL load which is emepty
for (int i = 0; i < Utilities.list.size(); i++) {
htmlSites.add(Utilities.list.get(i).getPath());
timeForSite.add(Utilities.list.get(i).getDuration());
}
//WebView
webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl("");
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
Toast.makeText(WebshowActivity.this, "Time for this Website: " + timeForSite.get(counter) + "ms", Toast.LENGTH_SHORT).show();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
webView.loadUrl(htmlSites.get(counter));
counter++;
if (firstCall == true) {
timeForSite.remove(0);
firstCall = false;
} else {
counter++;
}
if (counter == htmlSites.size()) {
counter = 0;
}
}
}, timeForSite.get(counter));
}
});
}
}
The Lists are in a other Class but I think the error is inside the onPageFinished Method.
UPDATE: To make scheduling more precise using Timer.
Here is an example:
public class MainActivity extends AppCompatActivity {
//mock
private static class SomeComplicatedObject {
private final String mPath;
private final Integer mDuration;
public SomeComplicatedObject(final String path, final int duration){
mPath = path;
mDuration = duration;
}
String getPath() { return mPath; }
Integer getDureation() { return mDuration; }
}
private static final List<SomeComplicatedObject> complicatedList = new ArrayList<>();
static {
complicatedList.add(new SomeComplicatedObject("http://google.com", 1000));
complicatedList.add(new SomeComplicatedObject("http://facebook.com", 2000));
complicatedList.add(new SomeComplicatedObject("http://google.com", 3000));
complicatedList.add(new SomeComplicatedObject("http://twitter.com", 3000));
}
private static final String TAG = "MainActivity";
private final ArrayList<Pair<String, Integer>> mSitesToDisplay = new ArrayList<>();
private final Timer mTimer = new Timer("LoadNext");
private final Handler mHandler = new Handler();
private WebView mWebView = null;
private int mIndex = -1;
private void fillSitesToDisplay(List<SomeComplicatedObject> list) {
mIndex = -1;
mSitesToDisplay.clear();
for (SomeComplicatedObject item : list) {
mSitesToDisplay.add(new Pair<>(item.getPath(), item.getDureation()));
}
}
private Pair<String, Integer> getNext() {
mIndex = (mIndex+1) % mSitesToDisplay.size();
return mSitesToDisplay.get(mIndex);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fillSitesToDisplay(complicatedList);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
mWebView = (WebView)findViewById(R.id.webview);
//initial start delayed by 1 sec
mTimer.schedule(createTimerTask(), TimeUnit.SECONDS.toMillis(1));
}
private Runnable mDisplayNextPage = new Runnable() {
#Override
public void run() {
final Pair<String, Integer> pathTimePair = getNext();
Log.e(TAG, "DisplayNext::run : Start loading next page : " + pathTimePair.first);
mWebView.setWebViewClient(new WaitPageLoadedClient(mTimer, createTimerTask(), pathTimePair.second));
mWebView.loadUrl(pathTimePair.first);
}
};
private TimerTask createTimerTask() {
return new TimerTriggered(mHandler, mDisplayNextPage);
}
//simple utility class for notifying timer triggered event
//on UI thread.
private static class TimerTriggered extends TimerTask {
Runnable mOnTriggered;
Handler mHandler;
protected TimerTriggered(Handler handler, Runnable onTriggered) {
super();
mHandler = handler;
mOnTriggered = onTriggered;
}
#Override
public void run() {
//Timer runs int it's own thread so we need to
//pass execution to MainThread for accessing WebView.
mHandler.post(mOnTriggered);
}
}
private static class WaitPageLoadedClient extends WebViewClient {
private final TimerTask mRunOnFinished;
private final Timer mTimer;
private final Integer mDelay;
public WaitPageLoadedClient(Timer timer, TimerTask toRunOnFinished, Integer delay) {
mRunOnFinished = toRunOnFinished;
mTimer = timer;
mDelay = delay;
}
#Override
public void onPageFinished(WebView view, String url) {
Log.e(TAG, "onPageFinished: Schedule timer for " + mDelay);
mTimer.schedule(mRunOnFinished, mDelay);
}
}
}
It will cycle forever.
Although Snackbar is beautiful, it doesn't persist when changing activities. This is a bummer in scenarios where I would like to confirm that a message was sent using a Snackbar, before finishing the activity. I've considered pausing the code before exiting the activity, but have found that to be a bad practice.
If what I describe isn't possible, is there any type of material design toast message? Or a way to make a rectangular toast message; one with rounded edges of a smaller radius?
To create a Snackbar with the application context which is visible across multiple activities:
Get the WindowManager as system service
Create and add a FrameLayout (rootView) with type WindowManager.LayoutParams.TYPE_TOAST and WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL to the WindowManager
Wait until on FrameLayout.onAttachedToWindow() is called in the FrameLayout (rootView)
Get the window token of the FrameLayout (rootView) with View.getWindowToken()
Create a ContextThemeWrapper with the application context and a derived #style/Theme.AppCompat
Use the new context to create an additional FrameLayout (snackbarContainer)
Add this FrameLayout (snackbarContainer) with type WindowManager.LayoutParams.TYPE_APPLICATION_PANEL and flag WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Wait until on View.onAttachedToWindow() is called in the FrameLayout (snackbarContainer)
Create the Snackbar like normal with the FrameLayout (snackbarContainer)
Set View.onDismissed() callback to the Snackbar and remove the FrameLayouts (rootView and snackbarContainer)
Show the snackbar Snackbar.show()
Here a working wrapper (NOTE: Swipe to dismiss is not working. Maybe some one else find the correct WindowManager.LayoutParams flags to receive touch events Fixed by CoordinatorLayout):
public class SnackbarWrapper
{
private final CharSequence text;
private final int duration;
private final WindowManager windowManager;
private final Context appplicationContext;
#Nullable
private Snackbar.Callback externalCallback;
#Nullable
private Action action;
#NonNull
public static SnackbarWrapper make(#NonNull Context applicationContext, #NonNull CharSequence text, #Snackbar.Duration int duration)
{
return new SnackbarWrapper(applicationContext, text, duration);
}
private SnackbarWrapper(#NonNull final Context appplicationContext, #NonNull CharSequence text, #Snackbar.Duration int duration)
{
this.appplicationContext = appplicationContext;
this.windowManager = (WindowManager) appplicationContext.getSystemService(Context.WINDOW_SERVICE);
this.text = text;
this.duration = duration;
}
public void show()
{
WindowManager.LayoutParams layoutParams = createDefaultLayoutParams(WindowManager.LayoutParams.TYPE_TOAST, null);
windowManager.addView(new FrameLayout(appplicationContext)
{
#Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
onRootViewAvailable(this);
}
}, layoutParams);
}
private void onRootViewAvailable(final FrameLayout rootView)
{
final CoordinatorLayout snackbarContainer = new CoordinatorLayout(new ContextThemeWrapper(appplicationContext, R.style.FOL_Theme_SnackbarWrapper))
{
#Override
public void onAttachedToWindow()
{
super.onAttachedToWindow();
onSnackbarContainerAttached(rootView, this);
}
};
windowManager.addView(snackbarContainer, createDefaultLayoutParams(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, rootView.getWindowToken()));
}
private void onSnackbarContainerAttached(final View rootView, final CoordinatorLayout snackbarContainer)
{
Snackbar snackbar = Snackbar.make(snackbarContainer, text, duration);
snackbar.setCallback(new Snackbar.Callback()
{
#Override
public void onDismissed(Snackbar snackbar, int event)
{
super.onDismissed(snackbar, event);
// Clean up (NOTE! This callback can be called multiple times)
if (snackbarContainer.getParent() != null && rootView.getParent() != null)
{
windowManager.removeView(snackbarContainer);
windowManager.removeView(rootView);
}
if (externalCallback != null)
{
externalCallback.onDismissed(snackbar, event);
}
}
#Override
public void onShown(Snackbar snackbar)
{
super.onShown(snackbar);
if (externalCallback != null)
{
externalCallback.onShown(snackbar);
}
}
});
if (action != null)
{
snackbar.setAction(action.text, action.listener);
}
snackbar.show();
}
private WindowManager.LayoutParams createDefaultLayoutParams(int type, #Nullable IBinder windowToken)
{
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.format = PixelFormat.TRANSLUCENT;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.gravity = GravityCompat.getAbsoluteGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, ViewCompat.LAYOUT_DIRECTION_LTR);
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
layoutParams.type = type;
layoutParams.token = windowToken;
return layoutParams;
}
#NonNull
public SnackbarWrapper setCallback(#Nullable Snackbar.Callback callback)
{
this.externalCallback = callback;
return this;
}
#NonNull
public SnackbarWrapper setAction(CharSequence text, final View.OnClickListener listener)
{
action = new Action(text, listener);
return this;
}
private static class Action
{
private final CharSequence text;
private final View.OnClickListener listener;
public Action(CharSequence text, View.OnClickListener listener)
{
this.text = text;
this.listener = listener;
}
}
}
EDIT
Once SnackbarWrapper is defined you can use it like this:
final SnackbarWrapper snackbarWrapper = SnackbarWrapper.make(getApplicationContext(),
"Test snackbarWrapper", Snackbar.LENGTH_LONG);
snackbarWrapper.setAction(R.string.snackbar_text,
new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Action",
Toast.LENGTH_SHORT).show();
}
});
snackbarWrapper.show();
If you don't have a theme, you can quickly define one in styles.xml:
<style name="FOL_Theme_SnackbarWrapper" parent="#style/Theme.AppCompat">
<!--Insert customization here-->
</style>
EDIT
For those on Android Oreo getting Bad Token Exception, change TYPE_TOAST to TYPE_APPLICATION_OVERLAY. This is due to Android Oreo implementing special permissions to draw over applications. You can ask for this permissions using:
if(!Settings.canDrawOverlays(Activity.this){
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, URI.parse("package:" + getPackageName()));
startActivityForResult(intent, REQ_CODE);
}
If I understand correctly, you do this:
Activity A launch Activity B to send a message
Once message is send, you display a confirmation message
You go back to Activity A
You can use SnackBar to do that by using an ActivityResult (here is a StackOverflow post with how to use it)
Here are the steps:
Activity A launch Activity B with startActivityForResult
Do your stuff on Activity B
Set your result (check the link above to understand)
Finish Activity
In Activity A, get that code in OnActivityResult and display your
SnackBar with the proper message
This allow you do display a Snackar in Activity A corresponding to result of Activity B.
Hopes it can helps your problem
Just in case somebody needs to do this in Xamarin I have adapted the accepted answer which I found really helpful.
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Widget;
using System;
public class SnackbarWrapper
{
private readonly string text;
private readonly int duration;
private readonly IWindowManager windowManager;
private readonly Context appplicationContext;
private Snackbar.Callback externalCallback;
private SnackbarAction action { get; set; }
public static SnackbarWrapper make(Context applicationContext, string text, int duration)
{
return new SnackbarWrapper(applicationContext, text, duration);
}
private SnackbarWrapper(Context appplicationContext, string text, int duration)
{
this.appplicationContext = appplicationContext;
var wm = appplicationContext.GetSystemService(Context.WindowService);
// We have to use JavaCast instead of a normal cast
this.windowManager = wm.JavaCast<IWindowManager>();
this.text = text;
this.duration = duration;
}
public void Show()
{
WindowManagerLayoutParams layoutParams = createDefaultLayoutParams(WindowManagerTypes.Toast, null);
var frameLayout = new FrameLayout(appplicationContext);
frameLayout.ViewAttachedToWindow += delegate
{
//this.onAttachedToWindow();
onRootViewAvailable(frameLayout);
};
windowManager.AddView(frameLayout, layoutParams);
}
private void onRootViewAvailable(FrameLayout rootView)
{
var ctw = new ContextThemeWrapper(appplicationContext, Resource.Style.Base_Theme_AppCompat);
CoordinatorLayout snackbarContainer = new CoordinatorLayout(ctw);
snackbarContainer.ViewAttachedToWindow += delegate
{
onSnackbarContainerAttached(rootView, snackbarContainer);
};
windowManager.AddView(snackbarContainer, createDefaultLayoutParams(WindowManagerTypes.ApplicationPanel, rootView.WindowToken));
}
private void onSnackbarContainerAttached(View rootView, CoordinatorLayout snackbarContainer)
{
Snackbar snackbar = Snackbar.Make(snackbarContainer, text, duration);
snackbar.SetCallback(new SnackbarCallbackImpl(rootView, snackbarContainer, windowManager));
if (action != null)
{
snackbar.SetAction(action.Text, action.Listener);
}
snackbar.Show();
}
private WindowManagerLayoutParams createDefaultLayoutParams(WindowManagerTypes type, IBinder windowToken)
{
WindowManagerLayoutParams layoutParams = new WindowManagerLayoutParams();
layoutParams.Format = Format.Translucent;
layoutParams.Width = ViewGroup.LayoutParams.MatchParent;
/* Si ponemos aqui WrapContent en alguna ocasion en la que haya un action largo y el texto tambien, el snackbar puede volverse como loco
* asi que usamos MatchParent. Aun asi sucede que a veces se puede mostrar en una linea o en dos el mismo texto, pero al menos no hace el temblor loco que de la otra forma*/
layoutParams.Height = ViewGroup.LayoutParams.MatchParent;
layoutParams.Gravity = GravityFlags.CenterHorizontal | GravityFlags.Bottom;
layoutParams.Flags = WindowManagerFlags.NotTouchModal;
layoutParams.Type = type;
layoutParams.Token = windowToken;
return layoutParams;
}
public SnackbarWrapper SetCallback(Snackbar.Callback callback)
{
this.externalCallback = callback;
return this;
}
public SnackbarWrapper SetAction(string text, Action<View> listener)
{
action = new SnackbarAction(text, listener);
return this;
}
}//class
internal class SnackbarAction
{
public string Text { get; set; }
public Action<View> Listener { get; set; }
public SnackbarAction(string text, Action<View> listener)
{
Text = text;
Listener = listener;
}
}
internal class SnackbarCallbackImpl : Snackbar.Callback
{
public Snackbar.Callback externalCallback { get; set; }
View rootView;
CoordinatorLayout snackbarContainer;
IWindowManager windowManager;
public SnackbarCallbackImpl(View rootView, CoordinatorLayout snackbarContainer, IWindowManager windowManager)
{
this.rootView = rootView;
this.snackbarContainer = snackbarContainer;
this.windowManager = windowManager;
}
public override void OnShown(Snackbar snackbar)
{
base.OnShown(snackbar);
externalCallback?.OnShown(snackbar);
}
public override void OnDismissed(Snackbar snackbar, int evt)
{
base.OnDismissed(snackbar, evt);
// Clean up (NOTE! This callback can be called multiple times)
if (snackbarContainer.Parent != null && rootView.Parent != null)
{
windowManager.RemoveView(snackbarContainer);
windowManager.RemoveView(rootView);
}
externalCallback?.OnDismissed(snackbar, evt);
}
}
To have a rectangular Toast, set a rectangular background for the Toast or just set a different background color for the Toast.
Refer this post where it was posted as a problem. But it your case it is a possible solution.
UPDATE: See selected answer.
The best solution to my question is using a Timer after the presenting the Snackbar and then in the run() method of the timer, starting the activity.
Snackbar.show(); // Excluded make for brevity.
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
Intent chooseVideoIntent = new Intent(Intent.ACTION_GET_CONTENT); // Any type of content/file. Song, doc, video...
chooseVideoIntent.setType("video/*");
startActivityForResult(chooseVideoIntent, CHOOSE_VIDEO_REQUEST);
}
}, 2 * 1000);
UPDATE: I found that by using findViewById(android.R.id.content) as the view in Snackbar.make() the Snackbar persists among fragment changes.
Actually I just need to display a message and I don't need a onClickListener on the message.
If you just need to show a message look at "Myke Dev" answer in this thread which is the one I needed:
https://stackoverflow.com/a/34640942/9993413
(Don't give upvote to me, give upvote to "Myke Dev" which wrote the answer)
In user1185087 answer you must request permissions from user by opening settings and this, for me, isn't a good thing for user interactions, but I thinks is the only way if you want to show a snackbar with an onClickListener.
(Maybe you can use an activity with no background which launch a snackbar-like dialog, but it won't act just as a window_alert snackbar)
I have can WebView in Fragment, when move tab Fragment,and I touch Button aboutUs--> move in Fragment AboutUs; I repeat about 10times.
Error is same picture.
can everyone help me?. Thank :
Code Fragment load WebView :
public class InAppBrowserFragment
extends BaseFragment {
private static final String LINK_PAGE = "linkPage";
private static final String TITLE_ACTION_BAR = "titleActionBar";
#InjectView(R.id.web_settings)
WebView mWebViewSettings;
#InjectView(R.id.actionbar_settings_sub)
ActionBar mActionBar;
#InjectView(R.id.img__settings_background)
ImageView mImgSettingsBackground;
/**
* Static method used to create an instance for this fragment.
*
* #return New instance of Fragment.
*/
public static InAppBrowserFragment newInstance(String titleActionBar,
String linkPage) {
final InAppBrowserFragment fragment = new InAppBrowserFragment();
final Bundle data = new Bundle();
if (titleActionBar != null) {
data.putString(LINK_PAGE,
linkPage);
data.putString(TITLE_ACTION_BAR,
titleActionBar);
}
// Attach data with fragment.
fragment.setArguments(data);
return fragment;
}
#Override
protected int getLayoutResourceId() {
return R.layout.fragment_in_app_browser;
}
#Override
protected void initUi(final Bundle savedInstanceState) {
String titleActionBar = getArguments().getString(TITLE_ACTION_BAR);
//set background
CommonUtil.displayImage(getActivity(),
CommonUtil.getDrawableResource(R.drawable.img_random_frontpage_1),
this.mImgSettingsBackground,
0,
0,
0,
true,
false,
null);
//set UI Action Bar
this.mActionBar.setupUI(null,
titleActionBar,
R.drawable.ab_ic_back,
0,
"");
this.mActionBar.setButtonRightPadding(0);
this.mActionBar.setButtonLeftListener(new ActionBar.IActionBarButtonLeftListener() {
#Override
public void onButtonLeftClicked(final View view) {
popBack(true);
mWebViewSettings.canGoBack();
}
});
}
#Override
protected void loadData(final Bundle savedInstanceState) {
String linkPage = getArguments().getString(LINK_PAGE);
// Init webview setting
WebSettings settings = mWebViewSettings.getSettings();
settings.setJavaScriptEnabled(true);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(true);
settings.setSupportZoom(true);
mWebViewSettings.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
}
});
mWebViewSettings.loadUrl(linkPage);
}
}
Conrect:
Inconrect:
i fix sucess :(set wrap_content for Webview )
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/CreateTrips.Widget.ScreenContent.Fragment">
<ImageView
android:id="#+id/img__settings_background"
style="#style/CreateTrips.Widget.BackgroundImage"
android:contentDescription="#null"/>
<com.createtrips.ui.widgets.ActionBar
android:id="#+id/actionbar_settings_sub"
style="#style/CreateTrips.Widget.ActionBar"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:layout_marginTop="#dimen/widget_action_bar_height"
>
<WebView
android:id="#+id/web_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</FrameLayout>
I want to get html source code in c# (mono for android)
I add webview in my project. webview name is web.
my code:
WebView webView;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main); webView.Settings.JavaScriptEnabled = true;
webView.Settings.SetSupportZoom(true);
webView.Settings.BuiltInZoomControls = true;
webView.Settings.LoadWithOverviewMode = true; //Load 100% zoomed out
webView.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
webView.ScrollbarFadingEnabled = true;
webView.VerticalScrollBarEnabled = true;
webView.HorizontalScrollBarEnabled = true;
webView.SetWebViewClient(new AwesomeWebClient());
webView.SetWebChromeClient(new AwesomeWebChromeClient(this));
webView.LoadUrl(#"http://www.google.com");
}
private class AwesomeWebClient : WebViewClient { }
private class AwesomeWebChromeClient : WebChromeClient
{
private Activity mParentActivity;
private string mTitle;
private string username;
private string password;
private string oldurl="";
public AwesomeWebChromeClient(Activity parentActivity)
{
mParentActivity = parentActivity;
mTitle = parentActivity.Title;
}
public override void OnProgressChanged(WebView view, int newProgress)
{
mParentActivity.Title = string.Format("Loading {0}%", newProgress);
mParentActivity.SetProgress(newProgress * 100);
if (newProgress==100) mParentActivity.Title=mTitle;
}
}
I open www.google.com in webview component and I want to see html source code
I don't believe that there is a way to obtain the HTML from the WebView.
Instead, you should grab the HTML yourself with a WebRequest, e.g. this handy StackOverflow answer.
I'm sharing some variables accross activities by using a class like this :
public class Globals {
static Boolean hint1_graph_type_switcher;
static Boolean hint2_stockview_valuation;
other variables ...
}
then I'm using these variables anywhere across my multiple activites with ...
if (Globals.hint2_stockview_valuation == false) {
....
}
pretty basic and it was working fine untill ...
I introduced some webview stuff like this:
//-----------------------------------------------------------
// open a webview with the NEWS when the more_arrow is clicked :
mNews.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String news_URL = "http://us.m.yahoo.com/w/yfinance/symbolheadlines/"+ ticker + "/?.intl=us&.lang=en";
Intent news_Webview_intent = new Intent(Chart_View.this, News_Webview.class);
news_Webview_intent.putExtra("NEWS_URL", news_URL);
startActivity(news_Webview_intent);
}
});
//-----------------------------------------------------------
and here's the News_Webview.class:
public class News_Webview extends Activity {
//
// http://www.chrisdanielson.com/tag/progressdialog/
//
String news_URL;
private WebView webview;
private ProgressDialog progressBar;
private static final String TAG = "Hub";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.webview_news);
this.webview = (WebView)findViewById(R.id.webView);
Bundle extras = getIntent().getExtras();
if (this.getIntent().getExtras()!=null){
news_URL = extras.getString("NEWS_URL");
}
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
progressBar = ProgressDialog.show(News_Webview.this, "", "Loading...");
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//Log.i(TAG, "Processing webview url click...");
Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(url));
startActivity(viewIntent);
return true;
}
public void onPageFinished(WebView view, String url) {
//Log.i(TAG, "Finished loading URL: " +url);
if (progressBar.isShowing()) {
progressBar.dismiss();
}
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Log.e(TAG, "Error: " + description);
Toast.makeText(News_Webview.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
alertDialog.setTitle("Error");
alertDialog.setMessage(description);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alertDialog.show();
}
});
webview.loadUrl(news_URL);
}
}
the problem now is that, when it "comes back" from this Activity, it looks like my Globals variables have disappeared ???
if (Globals.hint2_stockview_valuation == false) {
fires an error :
06-23 12:14:03.443:
ERROR/AndroidRuntime(2611): Caused by:
java.lang.NullPointerException
2 questions then :
Should I use something else than this "Global" class to share variables across activities ? Is it just bad practice to do this ?? I know that I can use the preferences but I thought it was quicker to do it this way (no need to "read" the preferences everytime I start a new activity ...
Any idea on WHY this is happening ? Should I "get back" my savedInstanceState in some way when my activity returns from the News_Webview.class ???
As always, thank you for your help.
H.
U could use intent.putExtra() for inter-activity interaction...
One thing(just for diagnostics) i would suggest is initializing the static variables to some value and then run the App... i suppose your global class is getting re-initialized when the intent started activity returns back...
I have used global variables, but in my case i kept them in an activity which never died. All other activities came after it and it worked perfectly fine...
The NullPointerException is bubbling up from the android runtime and has nothing to do with your Globals type.