Webview not working correctly in nestedscrollview - android

I have some content in NestedScrollView and under this content i have WebView with height wrap_content. When i scroll NestedScrollView scroll on element inside WebView not work.
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="#drawable/ic_launcher_foreground" />
<ImageView
android:id="#+id/imageView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="#drawable/ic_launcher_foreground" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<WebView
android:id="#+id/widgets"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
WebView inside NestedScrollView (not work)
WebView without NestedScrollView

public class CustomView extends WebView {
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onTouchEvent(MotionEvent event){
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
}
<com.abc.customer.android.widgets.CustomView
android:id="#+id/my_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Structure looks like
<?xml version="1.0" encoding="utf-8"?>
<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=".ui.main.view.MainActivity">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
app:srcCompat="#drawable/abc_vector_test" />
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
app:srcCompat="#drawable/abc_vector_test" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
app:srcCompat="#drawable/abc_vector_test" />
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
app:srcCompat="#drawable/abc_vector_test" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</RelativeLayout>
in backend
private lateinit var webView: WebView
webView = findViewById(R.id.webview)
webView.settings.setJavaScriptEnabled(true)
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view?.loadUrl(url)
return true
}
}
webView.loadUrl("https://www.google.co.in/")

Related

NestedScrollView with viewPager in CoordinatorLayout

Below is the code to handle the correct behaviour of my actionBar/toolbar/tabBar and below them the nestedScrollView with a ViewPager(webView). The ViewPager is basically a normal webView.
I am seeking to copy this exact behavior:
Everything works except my ViewPager can't be scrolled vertically at the same time as the toolBar being scrolled. When the viewPager is being scrolled the toolbar is static (in order to make the toolbar scroll aswell I need to manually scroll the toolbar-area but it does not get affected by the viewPager at all). I am not able to scroll both at the same time like the example above!
My code:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".ui.activity.FragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
app:theme="#style/M.Toolbar"
app:popupTheme="#style/M.Toolbar.PopupTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
android:visibility="gone"
android:background="#color/background"
app:background="#color/background"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#android:color/transparent"
android:fillViewport="true"
>
<com.m.ui.util.EdgeScrollViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:visibility="visible"
>
</com.m.ui.util.EdgeScrollViewPager>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
In order to make my viewPager(webView) scrollable I added a new class which extends webView:
public class TouchyWebView extends WebView {
public TouchyWebView(Context context) {
super(context);
}
public TouchyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TouchyWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onTouchEvent(MotionEvent event){
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
}
My viewPager.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<com.m.ui.base.TouchyWebView
android:id="#+id/web_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:visibility="visible" />
<LinearLayout
android:id="#+id/web_loadingview"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_gravity="center">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
android:layout_gravity="center"/>
</LinearLayout>
</FrameLayout>
Regards

Android Scrollview doesn't work behind navigation drawer

I have an Activity which have navigation drawer that works perfectly but behind the drawer ScrollView doesn't work.
Here is my xml code,
<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:paddingTop="4dp"
tools:context="com.bala.beautytipstamil.Content">
<WebView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/include"
android:layout_below="#+id/txtTitle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imgContent"
android:layout_width="match_parent"
android:layout_height="150dp" />
<WebView
android:id="#+id/txtContent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</ScrollView>
<include
android:id="#+id/include"
layout="#layout/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/navList"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:background="#ffeeeeee" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
Please help!
Put your ScrollView inside DrawerLayout like below code. just copy and paste it.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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:paddingTop="4dp"
tools:context="com.bala.beautytipstamil.Content">
<WebView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/include"
android:layout_below="#+id/txtTitle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imgContent"
android:layout_width="match_parent"
android:layout_height="150dp" />
<WebView
android:id="#+id/txtContent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</ScrollView>
<include
android:id="#+id/include"
layout="#layout/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
<ListView
android:id="#+id/navList"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:background="#ffeeeeee" />
</android.support.v4.widget.DrawerLayout>
public class VerticalScrollview extends ScrollView {
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
return false;
default: break;
}
return false;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
return true;
}
}

How to create your own controls in Android Studio

I looked at the official tutorial but I just don't get it.
This is my class:
public class mycontrol extends GridLayout {
public mycontrol(Context context, AttributeSet attrs) {
super(context, attrs);
}}
This is my res/layout/mycontrol.xml:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="60dp"
android:columnCount="4"
android:rowCount="2"
android:background="#drawable/cellshapeownstatus"
android:paddingTop="5dp"
android:id="#+id/my_status_id">
<TextView
android:textColor="#FFFFFF"
android:layout_column="1"
android:layout_row="0"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="doing stuff"
android:id="#+id/myOwnName" /></GridLayout>
This is my res/layout/activity_main.xml, where I want to show mycontrol:
<LinearLayout 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="2dp"
android:paddingRight="2dp"
tools:context=".MainActivity"
android:orientation="vertical"
android:background="#0A3E61"
android:id="#+id/activity_main_id">
<com.example.test.mycontrol
android:id="#+id/my_status"
android:layout_width="fill_parent"
android:layout_height="70dp"/></LinearLayout>
Nothing shows up in the Designer Preview. I can build without errors, but it instantly crashes when I try to run it on my Phone.
Simply use 'include'
<include
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="#layout/mycontrol"
/>
You don't need to extend GridLayout and you forgot to inflate your xml:
public class MyControl extends FrameLayout {
public MyControl(Context context, AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.mycontrol, this);
}
}
layout:
<LinearLayout 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="2dp"
android:paddingRight="2dp"
tools:context=".MainActivity"
android:orientation="vertical"
android:background="#0A3E61"
android:id="#+id/activity_main_id">
<com.example.test.MyControl
android:id="#+id/my_status"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

SwipeRefreshLayout with fixed header

I have the sequent layout:
<com.example.CustomSwipeRefreshLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/include" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/header_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<ListView
android:id="#+id/lv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
</com.example.CustomSwipeRefreshLayout>
with fixed header and a scrollable list. CustmoSwipeRefreshLayout is a class that extends SwipeRefreshLayout:
public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {
private ListView childListView;
public CustomSwipeRefreshLayout(Context context) {
super(context);
}
public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setChildListView(ListView childListView) {
this.childListView = childListView;
}
#Override
public boolean canChildScrollUp() {
return childListView.getFirstVisiblePosition() != 0;
}
(where childListView is the widget with id lv). This code doesn't work as i want. In fact, progress circle appear in two cases:
- i swipe listview to top
- i make swipe gesture on header and listview has first element visible.
I would that progress circle appear both if i swipe listview to top (as works now), and also if i make swipe gesture on header and listview is not to top element
I had the same problem, my solution was set android:clickable="true" inside my parent layout. try it like this:
<com.example.CustomSwipeRefreshLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/include" >
<LinearLayout
android:clickable="true" <!-- this line -->
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/header_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<ListView
android:id="#+id/lv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
</com.example.CustomSwipeRefreshLayout>

calendarview stops scrolling when nested in scrollview in android

I have nested calendarview in ScrollView . My problem begins when height of view increases.
I can scroll calendar months vertically but when scrollview scrollbar comes it does not let scroll calendar. Instead of scrolling calendar the whole view scroll up or down.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout android:orientation="vertical" android:id="#+id/ReminderLayout"
android:layout_width="fill_parent" android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="#+id/TaskName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords"
android:singleLine="true"
android:textSize="26.0sp" />
<View
android:id="#+id/seperator"
android:layout_width="fill_parent"
android:layout_height="1dip" />
<TextView
android:id="#+id/lblNotes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Notes" />
<EditText
android:id="#+id/TaskNotes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:textSize="26.0sp" />
<View
android:id="#+id/seperator"
android:layout_width="fill_parent"
android:layout_height="1dip" />
<TextView
android:id="#+id/lblReminder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Reminder" />
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content">"
<CalendarView
android:id="#+id/calendarReminder"
android:layout_width="fill_parent"
android:layout_height="250dp"
android:scrollbars="vertical"
android:isScrollContainer="true" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TimePicker
android:id="#+id/timePickerReminder"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:gravity="center" />
</LinearLayout>
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="wrap_content" >
<View android:id="#+id/seperator" android:layout_width="fill_parent" android:layout_height="1dip"/>
<TextView android:id="#+id/ReminderTime" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="On Time" android:paddingLeft="20dip"/>
<View android:id="#+id/seperator" android:layout_width="fill_parent" android:layout_height="1dip"/>
<TextView android:id="#+id/Recurring" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Only Once" android:paddingLeft="20dip"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
I've found answer to this problem here:
https://stackoverflow.com/a/9687545
Basically you need to implement custom CalendarView and override onInterceptTouchEvent method.
I did it as following:
package com.example.app.views;
public class CalendarViewScrollable extends CalendarView {
public CalendarViewScrollable(Context context) {
super(context);
}
public CalendarViewScrollable(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CalendarViewScrollable(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
{
ViewParent p = getParent();
if (p != null)
p.requestDisallowInterceptTouchEvent(true);
}
return false;
}
}
Then just use this view in XML layout file:
<com.example.app.views.CalendarViewScrollable
android:id="#+id/datePicker1"
android:layout_width="400dp"
android:layout_height="400dp"
/>
Here's one solution, you can implement a custom ScrollView which will only intercept verticale swipe.
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {...}
"onInterceptTouchEvent" will return false for horizontal swipe, so horizontal swipe will be enable for the CalendarView.
You can read more about this heree : https://stackoverflow.com/a/2655740/5158173

Categories

Resources