Welcome 微信登录

首页 / 操作系统 / Linux / Android开发:水平方向和垂直方向同时滚动

在这篇(http://www.linuxidc.com/Linux/2011-09/43135.htm)文章中,我们讲到了使用 ScrollView 和 HorizontalScrollView ,可以在同一时刻让屏幕要么在水平方向滚动,要么在垂直方向滚动。但却不能同时在水平和垂直两个方向滚动。这篇文章的目的就是为了解决同时在两个方向滚动的问题。   1.     创建一个 Android Project ,将 desktop.png( 大小为 1280 x 900) ,拷贝到 res/drawable-mdpi 文件夹下。 2.     修改 Activity 所对应的 Java 代码,使之如下: package com.pat.gui;   import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.GestureDetector.OnGestureListener; import android.widget.Toast;   public class ScrollPicture extends Activity implements OnGestureListener {          private int X = 0;          private int Y = 0;                   private static int scrollX = 0;          private static int scrollY = 0;                   PictureView main;          Bitmap bmp;          Bitmap adapt;          Resources res;          Paint paint;          GestureDetector gestureDetector;          DisplayMetrics dm;              @Override     public void onCreate(Bundle savedInstanceState)     {         super.onCreate(savedInstanceState);         gestureDetector = new GestureDetector(this);         paint = new Paint();         // 获取图像         res = getResources();         bmp = BitmapFactory.decodeResource(res, R.drawable.desktop);         // 获取图像的宽度和高度         X = bmp.getWidth();         Y = bmp.getHeight();                 // adapt 是 bmp 显示在屏幕上的那部分图像,见 PictureView 中的 handleScroll 方法         adapt = Bitmap.createBitmap(bmp);         main = new PictureView(this);                 // 去掉标题栏         requestWindowFeature(Window.FEATURE_NO_TITLE);         // 全屏显示         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                                                             WindowManager.LayoutParams.FLAG_FULLSCREEN);                 //setContentView(R.layout.main);         setContentView(main, new ViewGroup.LayoutParams(X, Y));                 // 以 landscape 方式显示         this.setRequestedOrientation(Configuration.ORIENTATION_LANDSCAPE);                 // 获取屏幕尺寸         dm = new DisplayMetrics();         getWindowManager().getDefaultDisplay().getMetrics(dm);      }       // 屏幕翻转时,要重新获取 dm 。要使 onConfigurationChanged 可以被触发,必须做到:     // 1. 在 AndroidManifest.xml 的 Activity 标签中,增加属性 android:configChanges="orientation"     // 2. 在 AndroidManifest.xml ,须增加权限:     //    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>     // 当屏幕显示有 landscape 变成 portrait ,或者有 portrait 变成 landscape 是,都会触发 onConfigurationChanged          @Override          public void onConfigurationChanged(Configuration newConfig)          {                    if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)                    {                             // 获取屏幕尺寸                             dm = new DisplayMetrics();                     getWindowManager().getDefaultDisplay().getMetrics(dm);                     // 重新计算 adapt 。显示 desktop.png 的左上角开始,占整个屏幕尺寸大小的那部分                     adapt = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);                     // scrollX 和 scrollY 分别为在水平或者垂直方向上,滚动的像素值                     scrollX = 0;                     scrollY = 0;                     // 重画                             main.invalidate();                     Toast.makeText(this, "(" + dm.widthPixels + ", " + dm.heightPixels + ")", Toast.LENGTH_SHORT).show();                    }                                       if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)                    {                             dm = new DisplayMetrics();                     getWindowManager().getDefaultDisplay().getMetrics(dm);                     adapt = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);                     scrollX = 0;                     scrollY = 0;                             main.invalidate();                     Toast.makeText(this, "(" + dm.widthPixels + ", " + dm.heightPixels + ")", Toast.LENGTH_SHORT).show();                    }                    // 下面这句必须存在,否则会出现???常                    super.onConfigurationChanged(newConfig);          }            public boolean onTouchEvent(MotionEvent me)          {                    return gestureDetector.onTouchEvent(me);          }            public boolean onDown(MotionEvent me)          {                    return true;          }            public boolean onFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY)          {                    return true;          }            public void onLongPress(MotionEvent me)          {            }            public boolean onScroll(MotionEvent me1, MotionEvent me2, float distanceX, float distanceY)          {                    // distanceX 和 distanceY ,分别为叫上次位置的滚动量,可以为正,也可能为负                   main.handleScroll(distanceX, distanceY);                    return true;          }            public void onShowPress(MotionEvent me)          {            }            public boolean onSingleTapUp(MotionEvent me)          {                    return true;          }              class PictureView extends View     {                    public PictureView(Context ctx)                    {                             super(ctx);                    }                      // 调用 invalidate 方法时,会触发 onDraw 这个方法                    protected void onDraw(Canvas canvas)                    {                             canvas.drawBitmap(adapt, 0, 0, paint);                    }                                       public void handleScroll(float distanceX, float distanceY)                    {                             // 修正每次滚动后的 scrollX 和 scrollY 的值                             scrollX += distanceX;                             scrollY += distanceY;                               if(scrollX < 0)                             {                                      scrollX = 0;                             }                                                         if(scrollX > (X - dm.widthPixels))                             {                                      scrollX = X - dm.widthPixels;                             }                                                         if(scrollY < 0)                             {                                      scrollY = 0;                             }                                                         if(scrollY > (Y - dm.heightPixels))                             {                                      scrollY = Y - dm.heightPixels;                             }                             // 重新获取 adapt                             adapt = Bitmap.createBitmap(bmp, scrollX, scrollY, dm.widthPixels, dm.heightPixels);                             // 重画                             invalidate();                    }     } }   3.     修改 AndroidManifest.xml ,使之如下: <? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = "http://schemas.android.com/apk/res/android"       package = "com.pat.gui"       android:versionCode = "1"       android:versionName = "1.0" >     < application android:icon = "@drawable/icon" android:label = "@string/app_name" >         < activity android:name = ".ScrollPicture"                   android:label = "@string/app_name"                   android:screenOrientation = "sensor"                   android:configChanges = "orientation" >             < intent-filter >                 < action android:name = "android.intent.action.MAIN" />                 < category android:name = "android.intent.category.LAUNCHER" />             </ intent-filter >         </ activity >       </ application >     < uses-sdk android:minSdkVersion = "7" />     < uses-permission android:name = "android.permission.CHANGE_CONFIGURATION" /> </ manifest > 注意 AndroidManifest.xml 文件中, 3 行粗体字。其中的 android:screenOrientation="sensor" 表示,由手机的重力感应器来决定屏幕是以 landscape 或者 portrait 方式显示。   运行结果:
结果表明可以同时在水平和垂直方向移动图片。