Domanda

I was wondering if it's possible to create an Android application which behaves the same as any browser on Android phones, including things like:

  • (Pinch) zooming
  • Panning/scrolling

I have tried a couple of things

  • ZoomView takes care of the first point, but doesn't work properly when the layout is bigger than the screen (where the scrolling/panning part comes in: the layout gets cut off if outside the screen, and behaves strange when put inside a ScrollView).
  • For panning/scrolling I tried a TwoDScrollView, but this one and the above don't get along, much like a normal ScrollView.
  • ZoomableRelativeLayout does work, even pinching is implemented, but this works only with images. The clickable area, for example, does not shift when zoomed/panned. So that was also a no-go.

Alternative

  • Using a WebView/PhoneGap, but I'm really no expert in HTML(5) or JavaScript.

Question

  • What is the best approach if I have a layout, which can be bigger than the screen, and make it fully zoomable and pannable, preferrably native?

Posts I've read

Current implementation and drawbacks

View zoomableLayout = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.actuallayout, null, false);
zoomableLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

zoomView = new ZoomView(this);
zoomView.addView(zoomableLayout);
LinearLayout main_container = (LinearLayout) findViewById(R.id.main_container);
main_container.addView(zoomView);   

This works quite nice, as long as the unzoomed layout fits the screen. Once it gets bigger, and I need to implement a ScrollView, the functionality is not as hoped or as expected. For example, if I scroll down, and zoom in, I can't scroll all the way up, only to what was visible when I zoomed in.

È stato utile?

Soluzione

I'd highly suggest HTML5 through PhoneGap. It's not that hard.

EDIT: a few steps are required:

  1. Add cordova as a library (in my case that's cordova-2.5.0.jar)
  2. Create a class that's gonna handle the returning javascript calls (see JSComm.java below)
  3. Create an activity with a webview DroidGap (see below); note that Apache renamed it to CordovaActivity in newer releases)
  4. Create a javascript file (below)
  5. Create an HTML page (below) which includes references to your javascript file AND the cordova javascript file (in my case cordova-2.5.0.js)
  6. Add some xml (see below) in /res/xml/config.xml
  7. Don't forget to add your activity to the manifest.

JSComm.java

public class JSComm extends CordovaPlugin {     
    public boolean execute(final String action, final JSONArray args, CallbackContext callbackContext) {
        final CallbackContextWrapper callbackContextWrapper = new CallbackContextWrapper(callbackContext);
        if (action.equals("MyString")
            return handleIt(args.getJSONObject(0));
        else 
            return false;
    }
}

MyCordovaActivity.java

public class FormViewer extends DroidGap {
    @SuppressLint("SetJavaScriptEnabled")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.init();
        super.appView.getSettings().setJavaScriptEnabled(true);
        super.appView.getSettings().setSupportZoom(true);
        super.appView.getSettings().setBuiltInZoomControls(true);
        super.appView.getSettings().setDisplayZoomControls(false);
        super.appView.getSettings().setUseWideViewPort(true);
        super.appView.getSettings().setLoadWithOverviewMode(true);
        super.loadUrl("file:///" + myHTMLFilePath);
    }

    public void nextPage() {
        this.sendJavascript("nextPage()"); //example
    }
}

JSComm.js

function nextPage() {
  var inputted = trytogetinputs(); //some method: get all html input elements
  cordova.exec(
      null, //what to execute when success? Nothing in this case.
      function(args) {
          addErrorBorders(args); //What to do if fail? add some error borders in this case.
      },
      "JSComm", //name of CordovaPlugin class
      "MyString", //to identify what method was run
      [inputted] //some data you can send along.
  );
}

Your HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css" href="common.css">
    <script type="text/javascript" src="../../jquery.min.js"></script>
    <script type="text/javascript" charset="utf-8" src="../../cordova-2.5.0.js"></script><!--Cordova js file-->
    <script type="text/javascript" charset="utf-8" src="../../javacomm.js"></script><!--Your js file-->
    <script type="text/javascript" src="../../jquery-ui.min.js"></script>
    <script type="text/javascript" src="../../jquery.signature.min.js"></script>
  </head>
  <body background="0.png">...etc...</body></html>

xml

<?xml version="1.0" encoding="utf-8"?>
<!--
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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.
-->
<cordova>
    <!--
    access elements control the Android whitelist.
    Domains are assumed blocked unless set otherwise
     -->

    <access origin="http://127.0.0.1*"/> <!-- allow local pages -->

    <!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
    <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
    <access origin=".*"/>

    <!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
    <content src="index.html" />

    <log level="DEBUG"/>
    <preference name="useBrowserHistory" value="true" />
    <preference name="exit-on-suspend" value="false" />
    <preference name="fullscreen" value="false" />
<plugins>
    <plugin name="App" value="org.apache.cordova.App"/>
    <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
    <plugin name="Device" value="org.apache.cordova.Device"/>
    <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
    <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
    <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
    <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
    <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
    <plugin name="File" value="org.apache.cordova.FileUtils"/>
    <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
    <plugin name="Notification" value="org.apache.cordova.Notification"/>
    <plugin name="Storage" value="org.apache.cordova.Storage"/>
    <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
    <plugin name="Capture" value="org.apache.cordova.Capture"/>
    <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
    <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
    <plugin name="Echo" value="org.apache.cordova.Echo" />
    <plugin name="Globalization" value="org.apache.cordova.Globalization"/>
    <plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser"/>
    <plugin name="JSComm" value="com.example.application.JSComm"/>
</plugins>
</cordova>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top