AndroidGUI23:水平方向和垂直方向同时滚动
2011-06-22 16:57
471 查看
在上一篇文章中,我们讲到了使用
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
方式显示。
运行结果:
结果表明可以同时在水平和垂直方向移动图片。
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
方式显示。
运行结果:
结果表明可以同时在水平和垂直方向移动图片。
相关文章推荐
- android 图片垂直方向( ScrollView) ,水平方向HorizontalScrollView 滚动
- css实现文字水平方向垂直方向同时居中的方式
- Android中TextView如何实现水平和垂直滚动
- Android RecyclerViewSwipeDismiss:水平、垂直方向的拖曳删除item
- 禁止uiscrollview垂直方向滚动,只允许水平方向滚动;或只允许垂直方向滚动
- 【Android 开发】:UI控件之 ScrollView垂直滚动控件 和 HorizontalScrollView水平滚动控件的使用
- Android垂直方向滚动的跑马灯,带gif
- Android HorizontalScrollView和ScrollView 水平滚动 垂直滚动
- android listview 水平滚动和垂直滚动的小例子
- android实现TextView垂直或水平滚动
- Android Layout布局使用总结Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件。 帧布局(FrameLayout):组件从
- 禁止uiscrollview垂直方向滚动,只允许水平方向滚动;或只允许垂直方向滚动
- 【Android】ListView监听上下滑动(设置滚动监听判断ListView的滚动方向同时获取屏幕高度、ListView实际高度,判断是否需要展示返回顶部按钮(具体逻辑请看代码--附有详细注释)。
- 最近做项目中用到的文字或图片水平和垂直方向平滑滚动(含Ajax效果)
- Android RecyclerView实现水平、垂直方向分割线
- Android中GridView水平滚动和垂直滚动的实现(动态)
- 自动滚动的RecyclerView(水平和垂直方向)
- [转]Android HorizontalScrollView和ScrollView 水平滚动 垂直滚动
- Android RecyclerViewSwipeDismiss:水平、垂直方向的拖曳删除item
- Android WebView 滚动方向判断同时底部导航栏隐藏或显示(动画效果)