【问题标题】:Android: Scrolling an ImageviewAndroid:滚动图像视图
【发布时间】:2011-03-04 17:50:44
【问题描述】:

我的 ImageView 是正常屏幕高度的两倍(960 dip)。我想在屏幕上很好地上下滚动它。屏幕底部应包含一个按钮。我尝试了 ScrollView 和 Imageviews 的各种组合,但没有任何成功。我也考虑过没有结果的 :isScrollContainer 属性。任何人都知道如何做到这一点? 干杯, 卢卡

【问题讨论】:

  • 它是:底部应该包含一个 BUTTON...抱歉打错了。

标签: android scroll imageview


【解决方案1】:

@cV2 非常感谢您提供的代码。它让我朝着我需要的方向前进。这是我的修改版本,它在图像边缘停止滚动...

    // set maximum scroll amount (based on center of image)
    int maxX = (int)((bitmapWidth / 2) - (screenWidth / 2));
    int maxY = (int)((bitmapHeight / 2) - (screenHeight / 2));

    // set scroll limits
    final int maxLeft = (maxX * -1);
    final int maxRight = maxX;
    final int maxTop = (maxY * -1);
    final int maxBottom = maxY;

    // set touchlistener
    ImageView_BitmapView.setOnTouchListener(new View.OnTouchListener()
    {
        float downX, downY;
        int totalX, totalY;
        int scrollByX, scrollByY;
        public boolean onTouch(View view, MotionEvent event)
        {
            float currentX, currentY;
            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    downX = event.getX();
                    downY = event.getY();
                    break;

                case MotionEvent.ACTION_MOVE:
                    currentX = event.getX();
                    currentY = event.getY();
                    scrollByX = (int)(downX - currentX);
                    scrollByY = (int)(downY - currentY);

                    // scrolling to left side of image (pic moving to the right)
                    if (currentX > downX)
                    {
                        if (totalX == maxLeft)
                        {
                            scrollByX = 0;
                        }
                        if (totalX > maxLeft)
                        {
                            totalX = totalX + scrollByX;
                        }
                        if (totalX < maxLeft)
                        {
                            scrollByX = maxLeft - (totalX - scrollByX);
                            totalX = maxLeft;
                        }
                    }

                    // scrolling to right side of image (pic moving to the left)
                    if (currentX < downX)
                    {
                        if (totalX == maxRight)
                        {
                            scrollByX = 0;
                        }
                        if (totalX < maxRight)
                        {
                            totalX = totalX + scrollByX;
                        }
                        if (totalX > maxRight)
                        {
                            scrollByX = maxRight - (totalX - scrollByX);
                            totalX = maxRight;
                        }
                    }

                    // scrolling to top of image (pic moving to the bottom)
                    if (currentY > downY)
                    {
                        if (totalY == maxTop)
                        {
                            scrollByY = 0;
                        }
                        if (totalY > maxTop)
                        {
                            totalY = totalY + scrollByY;
                        }
                        if (totalY < maxTop)
                        {
                            scrollByY = maxTop - (totalY - scrollByY);
                            totalY = maxTop;
                        }
                    }

                    // scrolling to bottom of image (pic moving to the top)
                    if (currentY < downY)
                    {
                        if (totalY == maxBottom)
                        {
                            scrollByY = 0;
                        }
                        if (totalY < maxBottom)
                        {
                            totalY = totalY + scrollByY;
                        }
                        if (totalY > maxBottom)
                        {
                            scrollByY = maxBottom - (totalY - scrollByY);
                            totalY = maxBottom;
                        }
                    }

                    ImageView_BitmapView.scrollBy(scrollByX, scrollByY);
                    downX = currentX;
                    downY = currentY;
                    break;

            }

            return true;
        }
    });

我相信它可以稍微改进一下,但效果很好。 :)

【讨论】:

  • @wirbly :我正在使用此代码,它对我来说非常有效,但只是想在左右移动时滚动屏幕宽度的一半。我们如何实现它?我必须改变的地方
  • 使用此代码,图像从角落到角落,idk
【解决方案2】:

我找了这么久的代码,所以我想分享这个代码的和平:

这段代码来自一个Activity,它在后端有一个xml文件包含一个名为'img'的ImageView

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/img"
    android:scaleType="center"
    android:background="#fff"
    android:src="@drawable/picName"
/>

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.xml_name_layout);

    final ImageView switcherView = (ImageView) this.findViewById(R.id.img);

    switcherView.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View arg0, MotionEvent event) {

            float curX, curY;

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    mx = event.getX();
                    my = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    curX = event.getX();
                    curY = event.getY();
                    switcherView.scrollBy((int) (mx - curX), (int) (my - curY));
                    mx = curX;
                    my = curY;
                    break;
                case MotionEvent.ACTION_UP:
                    curX = event.getX();
                    curY = event.getY();
                    switcherView.scrollBy((int) (mx - curX), (int) (my - curY));
                    break;
            }

            return true;
        }
    });

}

为我完美地完成了这项工作...... 包括水平和垂直滚动(已启用)

唯一的缺点是...您可以滚动图片的边缘... 但这对我来说没问题.. 花一些时间您可以轻松实现此功能:)

祝你好运&&玩得开心

【讨论】:

  • 布局是线性的还是相对的?
  • 对不起,不知道,但对于 imageview 本身,它不应该有任何区别 :) 祝你好运!
  • 很好的例子@cV2,我用它在imagView中滚动我的pdf。但是我有轻微的机会.. 在 onTouch 之前将 mx、my、curX 和 curY 声明为 mx,my 没有声明..:)
  • 什么是 mx 和我的?
【解决方案3】:

这就是我修复它的方法:p

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbarAlwaysDrawVerticalTrack="true">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="Specs"
        android:scrollbars="vertical"
        android:src="@drawable/image"/>
</ScrollView>

【讨论】:

  • 简单的解决方案..首选。
  • 双方?
【解决方案4】:

@wirbly 非常感谢您的代码,它完全按照我想要的方式工作。 但是当我第一次阅读您的代码时,我对您忘记定义的四个变量感到有些困惑。

所以,我想添加代码的定义以使其更清晰。

Resources res=getResources();
Bitmap mBitmap = BitmapFactory.decodeResource(res, R.drawable.p_1920x1080); 
BitmapDrawable bDrawable = new BitmapDrawable(res, mBitmap);

//get the size of the image and  the screen
int bitmapWidth = bDrawable.getIntrinsicWidth();
int bitmapHeight = bDrawable.getIntrinsicHeight();
int screenWidth = this.getWindowManager().getDefaultDisplay().getWidth();  
int screenHeight = this.getWindowManager().getDefaultDisplay().getHeight();

希望对你有帮助。

【讨论】:

    【解决方案5】:

    最简单的方法是使用 webview 并通过本地 html 文件将图像加载到其中。这样,如果您想使用缩放控件,您也将自动获得它们。 对于大图像(即如果它是 1000 或 3000 px 宽),您会注意到 Android (Coliris) 不太擅长非常清晰地显示大型缩放图像,即使原始图像是清晰且未压缩的)。这是一个已知的问题。解决方案是将大图像分解为较小的图块,然后通过 html(div 或表格)再次将它们组合在一起。 我使用这种方法向用户提供地铁地图(大于屏幕且可滚动)。

        WebView webView = (WebView)findViewById(R.id.webView);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setUseWideViewPort(true);
        webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
    
        webView.loadUrl( "content://com.myapp.android.localfile/sdcard/myappdata/common/mtr_map.html");
    

    这可能适用于大多数情况/“常规应用”,但取决于您的具体情况。如果您将图像作为游戏的可滚动背景进行讨论,它可能对您没有用处。

    除了 html 文件,您还可以直接加载图像(png、jpg)。如果您不想要缩放控件,只需将其关闭即可。

    【讨论】:

    • 我经常这样做,但我来这个问题是为了其他技术。不过我为你 +1 了!
    • 很抱歉我投了反对票,但我会尽一切努力避免使用 WebView,因为它是一个非常重的视图。
    • @MathiasLin WebView 显示图像可能非常方便,但我们体验到通过绑定到本机 WebKit 小部件的内存开销太高了 .此外,此视图似乎泄漏内存:code.google.com/p/android/issues/detail?id=9375
    • @martyonair 是的,你是对的。你链接的错误报告实际上是我当时报告的:)我知道这一点,所以基本上,它只是关于方便的缩放功能,假设只有一个 WebView - 内存消耗对你来说可能没那么重要某些情况。我想这也可以通过其他方式实现。
    • @MathiasLin 我记得我使用矩阵缩放来实现缩放 ImageViews,这篇文章中的解决方案:stackoverflow.com/questions/10630373/… 为我工作你报告了这个错误? dafuq - 世界上的小^^
    【解决方案6】:

    另一种方法是创建HorizontalScrollView,将imageView 添加到其中,然后将HorizontalScrollView 添加到ScrollView。这允许您向上、向下、向左、向右滚动。

    【讨论】:

    • 我刚刚尝试过,因为它看起来不错且简单,但遗憾的是用户体验令人失望。一次只能水平或垂直滚动​​,不能在对角线上发生。更糟糕的是:假设垂直滚动是外部容器,那么如果您进行不是近乎完美水平的对角滑动,则滚动将垂直发生,即使您的滑动的垂直分量远小于其水平分量。跨度>
    【解决方案7】:

    对我有用

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/img"
                android:scaleType="centerCrop"
                android:adjustViewBounds="true"/>
    
            <Button
                style="@style/btn"
                android:id="@+id/btn"
                android:layout_height="60dp"
                android:layout_marginTop="20dp"
                android:background="@drawable/btn"
                android:onClick="click"
                android:text="text" />
        </LinearLayout>
    
    </ScrollView>
    

    【讨论】:

      【解决方案8】:

      嘿,伙计们找到了一个简单且 100% 可靠的解决方案,正如上面提到的 X 先生(因为提到的其他代码在某些设备上不起作用或损坏) 只需使用 android 提供的 ScrollView 就可以了

      类似的东西

      <ScrollView android:layout_width="fill_parent" android:id="@+id/scrollView1"
              android:layout_height="wrap_content" android:layout_alignParentTop="true"
              android:layout_alignParentLeft="true" android:layout_above="@+id/button1"
              android:layout_alignParentRight="true" android:scrollbarAlwaysDrawVerticalTrack="true">
              <LinearLayout android:id="@+id/linearLayout1"
                  android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal">
                  <ImageView android:src="@android:drawable/ic_menu_report_image"
                      android:layout_height="wrap_content" android:id="@+id/imageView1"
                      android:layout_width="wrap_content"></ImageView>
              </LinearLayout>
          </ScrollView>
      

      并在 oncreate 类似的东西

      if (mImageName != null) {
              InputStream is = null;
              try {
                  is = this.getResources().getAssets().open("mathematics/"+mImageName);
              } catch (IOException e) {
              }
              Bitmap image = BitmapFactory.decodeStream(is);
      
              mImageView.setImageBitmap(image);
      }
      

      干杯!

      【讨论】:

      • ScrollView 只能垂直滚动。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多