cleaner titlewebview implementation
This commit is contained in:
parent
1d8a003fe1
commit
723fff03ec
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.fox.ttrss"
|
package="org.fox.ttrss"
|
||||||
android:versionCode="126"
|
android:versionCode="127"
|
||||||
android:versionName="1.4" >
|
android:versionName="1.5" >
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="8"
|
android:minSdkVersion="8"
|
||||||
|
@ -2,8 +2,14 @@
|
|||||||
android:id="@+id/article_fragment"
|
android:id="@+id/article_fragment"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:padding="5sp"
|
android:orientation="vertical"
|
||||||
android:orientation="vertical" >
|
android:padding="5sp" >
|
||||||
|
|
||||||
|
<org.fox.ttrss.TitleWebView
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1" >
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/article_header"
|
android:id="@+id/article_header"
|
||||||
@ -14,20 +20,20 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:textColor="?linkColor"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="There are many variations of passages of Lorem Ipsum available"
|
android:text="There are many variations of passages of Lorem Ipsum available"
|
||||||
|
android:textColor="?linkColor"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/comments"
|
android:id="@+id/comments"
|
||||||
android:textColor="?linkColor"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="24 comments"
|
android:text="24 comments"
|
||||||
|
android:textColor="?linkColor"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -40,10 +46,10 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0.7"
|
android:layout_weight="0.7"
|
||||||
android:textColor="?headlineExcerptTextColor"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="{TAGS}"
|
android:text="{TAGS}"
|
||||||
|
android:textColor="?headlineExcerptTextColor"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -53,63 +59,55 @@
|
|||||||
android:layout_weight="0.2"
|
android:layout_weight="0.2"
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
android:text="{DATE}"
|
android:text="{DATE}"
|
||||||
android:textColor="?headlineExcerptTextColor"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textColor="?headlineExcerptTextColor"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
android:textStyle="italic" />
|
android:textStyle="italic" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="5sp"
|
||||||
android:layout_weight="0"
|
android:layout_weight="0"
|
||||||
android:background="?horizontalDivider"
|
android:background="?horizontalDivider"
|
||||||
android:layout_marginBottom="5sp"
|
|
||||||
android:paddingTop="2dip" />
|
android:paddingTop="2dip" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</org.fox.ttrss.TitleWebView>
|
||||||
|
|
||||||
<com.nobu_games.android.view.web.TitleBarWebView
|
<LinearLayout
|
||||||
android:id="@+id/content"
|
android:id="@+id/attachments_holder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="0" >
|
||||||
/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<Spinner
|
||||||
android:id="@+id/attachments_holder"
|
android:id="@+id/attachments"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0" >
|
android:layout_weight="1"
|
||||||
|
android:prompt="@string/attachments_prompt" />
|
||||||
|
|
||||||
<Spinner
|
<Button
|
||||||
android:id="@+id/attachments"
|
android:id="@+id/attachment_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="0"
|
||||||
android:prompt="@string/attachments_prompt" />
|
android:text="@string/attachment_view" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/attachment_view"
|
android:id="@+id/attachment_share"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0"
|
android:layout_weight="0"
|
||||||
android:text="@string/attachment_view" />
|
android:text="@string/attachment_share" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/attachment_share"
|
android:id="@+id/attachment_copy"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0"
|
android:layout_weight="0"
|
||||||
android:text="@string/attachment_share" />
|
android:text="@string/attachment_copy" />
|
||||||
|
</LinearLayout>
|
||||||
<Button
|
|
||||||
android:id="@+id/attachment_copy"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:text="@string/attachment_copy" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,14 +0,0 @@
|
|||||||
package android.webkit;
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trojan class for getting access to a hidden API level 16 interface
|
|
||||||
*/
|
|
||||||
public class WebViewClassic {
|
|
||||||
public interface TitleBarDelegate {
|
|
||||||
int getTitleHeight();
|
|
||||||
|
|
||||||
public void onSetEmbeddedTitleBar(final View title);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,353 +0,0 @@
|
|||||||
package com.nobu_games.android.view.web;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012 Thomas Werner
|
|
||||||
* Portions Copyright (C) 2006 The Android Open Source Project
|
|
||||||
* Portions Copyright (C) 2012 The K-9 Dog Walkers
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.webkit.WebView;
|
|
||||||
import android.webkit.WebViewClassic.TitleBarDelegate;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WebView derivative with custom setEmbeddedTitleBar implementation for Android
|
|
||||||
* versions that do not support that feature anymore.
|
|
||||||
* <p>
|
|
||||||
* <b>Usage</b>
|
|
||||||
* <p>
|
|
||||||
* Call {@link #setEmbeddedTitleBarCompat(View)} for setting a view as embedded
|
|
||||||
* title bar on top of the displayed WebView page.
|
|
||||||
*/
|
|
||||||
public class TitleBarWebView extends WebView implements TitleBarDelegate {
|
|
||||||
/**
|
|
||||||
* Internally used view wrapper for suppressing unwanted touch events on the
|
|
||||||
* title bar view when WebView contents is being touched.
|
|
||||||
*/
|
|
||||||
private class TouchBlockView extends FrameLayout {
|
|
||||||
public TouchBlockView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
||||||
if(!mTouchInTitleBar) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
switch(ev.getAction() & MotionEvent.ACTION_MASK) {
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
case MotionEvent.ACTION_CANCEL:
|
|
||||||
mTouchInTitleBar = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.dispatchTouchEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TAG = "TitleBarWebView";
|
|
||||||
View mTitleBar;
|
|
||||||
int mTitleBarOffs;
|
|
||||||
boolean mTouchInTitleBar;
|
|
||||||
boolean mTouchMove;
|
|
||||||
private Rect mClipBounds = new Rect();
|
|
||||||
private Matrix mMatrix = new Matrix();
|
|
||||||
private Method mNativeGetVisibleTitleHeightMethod;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will always contain a reference to the title bar view no matter if
|
|
||||||
* {@code setEmbeddedTitleBar()} or the Jelly Bean workaround is used. We use this in
|
|
||||||
* {@link #getTitleHeight()}.
|
|
||||||
*/
|
|
||||||
private View mTitleBarView;
|
|
||||||
|
|
||||||
public TitleBarWebView(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TitleBarWebView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TitleBarWebView(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <i>Corrects the visual displacement caused by the title bar view.</i>
|
|
||||||
* <p>
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
|
||||||
if(mTitleBar != null) {
|
|
||||||
final int sy = getScrollY();
|
|
||||||
final int visTitleHeight = getVisibleTitleHeightCompat();
|
|
||||||
final float x = event.getX();
|
|
||||||
float y = event.getY();
|
|
||||||
|
|
||||||
switch(event.getAction() & MotionEvent.ACTION_MASK) {
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
if(y <= visTitleHeight) {
|
|
||||||
mTouchInTitleBar = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
|
||||||
mTouchMove = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
case MotionEvent.ACTION_CANCEL:
|
|
||||||
mTouchMove = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mTouchInTitleBar) {
|
|
||||||
y += sy;
|
|
||||||
event.setLocation(x, y);
|
|
||||||
|
|
||||||
return mTitleBar.dispatchTouchEvent(event);
|
|
||||||
} else {
|
|
||||||
if(Build.VERSION.SDK_INT < 16) {
|
|
||||||
if(!mTouchMove) {
|
|
||||||
mTitleBarOffs = getVisibleTitleHeightCompat();
|
|
||||||
}
|
|
||||||
|
|
||||||
y -= mTitleBarOffs;
|
|
||||||
if(y < 0) y = 0;
|
|
||||||
event.setLocation(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.dispatchTouchEvent(event);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return super.dispatchTouchEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a {@link View} as an embedded title bar to appear on top of the
|
|
||||||
* WebView page.
|
|
||||||
* <p>
|
|
||||||
* This method tries to call the hidden API method setEmbeddedTitleBar if
|
|
||||||
* present. On failure the custom implementation provided by this class will
|
|
||||||
* be used instead.
|
|
||||||
*
|
|
||||||
* @param v The view to set or null for removing the title bar view.
|
|
||||||
*/
|
|
||||||
public void setEmbeddedTitleBarCompat(View v) {
|
|
||||||
try {
|
|
||||||
Method nativeMethod = getClass().getMethod("setEmbeddedTitleBar",
|
|
||||||
View.class);
|
|
||||||
nativeMethod.invoke(this, v);
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.d(TAG,
|
|
||||||
"Native setEmbeddedTitleBar not available. Starting workaround");
|
|
||||||
setEmbeddedTitleBarJellyBean(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
mTitleBarView = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int computeVerticalScrollExtent() {
|
|
||||||
if(mTitleBar == null) return super.computeVerticalScrollExtent();
|
|
||||||
return getViewHeightWithTitle() - getVisibleTitleHeightCompat();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int computeVerticalScrollOffset() {
|
|
||||||
if(mTitleBar == null) return super.computeVerticalScrollOffset();
|
|
||||||
return Math.max(getScrollY() - getTitleHeight(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
|
||||||
canvas.save();
|
|
||||||
|
|
||||||
if(child == mTitleBar) {
|
|
||||||
mTitleBar.offsetLeftAndRight(getScrollX() - mTitleBar.getLeft());
|
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT < 16) {
|
|
||||||
mMatrix.set(canvas.getMatrix());
|
|
||||||
mMatrix.postTranslate(0, -getScrollY());
|
|
||||||
canvas.setMatrix(mMatrix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean result = super.drawChild(canvas, child, drawingTime);
|
|
||||||
canvas.restore();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the currently visible height of the title bar view if set.
|
|
||||||
*
|
|
||||||
* @return Visible height of title bar view or 0 if not set.
|
|
||||||
*/
|
|
||||||
protected int getVisibleTitleHeightCompat() {
|
|
||||||
if(mTitleBar == null && mNativeGetVisibleTitleHeightMethod != null) {
|
|
||||||
try {
|
|
||||||
return (Integer) mNativeGetVisibleTitleHeightMethod
|
|
||||||
.invoke(this);
|
|
||||||
} catch(Exception e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.max(getTitleHeight() - Math.max(0, getScrollY()), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.save();
|
|
||||||
|
|
||||||
if(mTitleBar != null) {
|
|
||||||
final int sy = getScrollY();
|
|
||||||
final int sx = getScrollX();
|
|
||||||
mClipBounds.top = sy;
|
|
||||||
mClipBounds.left = sx;
|
|
||||||
mClipBounds.right = mClipBounds.left + getWidth();
|
|
||||||
mClipBounds.bottom = mClipBounds.top + getHeight();
|
|
||||||
canvas.clipRect(mClipBounds);
|
|
||||||
mMatrix.set(canvas.getMatrix());
|
|
||||||
int titleBarOffs = getVisibleTitleHeightCompat();
|
|
||||||
if(titleBarOffs < 0) titleBarOffs = 0;
|
|
||||||
mMatrix.postTranslate(0, titleBarOffs);
|
|
||||||
canvas.setMatrix(mMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onDraw(canvas);
|
|
||||||
canvas.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides a hidden method by replicating the behavior of the original
|
|
||||||
* WebView class from Android 2.3.4.
|
|
||||||
* <p>
|
|
||||||
* The worst that could happen is that this method never gets called, which
|
|
||||||
* isn't too bad because this does not harm the functionality of this class.
|
|
||||||
*/
|
|
||||||
protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
|
|
||||||
int l, int t, int r, int b) {
|
|
||||||
int sy = getScrollY();
|
|
||||||
|
|
||||||
if(sy < 0) {
|
|
||||||
t -= sy;
|
|
||||||
}
|
|
||||||
scrollBar.setBounds(l, t + getVisibleTitleHeightCompat(), r, b);
|
|
||||||
scrollBar.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the height of the title bar view.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* In the Jelly Bean workaround we need this method because we have to implement the
|
|
||||||
* {@link TitleBarDelegate} interface. But by implementing this method we override the hidden
|
|
||||||
* {@code getTitleHeight()} of the {@link WebView}s in older Android versions.
|
|
||||||
* <br>
|
|
||||||
* What we should do, is return the title height on Jelly Bean and call through to the parent
|
|
||||||
* class on older Android versions. But this would require even more trickery, so we just
|
|
||||||
* inline the parent functionality which simply calls {@link View#getHeight()}. This is exactly
|
|
||||||
* what we do on Jelly Bean anyway.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int getTitleHeight() {
|
|
||||||
if (mTitleBarView != null) {
|
|
||||||
return mTitleBarView.getHeight();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getViewHeightWithTitle() {
|
|
||||||
int height = getHeight();
|
|
||||||
if(isHorizontalScrollBarEnabled() && !overlayHorizontalScrollbar()) {
|
|
||||||
height -= getHorizontalScrollbarHeight();
|
|
||||||
}
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
try {
|
|
||||||
mNativeGetVisibleTitleHeightMethod = WebView.class
|
|
||||||
.getDeclaredMethod("getVisibleTitleHeight");
|
|
||||||
} catch(NoSuchMethodException e) {
|
|
||||||
Log.w(TAG,
|
|
||||||
"Could not retrieve native hidden getVisibleTitleHeight method");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The hidden method setEmbeddedTitleBar has been removed from Jelly Bean.
|
|
||||||
* This method replicates the functionality.
|
|
||||||
*
|
|
||||||
* @param v
|
|
||||||
*/
|
|
||||||
private void setEmbeddedTitleBarJellyBean(View v) {
|
|
||||||
if(mTitleBar == v) return;
|
|
||||||
|
|
||||||
if(mTitleBar != null) {
|
|
||||||
removeView(mTitleBar);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(null != v) {
|
|
||||||
LayoutParams vParams = new LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0);
|
|
||||||
|
|
||||||
TouchBlockView tbv = new TouchBlockView(getContext());
|
|
||||||
FrameLayout.LayoutParams tbvParams = new FrameLayout.LayoutParams(
|
|
||||||
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
|
||||||
tbv.addView(v, tbvParams);
|
|
||||||
addView(tbv, vParams);
|
|
||||||
v = tbv;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTitleBar = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSetEmbeddedTitleBar(View title) { /* unused */ }
|
|
||||||
}
|
|
@ -13,23 +13,19 @@ import org.jsoup.nodes.Document;
|
|||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.select.Elements;
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
import com.nobu_games.android.view.web.TitleBarWebView;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.ActionBar;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
|
import android.view.GestureDetector;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@ -42,7 +38,6 @@ import android.webkit.WebSettings.LayoutAlgorithm;
|
|||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -174,16 +169,17 @@ public class ArticleFragment extends Fragment implements GestureDetector.OnDoubl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleBarWebView web = (TitleBarWebView)view.findViewById(R.id.content);
|
TitleWebView web = (TitleWebView)view.findViewById(R.id.content);
|
||||||
|
|
||||||
if (web != null) {
|
if (web != null) {
|
||||||
if (!m_activity.isPortrait() && m_activity.isSmallScreen()) {
|
/* if (!m_activity.isPortrait() && m_activity.isSmallScreen()) {
|
||||||
|
|
||||||
View header = view.findViewById(R.id.article_header);
|
View header = view.findViewById(R.id.article_header);
|
||||||
LinearLayout article = (LinearLayout)view.findViewById(R.id.article_fragment);
|
LinearLayout article = (LinearLayout)view.findViewById(R.id.article_fragment);
|
||||||
article.removeView(header);
|
article.removeView(header);
|
||||||
|
|
||||||
web.setEmbeddedTitleBarCompat(header);
|
web.setEmbeddedTitleBarCompat(header);
|
||||||
}
|
} */
|
||||||
|
|
||||||
web.setWebChromeClient(new WebChromeClient() {
|
web.setWebChromeClient(new WebChromeClient() {
|
||||||
@Override
|
@Override
|
||||||
|
91
src/org/fox/ttrss/TitleWebView.java
Normal file
91
src/org/fox/ttrss/TitleWebView.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package org.fox.ttrss;
|
||||||
|
|
||||||
|
// http://www.techques.com/question/1-9718245/Webview-in-Scrollview
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
|
||||||
|
public class TitleWebView extends WebView{
|
||||||
|
|
||||||
|
public TitleWebView(Context context, AttributeSet attrs){
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int titleHeight;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
// determine height of title bar
|
||||||
|
View title = getChildAt(0);
|
||||||
|
titleHeight = title==null ? 0 : title.getMeasuredHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent ev){
|
||||||
|
return true; // don't pass our touch events to children (title bar), we send these in dispatchTouchEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean touchInTitleBar;
|
||||||
|
@Override
|
||||||
|
public boolean dispatchTouchEvent(MotionEvent me){
|
||||||
|
|
||||||
|
boolean wasInTitle = false;
|
||||||
|
switch(me.getActionMasked()){
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
touchInTitleBar = (me.getY() <= visibleTitleHeight());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
wasInTitle = touchInTitleBar;
|
||||||
|
touchInTitleBar = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(touchInTitleBar || wasInTitle) {
|
||||||
|
View title = getChildAt(0);
|
||||||
|
if(title!=null) {
|
||||||
|
// this touch belongs to title bar, dispatch it here
|
||||||
|
me.offsetLocation(0, getScrollY());
|
||||||
|
return title.dispatchTouchEvent(me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this is our touch, offset and process
|
||||||
|
me.offsetLocation(0, -titleHeight);
|
||||||
|
return super.dispatchTouchEvent(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return visible height of title (may return negative values)
|
||||||
|
*/
|
||||||
|
private int visibleTitleHeight(){
|
||||||
|
return titleHeight-getScrollY();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onScrollChanged(int l, int t, int oldl, int oldt){
|
||||||
|
super.onScrollChanged(l, t, oldl, oldt);
|
||||||
|
View title = getChildAt(0);
|
||||||
|
if(title!=null) // undo horizontal scroll, so that title scrolls only vertically
|
||||||
|
title.offsetLeftAndRight(l - title.getLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas c){
|
||||||
|
|
||||||
|
c.save();
|
||||||
|
int tH = visibleTitleHeight();
|
||||||
|
if(tH>0) {
|
||||||
|
// clip so that it doesn't clear background under title bar
|
||||||
|
int sx = getScrollX(), sy = getScrollY();
|
||||||
|
c.clipRect(sx, sy+tH, sx+getWidth(), sy+getHeight());
|
||||||
|
}
|
||||||
|
c.translate(0, titleHeight);
|
||||||
|
super.onDraw(c);
|
||||||
|
c.restore();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user