Scroll Webview inside a Scroll View - android

What I have:
Right now I have a Scroll view as a parent. Inside this scroll view, I am using a WebView that loads a URL and then shows text in it.
Here is my xml:
<ScrollView
android:id="#+id/parentScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/Heading" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp" >
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#drawable/webview" />
</RelativeLayout>
</ScrollView>
What I want:
I want to scroll webView inside it. When I touch the webView, unfortunately the parent scroll view gets called.
I have to keep Parent scroll view also but besides this I want to scroll WebView content inside it when I touch on webView.
How can I do this?

Create a Custom Touch Intercepting Webview
CustomWebview.java
package com.mypackage.common.custom.android.widgets
public class CustomWebview extends WebView {
public CustomWebview(Context context) {
super(context);
}
public CustomWebview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomWebview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onTouchEvent(MotionEvent event){
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
}
in layout.xml
<com.package.custom.widgets.CustomWebview
android:id="#+id/view_extra"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

According to Android design documents you should never put a scrolling container inside a scrolling container if they scroll the same direction. It's not meant to handle such a thing.

I had the same problem. You should set your webView Height equal as its content. for this do this:
add this lines to your onCreate method in Activity:
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
webView.loadUrl("javascript:MyApp.resize(document.body.getBoundingClientRect().height)");
super.onPageFinished(view, url);
}
});
webView.addJavascriptInterface(this, "MyApp");
and add this method to your activity:
#JavascriptInterface
public void resize(final float height) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
webView.setLayoutParams(new LinearLayout.LayoutParams(getResources().getDisplayMetrics().widthPixels, (int) (height * getResources().getDisplayMetrics().density)));
}
});
}

Nested scrollable widgets are generally discouraged. It is a confusing user experience because it's easy to scroll the wrong thing. Say I intend to scroll the outer scroll region but I touched the inner region first and flinged really hard. Then the inner one will scroll and I'll be like huh? Why didn't it scroll?
Even if one scrolls horizontal and the other is vertical the gesture recognizers might confuse one for another so you get the same effect. It's a valid use case but it's still iffy and I'd avoid it. (IE: Humans don't perfectly swipe vertically and horizontally properly, it's usually with an angle.)
I would push to change the design to break out the scrollable areas. Ideally 1 scrollable item per page. Even propose one yourself and provide to the designer both experiences and see which one they choose.
To express how this will suck. Look at this example. This isn't a solution but just to show the experience.
<ScrollView
android:id="#+id/parentScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/Heading" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="#+id/topText"
android:layout_width="match_parent"
android:layout_height="1000dp"
android:text="#string/lotsoftext" />
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#drawable/webview" />
<TextView
android:id="#+id/topText"
android:layout_width="match_parent"
android:layout_height="1000dp"
android:text="#string/lotsoftext" />
</RelativeLayout>

Related

ViewPager : swipe only from a particular view

I have a created a custom viewpager, and i would like the user to swipe and change pages only from a part of the screen.
Every page has a linearlayout at the bottom with some text, and i would like to swipe only from there, not from the hole screen.
Is that possible?
This is my custom viewpager class:
public class MyViewPager extends ViewPager {
private boolean mSwipable = true;
public MyViewPager(Context context) {
super(context);
}
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return mSwipable ? super.onInterceptTouchEvent(event) : false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return mSwipable ? super.onTouchEvent(event) : false;
}
public boolean isSwipable() {
return mSwipable;
}
public void setSwipable(boolean swipable) {
mSwipable = swipable;
}
}
and this is the view of a page:
<?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"
android:background="#color/white"
android:clipChildren="false"
android:clipToPadding="false"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/fragment_search">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomLayout"
android:layout_marginBottom="#dimen/bottom_bar_height">
//show some stuff here
</LinearLayout>
<LinearLayout
android:id="#+id/bottomMenu"
android:layout_width="match_parent"
android:layout_height="#dimen/bottom_bar_height"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:orientation="horizontal">
// this is my footer, where i need to change the pages by swipe
</LinearLayout>
</RelativeLayout>
Follow this question in order to be able to disable swiping at will How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?
And combine that with your SliderAdapter in order to control which pages will be swipeable or not.
If you followed the link above, on your subclass of ViewPager, you can add some GestureDetector on onTouchEvent(MotionEvent event) and feed it with your event, like Android: How to handle right to left swipe gestures
By doing this, you will now have some onSwipeRight and manage there your logic, delegating to the adapter the question if the page should be swiped or not, or where to go next.

HTML scrolling events in an Android WebView that's inside a ScrollView

I have a web page for testing purposes ( https://storage.googleapis.com/htmltestingbucket/nested_scroll_helper.html ) that just prints a counter of the scroll event the html has caught in a fixed header
When the Android WebView is the only scroll-able element in the fragment everything is fine and the WebView sends the scroll events to the page
If I want to add native elements above and below the WebView then things get much more complex.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="SOMETHING ABOVE THE WEBVIEW" />
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="SOMETHING BELOW THE WEBVIEW" />
</LinearLayout>
</ScrollView>
I know it's not good to have a WebView inside a ScrollView but I have to provide a single scrolling experience with hybrid content and proper scrolling events in the html document.
I found plenty of questions on the matter but I was able to create a full end-to-end solution
Also, I know lint has an Offical check for that:
NestedScrolling
--------------- Summary: Nested scrolling widgets
Priority: 7 / 10 Severity: Warning Category: Correctness
A scrolling widget such as a ScrollView should not contain any nested
scrolling widgets since this has various usability issues
And yet, I can't implement the web view content in native so I need an alternative way to do that
To Keep Webview inside scrollview here you need to measure height of the webview and set it in layout params.
Here i have tried to give answer for the scrollable webview.
<ScrollView
android:layout_width="fill_parent" android:background="#FF744931"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="WebViewLayout">
<TextView
android:id="#+id/txtVoiceSeachQuery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:textSize="26sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="SOMETHING ABOVE THE WEBVIEW" />
<com.example.ScrollableWebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:isWebViewInsideScroll="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="SOMETHING BELOW THE WEBVIEW" />
</LinearLayout>
</ScrollView>
res/values/attrs.xml
To add attribute for the Custom Control
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollableWebView">
<attr name="isWebViewInsideScroll" format="boolean"></attr>
</declare-styleable>
</resources>
ScrollableWebView
public class ScrollableWebView extends WebView {
private boolean webViewInsideScroll = true;
public static final String RESOURCE_NAMESPACE = "http://schemas.android.com/apk/res-auto";
public ScrollableWebView(Context context) {
super(context);
}
public ScrollableWebView(Context context, AttributeSet attrs) {
super(context, attrs);
setWebViewInsideScroll(attrs.getAttributeBooleanValue
(RESOURCE_NAMESPACE, "isWebViewInsideScroll", true));
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isWebViewInsideScroll()) {
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
setLayoutParams(params);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public boolean isWebViewInsideScroll() {
return webViewInsideScroll;
}
public void setWebViewInsideScroll(boolean webViewInsideScroll) {
this.webViewInsideScroll = webViewInsideScroll;
}
}
To fetch attribute value you can also use Stylable but here i have done without using it.
ScrollableWebView webview = (ScrollableWebView) findViewById(R.id.webview);
webview.loadUrl("https://storage.googleapis.com/htmltestingbucket/nested_scroll_helper.html");
Below is link of output
Shows Textview(any view) on top inside scrollview with webview
Show TextView(any view) on bottom inside scrollview with webview
If you dont want to create attribute file & add Custom attributes in res/values/attrs.xml than you can ignore that file & check this pastebin here i gave without any custom attribute like isWebViewInsideScroll. you can remove it from xml layout too.
Let me know if anything.
if you place you webview inside scrollview you will not get html scrolling effect, because your webview content will not scroll ( it will be placed full lengtth inside scrollview.)
To face your need to place elements above and below you can listen to webview scroll and use DragViewHelper or nineoldandroids to move header and footer, so user will think, they are single element (you dont need scrollview).
webView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
ViewHelper.setTranslationY(headerTextView, -event.getY());
}
});
public class ObservableWebView extends WebView {
private OnScrollChangeListener onScrollChangeListener;
public ObservableWebView(Context context) {
super(context);
}
public ObservableWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ObservableWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (onScrollChangeListener != null) {
onScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
}
}
public void setOnScrollChangeListener(OnScrollChangeListener onScrollChangeListener) {
this.onScrollChangeListener = onScrollChangeListener;
}
public OnScrollChangeListener getOnScrollChangeListener() {
return onScrollChangeListener;
}
public interface OnScrollChangeListener {
/**
* Called when the scroll position of a view changes.
*
* #param v The view whose scroll position has changed.
* #param scrollX Current horizontal scroll origin.
* #param scrollY Current vertical scroll origin.
* #param oldScrollX Previous horizontal scroll origin.
* #param oldScrollY Previous vertical scroll origin.
*/
void onScrollChange(WebView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
}
}
This example should help you to hide header, i used nineoldandroid for it
It seems the most elegant way I could find to handle this is as following:
- Listen to the SrollView scrolls:You can use an ObservableScrollView or call setOnScrollChangeListener() from API level 23
- Calculate the scroll Y offset in pixels
- Call the WebView.evaluateJavascript()
- Pass it all the details of the scroll event
So the general concepts is passing:
"$(document).trigger('scroll');" as the first param evaluateJavascript
I'm still testing the details and working out the kinks but it Seems like the better way to go, I will try to edit this answer with more info as I solve this
If anyway has a better solution for I would like to hear it
I have the same issue recently and I found your posts here :)
I have a WebView nested in a ScrollVIew. And the page which I loaded into WebView need to call a JS function when it scroll to the end, but in scroll view , web page's window.onscroll = functionXXX() {} never get called.
Finally, I have to set a OnScrollListener to the ScrollView, and call my JS function manually by the code below
#Override
public void onScroll(int scrollY) {
if (!scrollView.canScrollVertically(scrollY)) {
mWebView.loadUrl("javascript:functionXXX();");
}
}
Maybe our situations are different, but I hope it will give u some inspiration :)
in fact it is not so good put an scrollable view into another. Try to use this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
And
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>

How to stop ScrollView from scrolling through to bottom of the current loaded page in WebView

I know there are similar questions and I already tried and implemented all those solution suggestions. However, none of them worked with me.Even Though WebView Finished Loading Data, ScrollView Never Stops Scrolling to the Bottom. I want to use pull to refresh and hide the action bar with onScrollListener. Everything is good but I can't prevent scrolView from non-stop scrolling to the bottom.
I read this: How to prevent a scrollview from scrolling to a webview after data is loaded?
I read this as well: webview is forcing my scrollview to the bottom
I tried to implement a custom scrollview which overrides requestChildFocus method.
I added android:descendantFocusability="blocksDescendants" to my xml file.
I added android:focusableInTouchMode="true" too but still no good, no change. It still forces to scroll forever.
Here is my Custom scrollview:
package com.example.john.cosmicbrowser;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.webkit.WebView;
import android.widget.ScrollView;
public class MyScrollView extends ScrollView
{
public MyScrollView(Context context)
{
super(context);
}
public MyScrollView(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
}
public MyScrollView(Context context, AttributeSet attributeSet, int defStyle)
{
super(context, attributeSet, defStyle);
}
#Override
public void requestChildFocus(View child, View focused)
{
if (focused instanceof WebView)
return;
super.requestChildFocus(child, focused);
}
}
Here is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe"
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:descendantFocusability="blocksDescendants"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".WebActivity"
tools:showIn="#layout/activity_webview"
>
<com.example.john.cosmicbrowser.MyScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:descendantFocusability="blocksDescendants"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
>
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:padding="0dp"/>
<ProgressBar
android:id="#+id/cosmicProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:indeterminate="false"/>
</RelativeLayout>
</com.example.john.cosmicbrowser.MyScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
For example imagine you opened Google.com on this webview. After page loaded it incredibly scrolls down to the bottom you can't even see any information at the bottom of the page. How can I fix this problem? Any help would be extremely appreciated! Thanks in advance!
By the way adding android:descendantFocusability="blocksDescendants" causing problems like you can't search once Google.com opened you can't enter any input to the Google's search bar!
I got the same issues. My solution is to set the height of the webview equal to its content right after loading URL:
mWebView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mWebView.getMeasuredHeight());
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
mWebView.setLayoutParams(params);
}
});
Please note that RelativeLayout is the parent of the WebView in my case, you should change to your corresponding one.

Hide keyboard in Scrollview when user touches (outside), scrolls or clicks (other views) in Android

This might look like a redundant and already answered query but I am stuck. I have browsed through previously shared plethora of responses but none of them turned out to be a holistic solution.
Here's how the main activity xml looks like:
<RelativeLayout >
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<ScrollView >
<LinearLayout >
<android.support.v7.widget.CardView >
<LinearLayout >
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView >
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
</RelativeLayout>
<android.support.design.widget.NavigationView />
The Problem
There is a edit text view in child linear layout of first card view. As of now, if I click on it, the keyboard pops up but doesn't hide when I click elsewhere or scroll the page or click any other view (there's a drop down).
What I plan to do is to hide the keyboard when,
1. I click anywhere outside the edit text view.
2. Scroll the page.
3. Interact with other views (the drop down).
Possible Solutions Tried
how to dismiss keyboard from editText when placed in scroll view - This one isn't working at all for me.
How to hide soft keyboard on android after clicking outside EditText? - There was one solution from #vida which worked partially, as in when clicked outside, the keyboard did dismiss. But then again, that's only a partial solution to what I am trying to achieve.
I would appreciate if someone could share a solution (or procedure) to sort this one out. Thanks!
You could try to override the Scroll Views onClickListener to call this method every time the user clicks anywhere on the app. If that doesnt work just set the outer relative layout to be clickable and everytime the layout is clicked you can call this hideKeyboard method!
public void hideKeyboard(View view) {
InputMethodManager im =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
First, extend EditText and add a snippet of code that helps dismiss the keyboard every time the EditText instances lose their focus
public class MyEditText extends AppCompatEditText {
public MyEditText(Context context) {
super(context);
setupEditText();
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setupEditText();
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupEditText();
}
public void setupEditText() {
// Any time edit text instances lose their focus, dismiss the keyboard!
setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && !(findFocus() instanceof MyEditText)) {
hideKeyboard(v);
} else {
showKeyboard(v);
}
}
});
}
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public void showKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(view, 0);
}
}
Then, set android:clickable="true" and android:focusableInTouchMode="true" in the child layout of your ScrollView!
Please note that, it should be the child layout of ScrollView, not ScrollView itself.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<MyEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</MyEditText>
</LinearLayout>
</ScrollView>
That should work!

Button not clickable in custom LinearLayout

I have a custom view that contain a framelayout. This framelayout contain two views (LinearLayout) that can be swipe. If I swipe the first one, the second one appears and vice versa. One of those views has a button but I don't know why, this button is like disable. I cannot click on it and the onClick method has no effect.
Here the structure of the layout xml inflated in the custom view :
<FrameLayout>
<LinearLayout
android:id="#+id/frontview"
/>
<LinearLayout
android:id="#+id/backview">
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/ButtonUpdate"
android:text="#string/bUpdate"
android:padding="5dp"
android:clickable="true"
style="?android:attr/borderlessButtonStyle"
/>
</LinearLayout>
</FrameLayout>
Here the code in my custom view :
public class mView extends LinearLayout {
ImageView icon;
TextView current_data;
TextView previous_data;
TextView time ;
Button bUpdate;
EditText TextUpdate;
public mView(Context context) {
super(context);
init(context);
}
public mView(Context context, AttributeSet attrs) {
super(context,attrs);
init(context);
}
public mView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// nothing
}
}
public void init(Context pContext) {
LayoutInflater inflater = (LayoutInflater) pContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View ll = inflater.inflate(R.layout.list_item_data, this, true);
/** We initialize the elements of our UI **/
/**
* First View
*/
icon= (ImageView) ll.findViewById(R.id.ic_icon);
current_data = ll.(TextView) findViewById(R.id.current_data);
previous_data = ll.(TextView) findViewById(R.id.previous_data);
time = (TextView) ll.findViewById(R.id.time);
/**
* Second View
*/
bUpdate = (Button) ll.findViewById(R.id.ButtonUpdate);
TextUpdate= (EditText) ll.findViewById(R.id.TextUpdate);
bUpdate.setOnClickListener(new bUpdateClickListener());
}
private class bUpdateClickListener implements OnClickListener {
#Override
public void onClick(View v) {
// When the button is clicked, the front view re-appears and the backview disappears
frontview
.animate()
.translationX(0);
backview
.animate()
.translationX(-backview.getMeasuredWidth());
}
}
The swipe is correctly handle with onInterceptTouchEvent(MotionEvent ev) and onTouchEvent(MotionEvent ev).
Here the main.xml used in MyActivity :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f6f6f6">
<TextView
android:id="#+id/infoimc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:layout_marginTop="8dp"
android:text="#string/app_name"
android:textColor="#000000"
android:textSize="16dp"/>
<View
android:id="#+id/divider_infoimc"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginRight="18dp"
android:layout_marginLeft="18dp"
android:background="#99CC00"/>
<com.example.essai.CustomGraph
android:id="#+id/CustomGraph"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:visibility="visible"
android:layout_marginTop="10dp"/>
</LinearLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="80dp"
android:layout_gravity="left|center_vertical">
<com.example.essai.mView
android:id="#+id/CustomView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
</LinearLayout>
And MyActivity.class :
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
I don't know if the button must be handle also in the Activity ?
Thanks for your help !
The root cause
According to API:
FrameLayout is designed to block out an area on the screen to display
a single item.
If there is more items, like in your case, then "unexpected" things will happen:
Child views are drawn in a stack, with the most recently added child
on top.
This means, your frontview is on top of your backview and since the frontview doesn't have android:clickable="true" the click events (on button) are not delegated below.
Solution 1
Reorder the child-layout gravity programmatically.
You can, however, add multiple children to a FrameLayout and control
their position within the FrameLayout by assigning gravity to each
child, using the android:layout_gravity attribute.
Just switch the android:layout_gravity="top" and android:layout_gravity="bottom" whenever you are sliding them.
Solution 2
Control the visibility of the child-layouts programmatically.
When the backview should be displayed, set the visibility of the frontview to View.GONE. And set it to View.VISIBLE in the reversed case.
Solution 3
Change FrameLayout to a different layout type.
Could require more "fiddling" with layout xmls...
See what you're familliar with the most and choose the solution accordingly :)

Categories

Resources