【问题标题】:scroll an image bigger than the screen and stop at its border on Android滚动比屏幕大的图像并在 Android 上停在其边界处
【发布时间】:2010-08-10 09:35:14
【问题描述】:

我知道如何显示比屏幕更大的图像。这相当简单,并详细解释了here,但是,如果您离开图像并且只有黑屏,则此方法使您可以随意滚动。我想知道当我们到达图片的一侧时如何让滚动停止......

【问题讨论】:

  • 没有人对此有任何建议吗?我应该直接在 Canvas、SurfaceView 上工作吗?

标签: android image scroll


【解决方案1】:

将您的图像加载到 WebView 中。然后,您将获得您正在寻找的所有滚动行为,甚至是默认的缩放控件(如果您选择打开它们)……几乎是免费的。您唯一的其他选择(据我所知)是使用 2D 图形 API(Canvas 等)并创建您自己的绘图图块版本(例如查看地图的一部分)。

如果你的图片是本地的,看看from the SD Card这个读取本地图片数据的例子。在这种情况下,提供本地图像的更简洁的方法是创建一个 ContentProvider 并通过 WebView 中的 content:// URL 访问资源。

使用项目的assets 目录中的捆绑图像car.jpg 的示例:

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <WebView
      android:id="@+id/web"
      android:layout_width="150dip"
      android:layout_height="150dip"
    />
</LinearLayout>

src/ImageViewer.java

public class ImageViewer extends Activity {

  WebView webView;
  /** 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.web);
    webView.loadUrl("file:///android_asset/car.jpg");
  }
}

对于与您的项目捆绑在一起的图像,这是最简单的方法。这不适用于资源目录中的图像(如 res/drawable)。该路径不值得完成它所需的代码。

【讨论】:

  • 感谢您的回答,明天我会花时间查看所有这些内容,然后回来提供一些反馈。谢谢大家
  • 好的,现在第一个问题,我无法在 Webview 中设置此图像,因为我将它作为 webview 的背景并且图像被调整大小,或者我尝试从资源,我无法解决。 (我认为这是路径问题......我知道我可以从资产中做到这一点,但我希望它来自 res/drawable),并且由于我没有屏幕大小,所以我没有知道在 img src 中放置宽度和高度的内容
  • 从文件系统或资产加载捆绑的图像是使用 WebView 时最简单的方法(我使用示例进行了编辑)。这是因为 Android 已经在 AssetManager 中构建了内容服务……而其他资源不存在。您必须在自定义 ContentProvider 的 openFile() 方法中复制行为 AssetManager.openFd()。这是更多的代码。
  • 有没有办法防止图像被调整大小以完全适应屏幕并使其保持原来的大小?
  • 如果您在 WebView 中加载内容,它不应该调整数据大小,这就是建议的重点。除非您将其设置为视图的背景或其他属性。我使用资产的推荐示例重新调整了我的答案。
【解决方案2】:

在您的 Activity.onCreate() 中:

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

我不确定你到底指的是哪种布局,所以我发布了 2 个版本:

版本 1(图片下方的按钮):

<?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">

    <ScrollView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:layout_weight="1"
        android:fadingEdge="none" android:scrollbars="none">

        <ImageView android:id="@+id/image" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:scaleType="center" />

    </ScrollView>

    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:text="OK"
        android:layout_gravity="center" />

</LinearLayout>

版本 2(图像上方的按钮 - 在 z 轴上):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">

    <ScrollView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:fadingEdge="none"
        android:scrollbars="none">

        <ImageView android:id="@+id/image" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:scaleType="center" />

    </ScrollView>

    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:text="OK"
        android:layout_gravity="bottom|center_horizontal" />

</FrameLayout>

您也可以尝试将 ScrollView 放在 Horizo​​ntalScrollView 中。

【讨论】:

    【解决方案3】:

    好吧,我遇到了同样的问题,这是我的解决方案:

      Display display = getWindowManager().getDefaultDisplay();
        screenSize = new Point();
        display.getSize(screenSize);
    

    获取需要设置底部和右侧边界的屏幕尺寸

    image.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                float curX, curY;
    
                switch (event.getAction()) {
    
                    case MotionEvent.ACTION_DOWN:
                        mx = event.getX();
                        my = event.getY();
                        rect = image.getDrawable().getBounds();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        curX = event.getX();
                        curY = event.getY();
                        image.scrollBy(getX((int) (mx - curX)), getY((int) (my - curY)));
                        mx = curX;
                        my = curY;
                        break;
                }
                return true;
            }
        });
    

    最后还有两种设置新滚动坐标的方法

    private int getX(int x){
        if (image.getScrollX() + x < 0 ){ //left side 
            return 0;
        } else if (image.getScrollX() + x >= (rect.right - screenSize.x)){ //right side
            return 0;
        } else {
            return x;
        }
    }
    
    private int getY(int y){
        if (image.getScrollY() + y < 0 ){  //top side 
            return 0;
        } else if (image.getScrollY() + y >= (rect.bottom - screenSize.y)){ //bottom side
            return 0;
        } else {
            return y;
        }
    } 
    

    适用于 API 16+,希望对您有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多