Android App 中把WebView分割固定的 最佳解决方案
1. 问题领域
一个线上的android产品,app的架子是由java做成,中间的内容显示是webview。不多说。
产品经理突然脑子进水,想要把webview切割成上中下三块,
a. 下块可以上下滑动,当向上滑动时,上中两块跟着上移。
b. 当上块,上移到完全看不到的时候,中块固定住不动,不再上移。
c. 中块固定不住以后,下块依然可以上移。
d. 当下块重新移下去的时候,重新加载上块显示
就技术解决方案而言
a. 最笨的方法,把一个webview分割成几个webview。这个方法最笨。但是我看到赶集网就是用这个办法做的。当然这样有好处,可以保证与android版本无关。
b. 用js+css解决。这个办法最好,但是很少有人实现过
2. js+css的解决之道
利用CSS中的position:fixed可以解决这个问题。
有三条路:
a. 用jQuery Mobile框架
b. 用iScroll框架
c. 自己写js
当然自己写js最好。
下面是我实验的结果。
首先写一个demo的html
中间引用如下的css
- <style type="text/css">
- .fixed {
- position: fixed;
- top: 0;
- width: 100%;
- z-index: 100;
- }
- </style>
<style type="text/css"> .fixed { position: fixed; top: 0; width: 100%; z-index: 100; } </style>
引用如下的js
- <script>
- jQuery(function($){
- if ($('.h1').size() > 0) {
- var nav = $('.h1');
- var navTop = nav.offset().top;
- $(window).scroll(function () {
- var winTop = $(this).scrollTop();
- if (winTop > navTop) {
- nav.addClass('fixed');
- } elseif (winTop <= navTop) {
- nav.removeClass('fixed');
- }
- });
- }
- });
- </script>
<script> jQuery(function($){ if ($('.h1').size() > 0) { var nav = $('.h1'); var navTop = nav.offset().top; $(window).scroll(function () { var winTop = $(this).scrollTop(); if (winTop > navTop) { nav.addClass('fixed'); } else if (winTop <= navTop) { nav.removeClass('fixed'); } }); } }); </script>
html中要被固定的部分如下
- <divclass="content">
- <h1class="h1">fixed</h1>
- </div>
<div class="content"> <h1 class="h1">fixed</h1> </div>
然后创建一个android工程
在AndroidManifest.xml中添加
- <uses-permissionandroid:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
在layout下的main.xml中如下添加webview
- <LinearLayout
- android:id="@+id/linear_layout_webview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
- <WebView
- android:id="@+id/test_site"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- </WebView>
- </LinearLayout>
<LinearLayout android:id="@+id/linear_layout_webview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <WebView android:id="@+id/test_site" android:layout_width="fill_parent" android:layout_height="fill_parent" > </WebView> </LinearLayout>
主Activity的代码如下:
- package com.hyronjs.jiangbiao;
- import android.app.Activity;
- import android.os.Bundle;
- import android.webkit.WebChromeClient;
- import android.webkit.WebView;
- import android.webkit.WebViewClient;
- publicclass WebViewFixedActivity extends Activity {
- private WebView webView = null;
- /** Called when the activity is first created. */
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- webView=(WebView)findViewById(R.id.test_site);
- webView.setWebChromeClient(new WebChromeClient());
- webView.setWebViewClient(new WebViewClient());
- webView.getSettings().setJavaScriptEnabled(true);
- webView.getSettings().setPluginsEnabled(true);
- webView.loadUrl("file:///android_asset/test.html");
- }
- }
package com.hyronjs.jiangbiao; import android.app.Activity; import android.os.Bundle; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; public class WebViewFixedActivity extends Activity { private WebView webView = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); webView=(WebView)findViewById(R.id.test_site); webView.setWebChromeClient(new WebChromeClient()); webView.setWebViewClient(new WebViewClient()); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setPluginsEnabled(true); webView.loadUrl("file:///android_asset/test.html"); } }
在Android 3.1以上启动之后,就能看到webview中有一部分被固定住的效果了。
3. 对应多版本Android的解决之道
但是,同样的上面的代码,如果你用android 2.3系列去跑,就会发现webview中间固定的效果没有了。
原因在于Android 3.0以下版本,不支持position:fixed的CSS
position:fixed的支持情况参见以下
为了解决,你必须要在html开头加上下面这段meta
- <metaname="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
user-scalable=no 把app自动缩防关掉,就成了。
(理由是什么??)