AndroidGUI23:水平方向和垂直方向同时滚动

来源:互联网 发布:五洲传播中心 知乎 编辑:程序博客网 时间:2024/06/08 08:32

在上一篇文章中,我们讲到了使用ScrollViewHorizontalScrollView,可以在同一时刻让屏幕要么在水平方向滚动,要么在垂直方向滚动。但却不能同时在水平和垂直两个方向滚动。这篇文章的目的就是为了解决同时在两个方向滚动的问题。

 

1.    创建一个AndroidProject,将desktop.png(大小为1280x 900),拷贝到res/drawable-mdpi文件夹下。

2.    修改Activity所对应的Java代码,使之如下:

packagecom.pat.gui;

 

importandroid.app.Activity;

importandroid.content.Context;

importandroid.content.res.Configuration;

importandroid.content.res.Resources;

importandroid.graphics.Bitmap;

importandroid.graphics.BitmapFactory;

importandroid.graphics.Canvas;

importandroid.graphics.Paint;

importandroid.os.Bundle;

importandroid.util.DisplayMetrics;

importandroid.view.GestureDetector;

importandroid.view.MotionEvent;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.view.Window;

importandroid.view.WindowManager;

importandroid.view.GestureDetector.OnGestureListener;

importandroid.widget.Toast;

 

publicclass 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(BundlesavedInstanceState)

    {

        super.onCreate(savedInstanceState);

        gestureDetector = newGestureDetector(this);

        paint = new Paint();

        // 获取图像

        res = getResources();

        bmp = BitmapFactory.decodeResource(res,R.drawable.desktop);

        // 获取图像的宽度和高度

        X = bmp.getWidth();

        Y = bmp.getHeight();

       

        // adaptbmp显示在屏幕上的那部分图像,见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.xmlActivity标签中,增加属性android:configChanges="orientation"

    // 2. AndroidManifest.xml,须增加权限:

    //   <uses-permissionandroid:name="android.permission.CHANGE_CONFIGURATION"/>

    // 当屏幕显示有landscape变成portrait,或者有portrait变成landscape是,都会触发onConfigurationChanged

         @Override

         public voidonConfigurationChanged(Configuration newConfig)

         {

                   if(newConfig.orientation ==Configuration.ORIENTATION_LANDSCAPE)

                   {

                            // 获取屏幕尺寸

                            dm = newDisplayMetrics();

                   getWindowManager().getDefaultDisplay().getMetrics(dm);

                   // 重新计算adapt。显示desktop.png的左上角开始,占整个屏幕尺寸大小的那部分

                   adapt = Bitmap.createBitmap(bmp,0, 0, dm.widthPixels, dm.heightPixels);

                   // scrollXscrollY分别为在水平或者垂直方向上,滚动的像素值

                   scrollX = 0;

                   scrollY = 0;

                   // 重画

                            main.invalidate();

                   Toast.makeText(this,"(" + dm.widthPixels + ", " + dm.heightPixels + ")",Toast.LENGTH_SHORT).show();

                   }

                  

                   if(newConfig.orientation ==Configuration.ORIENTATION_PORTRAIT)

                   {

                            dm = newDisplayMetrics();

                   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(MotionEventme)

         {

                   returngestureDetector.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(MotionEventme1, MotionEvent me2, float distanceX, float distanceY)

         {

                   // distanceXdistanceY,分别为叫上次位置的滚动量,可以为正,也可能为负

                  main.handleScroll(distanceX,distanceY);

                   return true;

         }

 

         public void onShowPress(MotionEvent me)

         {

 

         }

 

         public booleanonSingleTapUp(MotionEvent me)

         {

                   return true;

         }

        

    class PictureView extends View

    {

                   public PictureView(Contextctx)

                   {

                            super(ctx);

                   }

 

                   // 调用invalidate方法时,会触发onDraw这个方法

                   protected void onDraw(Canvascanvas)

                   {

                            canvas.drawBitmap(adapt,0, 0, paint);

                   }

                  

                   public voidhandleScroll(float distanceX, float distanceY)

                   {

                            // 修正每次滚动后的scrollXscrollY的值

                            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方式显示。

 

运行结果:


结果表明可以同时在水平和垂直方向移动图片。

 

原创粉丝点击