I have an ImageView that is twice the height of a normale screen ( 960 dip). I would like to scroll it nicely up and down on the screen. The bottom of the screen should contain a bottom. I have tried various combinations of ScrollView and Imageviews without any success. I have also thinkered with the :isScrollContainer attribute without results. Anyone knows how to do this? Cheers, Luca
The easiest way is imho to use a webview and load the image into it via a local html file. This way you will also automatically get the zoom controls if you want to use them. For a large image (i.e. if it's 1000 or 3000 px wide) you will notice that Android (Coliris) isn't very good at displaying large zoomed images very sharp, even if the original images is sharp and uncompressed). This is a known issue. The solution for that is to break down the large image into smaller tiles and put them together again via html (div's or table). I use this approach to provide a subway map (larger than the screen and scrollable) to the user.
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");
This might work for most cases / 'regular apps', although depends on your particular case. If you are talking about a image as a scrollable background of a game, it might not be useful for you.
Instead of a html file, you could also load the image directly (png, jpg). If you don't want the zoom control, just turn them off.
Guys,
I searched so long for this Code, so I wanted to share this great peace of code:
this code is from an Activity, which has a xml file on the backend containing an ImageView called 'img'
<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;
}
});
}
did the job perfectly for me... horizontal & vertical scrolling included (enabled)
only negative side is... you can scroll over the edge of the picture... but this is no problem for me.. and spending some time you could easily implement this feature :)
good luck && have fun
@cV2 Thank you so much for that code. It got me going in the direction I needed. Here's my modified version which stops scrolling at the edges of the image...
// 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;
}
});
I'm sure it could be refined a bit, but it works pretty well. :)