【问题标题】:Strange behaviour when using WebView and RelativeLayout in fullscreen全屏使用 WebView 和 RelativeLayout 时的奇怪行为
【发布时间】:2012-08-19 17:36:07
【问题描述】:

编辑: 这是显示问题的视频:www.youtube.com/watch?v=5ZZsuMH5T9k 我真的被困在这里了:/

--

我有一个活动,它由一个 webview 和一个底部的按钮组成。我在onCreate 中使用此代码将活动的窗口设置为全屏:

@Override
public void onCreate(Bundle savedInstanceState) {
  InstaFetchApplication.applyCurrentTheme(this);

  super.onCreate(savedInstanceState);

  getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  requestWindowFeature(Window.FEATURE_PROGRESS);

  if (UserPreferences.getIsFullScreenReadingEnabled(this)) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    // this just do this: window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    ActivityUtils.toggleFullScreen(this, true);
  }

  setContentView(R.layout.view_article);

  // ...
}

问题在于大部分时间 web 视图似乎将按钮“推”出屏幕。截图如下:

(larger version)

我希望看到的(有时我会看到)在这里:

(larger version)

这是我正在使用的布局(请注意,在我的应用中,顶部布局必须是 RelativeLayout):

<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/layout_test"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>
  <Button
    android:id="@+id/button"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:text="Click me!"
  />
  <WebView
    android:id="@+id/web_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_above="@id/button"
  />
</RelativeLayout>

我还注意到,如果您使用系统设置关闭设备上的所有动画,问题就消失了(尽管当整个视图有一个上边距然后它跳回到正确的位置时会出现这个故障)。

有没有人遇到过类似的问题并知道如何解决?

【问题讨论】:

  • 你能发一下onCreate()
  • 你是在设备还是模拟器上测试?
  • 你能发布你的代码吗?您需要标题栏中的进度对话框吗? Window.FEATURE_PROGRESS 应该与 setProgressBarVisibility(true) 一起使用,或者如果您不想要进度条,则根本不使用。如果你想隐藏标题栏,那么你可以使用android:windowNoTitle
  • @AdilSoomro 我已经更新了问题。
  • @LalitPoptani 模拟器和设备都出现问题。

标签: android layout webview fullscreen


【解决方案1】:

我终于找到了答案。在窗口中添加WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 标志解决了我的问题。

看到这个帖子:flag_fullscreen + windowNoTitle == button focus bug

【讨论】:

    【解决方案2】:

    我刚刚在Hello WebView 教程中添加了一个按钮,一切似乎都正常。然后我将main.xmlLinearLayout 转换为RelativeLayout,一切看起来仍然正常。我认为你把事情弄得太复杂了。 :-) 尝试从onCreate() 中删除大部分初始化代码,然后在 XML 中指定它。

    这是我的项目。

    AndroidManifest.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.android.hellowebview"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" />
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <activity
                android:name=".HelloWebViewActivity"
                android:label="@string/app_name" 
                android:theme="@android:style/Theme.NoTitleBar"
                >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    HelloWebViewActivity.java:

    package com.example.android.hellowebview;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    
    public class HelloWebViewActivity extends Activity {
    
        WebView mWebView;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_rl);
    
            mWebView = (WebView) findViewById(R.id.webview);
            mWebView.setWebViewClient(new HelloWebViewClient());
            mWebView.getSettings().setJavaScriptEnabled(true);
            mWebView.loadUrl("http://www.google.com");
        }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
                mWebView.goBack();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
    
        private class HelloWebViewClient extends WebViewClient {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        }
    }
    

    main_ll.xml(线性布局):

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <WebView
            android:id="@+id/webview"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
        />
        <Button
            android:id="@+id/mainbtn"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:text="@string/btn_label"
        />
    </LinearLayout>
    

    main_rl.xml(相对布局):

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <WebView
            android:id="@+id/webview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_above="@+id/mainbtn"
        />
        <Button
            android:id="@+id/mainbtn"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="@string/btn_label"
        />
    </RelativeLayout>
    

    strings.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="hello">Hello World, HelloWebViewActivity!</string>
        <string name="app_name">HelloWebView</string>
        <string name="btn_label">Push Me</string>
    
    </resources>
    

    【讨论】:

    • 对于相对布局 android:layout_above="@+id/mainbtn" 将不起作用,因为您在该代码下方定义了按钮
    • 我不能说它是否应该起作用,但它确实起作用。我在运行 Android 1.6、2.3 和 4.0 的设备上对其进行了测试。
    【解决方案3】:

    尝试将 web 视图与父顶部对齐,并将按钮与父底部对齐并且在 web 视图下方。我发现有时候,如果元素没有以线性顺序排列在一起,无论是锚定在屏幕顶部还是底部,它们都没有完全正确排列。

    我假设您没有覆盖 onMeasure() 方法并更改按钮的测量高度。我在开发我的应用程序期间通过在布局阶段错误计算元素的高度而创建了许多(太多)错误,并且花了几个小时努力调试布局定义代码才发现它很好,但是高度计算是将无效数据输入布局的渲染阶段。

    【讨论】:

    • 看来这不是布局错位的问题。就好像框架认为通知栏的动画消失导致整个窗口变小了一样。
    【解决方案4】:

    除非RelativeLayout 是绝对必要的,否则您可以更改为LinearLayout

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <WebView 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="I'm a button"/>
    </LinearLayout>
    

    它应该会给出更好的结果。

    【讨论】:

    • 谢谢,但它确实必须是 RelativeLayout。
    • 与其指定机制,不如指定你需要达到的结果。你能解释一下是什么设计约束使非RelativeLayout解决方案不可行吗?
    • 如果您将 WebView 设置为 alignParentTop 而不是 layout_above 是否有效?视图将能够延伸到按钮后面而不是向下推...
    【解决方案5】:

    隐藏我使用的标题栏:

    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    

    在 Galaxy S 2 (Android 2.3.3) 和 Huawei U8180 X1 (Android 2.2.2) 上进行测试,并且与您的相关布局配合良好。

    从屏幕截图中,我认为问题在于您请求的进度指示器不完整。关闭动画后问题消失的事实也支持这一理论。

    【讨论】:

    • 谢谢,实际上我使用带有 FLAG_FULLSCREEN 的 setFlags 只是错误地将其包含在问题中。我尝试删除 FEATURE_PROGRESS 但没有帮助。
    • 您在什么版本的 Android 和什么设备上进行测试?你见过 LinearLayout 的奇怪行为吗?我仍然认为糟糕截图顶部的黑色方块与布局无关,而是半渲染的标题或通知栏。
    【解决方案6】:

    你可以试试这个。顶部布局仍然是RelativeLayout,与您的唯一区别是LinearLayout 正在包装所有内容:

        <RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/layout_test"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
    
    >
    <LinearLayout android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"
      android:weightSum="1">
      <WebView
    
          android:id="@+id/web_view"
          android:layout_width="fill_parent"
          android:layout_height="0px"
          android:layout_weight=".90" />
    
    
    </LinearLayout>
    </RelativeLayout>
    

    LinearLayout 中,WebView 占据整个窗口(和父窗口)的90% 和剩余的按钮10%。两者的高度都设置为0px,因此重量可以为他们俩做功。解析这个 xml 的成本是微不足道的。

    在 Java 代码中我做了:

       @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
    
           getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
           getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
           requestWindowFeature(Window.FEATURE_NO_TITLE);
            requestWindowFeature(Window.FEATURE_PROGRESS);
            setContentView(R.layout.main);
            LinearLayout mLinearLayout = (LinearLayout)findViewById(R.id.ll);
            Button mButton = new Button(this);
            LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, 0.10f);
            mButton.setText("Click me!");
            mButton.setLayoutParams(mParams);
            mLinearLayout.addView(mButton);
            mLinearLayout.invalidate();
    
        }
    

    【讨论】:

      【解决方案7】:

      下面的代码可能会对你有所帮助,

          webView = (WebView) findViewById(R.id.webview1);
          webView.setInitialScale(100);
      
          webView.setWebViewClient(new WebViewClient() {
              @Override
              public void onPageFinished(WebView view, String url) {
                  // TODO Auto-generated method stub
                  super.onPageFinished(view, url);
                  view.scrollTo(0, 0);
      
              }
      
              @Override
              public boolean shouldOverrideUrlLoading(WebView view, String url) {
      
                  view.loadDataWithBaseURL(null, yourdata, "text/html", "utf-8", null);
                  // view.loadUrl(url);
                  return true;
              }
          });
      
      
      webView.setWebChromeClient(new WebChromeClient() {
          @Override
          public void onProgressChanged(WebView view, int newProgress) {
              try {
                  //your stuff
              } catch (Throwable e) {
                  e.printStackTrace();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-28
        • 2016-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        相关资源
        最近更新 更多