SwipeRefreshLayout conflict with scroll down in WebView - android

In my WebView application SwipeRefreshLayout doesn't work because when I scroll down it triggers page reload function.
One solution I think would be limit the pull-to-refresh layout. I tried this and it doesn't seem to work.
Here is my implementation:
Java file
SwipeRefreshLayout mySwipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySwipeRefreshLayout = (SwipeRefreshLayout)this.findViewById(R.id.swipeContainer);
String URL = "my_url";
mWebView = (WebView) findViewById(R.id.enyakin);
WebSettings webSettings = mWebView.getSettings();
mWebView.loadUrl(URL);
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient() {
// Phone call function if this matters
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("tel:"))
{
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(intent);
return true;
}
view.loadUrl(url);
return true;
}
});
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mWebView.reload();
if (null != mySwipeRefreshLayout) {
mySwipeRefreshLayout.setRefreshing(false);
}
}
}
);
XML file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.google.firebase.quickstart.fcm.MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fillViewport="true">
<WebView
android:id="#+id/enyakin"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
Can you help me to understand how can I seperate those two scrolling features?
Edit:
Looked here this doesn't answer my question

use setOnChildScrollUpCallback to control when a refresh should be triggered.
Here is the sample code in kotlin.
mySwipeRefreshLayout.apply {
setOnRefreshListener {
// Handle refresh
}
setOnChildScrollUpCallback {parent, child ->
// Return true to disable swiping to refresh.
// You can get scrolling position of nested scroll view and only return true when it is larger than 0.
}
}

Related

How to use RefreshView in project type "Android App (Xamarin)"

I have created a project of type "Android App (Xamarin)" in VS2019 which has the following activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:id="#+id/web"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
I have code that uses the pipes a value from the built in NFC reader on Samsung tablet to the web page loaded into the WebView, and all is working well.
However, if a page load stalls or the user gets an error in the web page for some reason, there is no way to refresh the page. I wanted to add a pull down to refresh, and also a pull from left to right to go back would be pretty cool as well, but will focus on pull to refresh in this post.
I found a Xamarin Forms example of how to use the RefreshView to achieve this, but it doesn't seem to work in the Android only project.
How can I use the RefreshView in my "Android App (Xamarin)" project, or is there a better way to do this?
I am targeting Android 9.0.
Thanks for your time.
A simple sample like below:
public class RefreshWebView : Activity,SwipeRefreshLayout.IOnRefreshListener,SwipeRefreshLayout.IOnChildScrollUpCallback
{
private WebView webView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.refresh_webview);
SwipeRefreshLayout swipeRefreshLayout = FindViewById<SwipeRefreshLayout>(Resource.Id.swipe_fresh);
webView = FindViewById<WebView>(Resource.Id.web);
webView.LoadUrl("https://www.google.com");
webView.SetWebViewClient(new MyWebClient(swipeRefreshLayout));
swipeRefreshLayout.SetOnRefreshListener(this);
swipeRefreshLayout.SetOnChildScrollUpCallback(this);
}
public void OnRefresh()
{
webView.LoadUrl(webView.Url.ToString());
}
public bool CanChildScrollUp(SwipeRefreshLayout parent, View child)
{
return webView.ScrollY > 0;
}
class MyWebClient : WebViewClient
{
SwipeRefreshLayout swipeRefresh;
public MyWebClient(SwipeRefreshLayout swipeRefreshLayout)
{
swipeRefresh = swipeRefreshLayout;
}
public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
{
view.LoadUrl(request.Url.ToString());
return true;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
if (swipeRefresh.Refreshing)
{
swipeRefresh.Refreshing = false;
}
}
}
}
xaml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_fresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<WebView
android:id="#+id/web"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>

WebView Swipe-to-Refresh Issue: Scrolling up triggers a refresh

When I scroll up in my webview app, it triggers a Swipe-to-Refresh refresh-
How can I make the refresh to trigger only when reaching the top of the page?
I saw this post about this exact problem, but I couldn't understand where to insert the code
If you answer please be specific about how I implement the code and where
Thank you
If you're using WebView only,
you may have to use these layout in the provided order,
SwipeRefreshLayout
1.1 NestedScrollView
1.1.1 WebView
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/webview1"
android:layout_width="598dp"
android:layout_height="1022dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
And in your Activity
public class WebView1 extends AppCompatActivity {
SwipeRefreshLayout swipeRefreshLayout;
WebView browser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
browser = (WebView) findViewById(R.id.webview1);
swipeRefreshLayout = (SwipeRefreshLayout)this.findViewById(R.id.swipeContainer);
browser.setWebViewClient(new WebViewClient());browser.getSettings().setJavaScriptEnabled(true);
browser.loadUrl("http://www.google.com");
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
browser.reload();
swipeRefreshLayout.setRefreshing(false);
}
});
}
}
If you're copying this code, please note that I'm importing androidx libraries
To make it to support libraries, consider the following
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout/>
<androidx.nesv4.widget.NestedScrollView/>
to
<android.support.v4.widget.SwipeRefreshLayout/>
<android.support.v4.widget.NestedScrollView/>

SwipeRefreshLayout and to handle external links in webview( manual class) not working together in android webview

I am using webview in android i have implemented pull to refresh in webview. Also i have created a class that handles the external links inside the website to open the links within the app only but the problem is reloader keeps on loading like this
xml file of webview fragment
<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.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe2"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<WebView
android:id="#+id/Zomato"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
/>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
SwipeLayout in the Desc.java
SwipeRefreshLayout swipe;
static WebView webView;
#Override
public void onViewCreated(#NonNull final View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
webView=view.findViewById(R.id.Zomato);
swipe=view.findViewById(R.id.swipe2);
}
swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
String url = "https://www.zomato.com/";
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
swipe.setRefreshing(false);
}
});
}
webView.setWebViewClient(new Fragment2.GeoWebViewClient());
Hi Actually you are doing wrong because here you are setting web view client tow time means it will override first one so please set only first time and put logic in that onPageFinished it will work. Referer bellow answer
https://stackoverflow.com/a/6720004/3894930

Load webview in the top of the page

I'm working in a WebView App.
In my last change, i added a function to hide the app bar when i scroll down in webview. Nice !!!
But i have noticed a problem. I will try explain.
Let's suposse that i'm in a News Site, and i'm openning the last news. The most recent news are in the start of the page, and the last news are close to the ends of the page, so i open the last news, and my webview load the url. When the url is loaded, my webview is in the end of the site, and not in the start. It started after i added my "webview" inside of "NestedScrollView". Looks like NestedScrollView is saving my position, and it's affecting my position in the web page. How to fix this ?
Edit: My webview is load inside Framelayout, my webview is a fragment.
WebView Layout
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipelayout">
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
>
<WebView
android:id="#+id/inicio_pagina"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"></WebView>
</android.support.v4.widget.NestedScrollView>
FrameLayout
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</android.support.design.widget.CoordinatorLayout>
App_Bar_Main
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main"
android:id="#+id/include" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/face"
android:scaleType="center"/>
Edit 2: WebView Fragment
public class InicioPagina extends Fragment {
private ProgressBar prg;
SwipeRefreshLayout mySwipeRefreshLayout;
NestedScrollView NestedScrollView;
public WebView myWebView;
public static InicioPagina newInstance() {
InicioPagina fragment = new InicioPagina();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.iniciopagina, container, false);
prg = (ProgressBar)rootView.findViewById(R.id.progressBar2);
NestedScrollView = (NestedScrollView) rootView.findViewById(R.id.nested_scroll_view);
mySwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipelayout);
myWebView = (WebView) rootView.findViewById(R.id.inicio_pagina);
myWebView.loadUrl("http://google.com.br/");
//*Ativar JavaScript
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
//*Forçar links para abrir no WebView ao invés do navegador
myWebView.setWebViewClient(new WebViewClient());
NestedScrollView.scrollTo(0, 0);
myWebView.setVerticalScrollBarEnabled(false);
mySwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
myWebView.reload();
mySwipeRefreshLayout.setRefreshing(false);
}
});
myWebView.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;
}
});
return rootView;
}
public class WebViewClient extends android.webkit.WebViewClient{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
prg.setVisibility(View.VISIBLE);
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, String url) {
prg.setVisibility(View.GONE);
super.onPageFinished(view, url);
}
}
1) Make id for the NestedScrollView
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical">
2) Create NestedScrollView object
3) When the new URL is loaded, set the scroll property of the nestedScrollViewobject to 0,0.
nestedScrollViewObj.scrollTo(0, 0);

Progressbar in ActionBar

I am working with an app which will load a website Inside the app .Now i want to add a ProgressBar in action bar without swipe up to repress feature.
Like that
I am using Fragment in my app.
WebviewFragment
public class WebviewFragment extends Fragment {
WebView webView;
String newslink;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_webview, container, false);
newslink = getArguments().getString("LINK");
webView = (WebView) view.findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(newslink);
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webView.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return false;
}
});
return view;
}
}
fragment_webview.XML
<?xml version="1.0" encoding ="utf-8"?
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/webView" />
</LinearLayout>
Any solution for me ?
if you want add progress to actionbar call this method before setlayout
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
UPDATE where should request window feature
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
.... // other code goes here
}
and call this method when you want run it
EDIT in fragment you can add getActivity() before requestWindowFeature to be getActivity().requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true); // turn progress on
setProgressBarIndeterminateVisibility(false); // turn progress off
hope this work , my recommendation to use toolbar
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/material_green_500"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<ProgressBar
android:id="#+id/toolbar_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="#795548"
android:indeterminateTintMode="src_in"
android:layout_gravity="right"
/>
</android.support.v7.widget.Toolbar>
Why I recommended toolbar with ProgressBar ?
for two reasons , First setSupportProgressBarIndeterminate deprecated.
Second easy to use just set setVisibility method to make it visible call setVisibility(View.VISIBLE);
to hide view call setVisibility(View.GONE);

Categories

Resources