package oak.web; import android.annotation.SuppressLint; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import oak.OAK; import oak.R; /** * Created by ericrichardson on 1/9/14. */ public class OakWebViewFragment extends Fragment { public static final int PROVIDED_LAYOUT = 0; private String url; private WebView webView; private View refresh, progress, back, fwd, container; private boolean hidden, openInBrowserEnabled = false, showControls = true, refreshInMenuEnabled = false; private boolean fadeControls = true; private long fadeTimeout = 1500; private int layoutId = R.layout.webview; private float fadeoutMinimum = 0.2f; private float fadeoutMaximum = 1.0f; public static class BundleBuilder { private Bundle bundle; public BundleBuilder(Bundle bundle) { this.bundle = bundle; } public BundleBuilder(String url) { bundle = new Bundle(); bundle.putString(OAK.EXTRA_URL, url); } public BundleBuilder showControls(boolean showControls) { bundle.putBoolean(OAK.EXTRA_SHOW_CONTROLS, showControls); return this; } public BundleBuilder fadeControls(boolean fadeControls) { bundle.putBoolean(OAK.EXTRA_CONTROL_FADE, fadeControls); return this; } public BundleBuilder layoutId(int layoutId) { bundle.putInt(OAK.EXTRA_LAYOUT, layoutId); return this; } public BundleBuilder fadeTimeout(long milliseconds) { bundle.putLong(OAK.EXTRA_FADE_TIMEOUT, milliseconds); return this; } public BundleBuilder maxControlAlpha(float maxAlpha) { bundle.putFloat(OAK.EXTRA_FADE_MAX, maxAlpha); return this; } public BundleBuilder minControlAlpha(float minAlpha) { bundle.putFloat(OAK.EXTRA_FADE_MIN, minAlpha); return this; } public BundleBuilder openInBrowserEnabled(boolean enabled) { bundle.putBoolean(OAK.EXTRA_OPEN_IN_BROWSER, enabled); return this; } public BundleBuilder refreshInMenuEnabled(boolean enabled) { bundle.putBoolean(OAK.EXTRA_REFRESH_IN_MENU, enabled); return this; } public Bundle build() { return bundle; } } /** * Sets whether buttons fade out after touch * * @param fadeControls whether to fade controls after inactivity */ public void setFadeControls(boolean fadeControls) { this.fadeControls = fadeControls; } /** * Sets whether WebView should show controls * * @param showControls whether to show controls */ public void setShowControls(boolean showControls) { this.showControls = showControls; } /** * Sets time in seconds for how long after touch buttons fade out * * @param fadeTimeout timeout for fade in seconds */ public void setFadeTimeout(long fadeTimeout) { this.fadeTimeout = fadeTimeout; } /** * Sets maximum alpha when buttons fade in * * @param maxAlpha maximum alpha for controls. */ public void setMaximumAlpha(float maxAlpha) { this.fadeoutMaximum = maxAlpha; } /** * Set's minimum alpha when buttons fade out * * @param minAlpha minimum alpha for controls */ public void setMinimumAlpha(float minAlpha) { this.fadeoutMinimum = minAlpha; } /** * Set Whether a "open in browser" option is shown in menu. * * @param openInBrowserEnabled whether to open links in device default browser */ public void setOpenInBrowserEnabled(boolean openInBrowserEnabled) { this.openInBrowserEnabled = openInBrowserEnabled; } public void setRefreshInMenuEnabled(boolean refreshInMenuEnabled) { this.refreshInMenuEnabled = refreshInMenuEnabled; } public void setWebViewClient(WebViewClient client) { webView.setWebViewClient(client); } public void setwebChromeClient(WebChromeClient client) { webView.setWebChromeClient(client); } public void back() { if (webView != null && webView.canGoBack()) { webView.goBack(); } } public boolean canGoBack() { return webView.canGoBack(); } public boolean canGoForward() { return webView.canGoForward(); } public void forward() { if (webView != null && webView.canGoForward()) { webView.goForward(); } } public void refresh() { if (webView != null) { webView.reload(); } } public static OakWebViewFragment getInstance(String url) { return getInstance(new BundleBuilder(url).build()); } public static OakWebViewFragment getInstance(Bundle arguments) { OakWebViewFragment fragment = new OakWebViewFragment(); fragment.setArguments(arguments); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); url = getArguments().getString(OAK.EXTRA_URL); setOpenInBrowserEnabled(getArguments().getBoolean(OAK.EXTRA_OPEN_IN_BROWSER, true)); setFadeControls(getArguments().getBoolean(OAK.EXTRA_CONTROL_FADE, true)); setShowControls(getArguments().getBoolean(OAK.EXTRA_SHOW_CONTROLS, true)); setFadeTimeout(getArguments().getLong(OAK.EXTRA_FADE_TIMEOUT, 1500l)); setMaximumAlpha(getArguments().getFloat(OAK.EXTRA_FADE_MAX, 1.0f)); setMinimumAlpha(getArguments().getFloat(OAK.EXTRA_FADE_MIN, 0.2f)); setRefreshInMenuEnabled(getArguments().getBoolean(OAK.EXTRA_REFRESH_IN_MENU, false)); layoutId = getArguments().getInt(OAK.EXTRA_LAYOUT, R.layout.webview); setHasOptionsMenu(refreshInMenuEnabled || openInBrowserEnabled); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(layoutId, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); webView = (WebView) view.findViewById(R.id.webview); if (webView == null) { throw new IllegalStateException("Layout used with this webview must contain a WebView with the ID R.id.webview"); } if (showControls) { back = view.findViewById(R.id.back); fwd = view.findViewById(R.id.forward); refresh = view.findViewById(R.id.refresh); progress = view.findViewById(R.id.progress); if (back != null) { back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (webView.canGoBack()) { webView.goBack(); } } }); } if (fwd != null) { fwd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (webView.canGoForward()) { webView.goForward(); } } }); } if (refresh != null) { refresh.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { webView.reload(); progress.setVisibility(View.VISIBLE); refresh.setVisibility(View.INVISIBLE); } }); } webView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (hidden) { hidden = false; unHide(); } else { view.postDelayed(new Runnable() { @Override public void run() { hide(); hidden = true; } }, fadeTimeout); } return false; } }); } else { view.findViewById(R.id.button_container).setVisibility(View.GONE); } webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setPluginState(WebSettings.PluginState.ON); webView.getSettings().setAllowFileAccess(true); webView.getSettings().setUseWideViewPort(true); webView.getSettings().setLoadsImagesAutomatically(true); webView.getSettings().setSupportZoom(!fadeControls); webView.getSettings().setBuiltInZoomControls(!fadeControls); webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http")) { view.loadUrl(url); return true; } else { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); return true; } } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { if (showControls) { refresh.setVisibility(View.INVISIBLE); progress.setVisibility(View.VISIBLE); } super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { if (showControls) { refresh.setVisibility(View.VISIBLE); progress.setVisibility(View.INVISIBLE); configureButtons(view); } super.onPageFinished(view, url); } }); webView.loadUrl(url); } @Override public void onResume() { super.onResume(); } @SuppressLint("NewApi") private void unHide() { configureButtons(webView); if (fadeControls) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { if (refresh != null) { refresh.animate().alpha(fadeoutMaximum); } if (progress != null) { progress.animate().alpha(fadeoutMaximum); } } } } @SuppressLint("NewApi") private void hide() { configureButtons(webView); if (fadeControls) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { if (refresh != null) { refresh.animate().alpha(fadeoutMinimum); } if (progress != null) { progress.animate().alpha(fadeoutMinimum); } } } } @SuppressLint("NewApi") private void configureButtons(WebView webView) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { if (webView.canGoBack()) { back.animate().alpha(hidden && fadeControls ? fadeoutMinimum : fadeoutMaximum); back.setEnabled(true); } else { back.animate().alpha(fadeoutMinimum); back.setEnabled(false); } if (webView.canGoForward()) { fwd.animate().alpha(hidden && fadeControls ? fadeoutMinimum : fadeoutMaximum); fwd.setEnabled(true); } else { fwd.animate().alpha(fadeoutMinimum); fwd.setEnabled(false); } } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); if (openInBrowserEnabled) { menu.add(Menu.NONE, R.id.oak_menu_open_in_broswer, Menu.NONE, R.string.open_in_browser); } if (refreshInMenuEnabled) { menu.add(Menu.NONE, R.id.oak_menu_refresh, Menu.NONE, R.string.refresh_in_menu); } } @Override public boolean onOptionsItemSelected(android.view.MenuItem item) { if (item.getItemId() == R.id.oak_menu_open_in_broswer) { Intent toBroswer = new Intent(Intent.ACTION_VIEW); toBroswer.setData(Uri.parse(webView.getUrl())); startActivity(toBroswer); } if (item.getItemId() == R.id.oak_menu_refresh) { webView.reload(); } return super.onOptionsItemSelected(item); } }