編輯:關於Android編程
兩個人共嘗一個痛苦只有半個痛苦,兩個人共享一個歡樂卻有兩個歡樂。
本講內容:Gallery仿圖像集浏覽
一、基本原理
在 Activity 中實現 OnGestureListener 的接口 onFling() 手勢事件,通過自定義的 View 繪制draw() 圖片
二、手勢坐標介紹
下面示例中,用到了OnGestureListener接口的onScroll()和OnFling()方法,涉及到了Android系統坐標及觸摸MotionEvent
e1和e2、速度velocityX、velocityY等值

<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CqOoMaOpTW90aW9uRXZlbnTW0CBlMcrHytbWuLXa0ru0zrC0yc/GwcS7tcTG8LXjo6xlMsrHzKfG8MrW1rjA67+qxsHEu7XE1tW146OsuPm+3cnPzbxBbmRyb2lkxsHEu9f4serPtb/J1qqjujwvcD4KPHA+CsrW1rjP8tPSu6y2r6Os1tW146OoZTKjqdTaxvC146OoZTGjqbXE09Ky4KOs09BlMi5nZXRYKCkgLSBlMS5nZXRYKCkgtPPT2jA8YnI+CsrW1rjP8tfzu6y2r6Os1tW146OoZTKjqdTaxvC146OoZTGjqbXE1/Oy4KOs09BlMi5nZXRYKCkgLSBlMS5nZXRYKCkg0KHT2jA8YnI+CsrW1rjP8s/Cu6y2r6Os1tW146OoZTKjqdTaxvC146OoZTGjqbXEz8Ky4KOs09BlMi5nZXRZKCkgLSBlMS5nZXRZKCkgtPPT2jA8YnI+CsrW1rjP8snPu6y2r6Os1tW146OoZTKjqdTaxvC146OoZTGjqbXEyc+y4KOs09BlMi5nZXRZKCkgLSBlMS5nZXRZKCkg0KHT2jA8L3A+CjxwPgo8YnI+CjwvcD4KPHA+CqOoMqOpb25TY3JvbGwoTW90aW9uRXZlbnQgZTEsIE1vdGlvbkV2ZW50IGUyLCBmbG9hdCBkaXN0YW5jZVgsIGZsb2F0IGRpc3RhbmNlWSk8L3A+CjxwPgpkaXN0YW5jZVijrMrHx7C688G9tM5jYWxstcRYvuDA66OssrvKx2Uy0+tlMbXEy67Gvb7gwOs8L3A+CjxwPgpkaXN0YW5jZVijrMrHx7C688G9tM5jYWxstcRZvuDA66OssrvKx2Uy0+tlMbXEtLnWsb7gwOs8YnI+CjwvcD4KPHA+Cr7fzOXK/SYjMjA1NDA7tcS3vc/yo6zH68/qvPvJz828o6jW0KOpPC9wPgo8cD4KPGJyPgo8L3A+CjxwPgqjqDOjqW9uRmxpbmcoTW90aW9uRXZlbnQgZTEsIE1vdGlvbkV2ZW50IGUyLCBmbG9hdCB2ZWxvY2l0eVgsIGZsb2F0IHZlbG9jaXR5WSkgPC9wPgo8cD4KdmVsb2NpdHlYo6zKx1jW4bXEw7/D68vZtsg8L3A+CjxwPgp2ZWxvY2l0eVmjrMrHWdbhtcTDv8Pry9m2yDwvcD4KPHA+Cr7fzOXK/SYjMjA1NDA7tcS3vc/yo6zH68/qvPvJz828o6jT0qOpPC9wPgo8cD4K19DPuLnbsuy/ydLUt6LP1qO6dmVsb2NpdHlYoaJ2ZWxvY2l0eVm1xLe9z/LT62Rpc3RhbmNlWKGiZGlzdGFuY2VZt73P8tX9usPP4Le0PC9wPgo8YnI+CjxwPjxicj4KPC9wPgo8cD5HYWxsZXJ5zbzP8byvtcTNvMas5K/AwNCnufuho9CnufvNvMjnz8Kjujxicj4KPC9wPgo8cD48aW1nIHNyYz0="/uploadfile/Collfiles/20150314/2015031408421070.png" alt="\">

下面是FlingView.java文件:
public class FlingView extends View {
private Bitmap bitmap;
private Bitmap nBitmap;
private Bitmap fBitmap;
public int offsetX = 0;
public int offsetY = 0;
public int postion = 0;
private Bitmap[] bitmaps;
public FlingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlingView(Context context, Bitmap[] bitmaps) {
super(context);
this.bitmaps = bitmaps;
bitmap = getBitmap(0);
nBitmap = getBitmap(1);
}
// 在滑動過程中,通過實現View的Draw()方法繪制圖片,注意:此時需要同時繪制當前圖片(獲取焦點)和下一張圖片(即將獲取焦點)共兩張圖片
@Override
public void draw(Canvas canvas) {
Paint paint = new Paint();
Rect rect = new Rect();
canvas.drawColor(Color.BLACK);
// 繪制當前圖片
if (bitmap != null) {
int left = offsetX;
int top = offsetY;
int right = offsetX + MainActivity.deviceScreenWidth;
int bottom = offsetY + MainActivity.deviceScreenHeight;
rect.set(left, top, right, bottom);
canvas.drawBitmap(bitmap, null, rect, paint);
}
// 繪制下一張圖片
if (offsetX < 0) { // 向左滑動
if (nBitmap != null) {
int left = MainActivity.deviceScreenWidth + 15 + offsetX;
int top = 0;
int right = left + MainActivity.deviceScreenWidth;
int bottom = MainActivity.deviceScreenHeight;
rect.set(left, top, right, bottom);
canvas.drawBitmap(nBitmap, null, rect, paint);
}
} else if (offsetX > 0) { // 向右滑動
if (fBitmap != null) {
int left = -MainActivity.deviceScreenWidth - 15 + offsetX;
int top = 0;
int right = left + MainActivity.deviceScreenWidth;
int bottom = MainActivity.deviceScreenHeight;
rect.set(left, top, right, bottom);
canvas.drawBitmap(fBitmap, null, rect, paint);
}
}
}
public void handleScroll(int deltaX) {
if (deltaX > 0) {
offsetX -= -deltaX;
} else {
offsetX += deltaX;
}
invalidate();
}
boolean isFling = false; // 標記是否需要切換到下一張(滑動距離超過屏幕寬度的 1/3)
boolean isFlingRight = false; // 標記為需要向右滑動
boolean isFlingLeft = false; // 標記為需要向左滑動
class MyAnimation extends Animation {
private int tmpOffsetX;
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
tmpOffsetX = offsetX;
super.initialize(width, height, parentWidth, parentHeight);
setDuration(500);
setFillAfter(true);
setInterpolator(new LinearInterpolator());
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
// Log.i("bb", "offsetX==>"+offsetX);
if (isFling) { // 需要滑動圖片時根據方向來變換offsetX大小
if (tmpOffsetX > 0) {
offsetX = (int) ((MainActivity.deviceScreenWidth - tmpOffsetX)
* interpolatedTime + tmpOffsetX);
} else {
offsetX = (int) ((-MainActivity.deviceScreenWidth - tmpOffsetX)
* interpolatedTime + tmpOffsetX);
}
} else { // 不需要變換的情況
offsetX = (int) (tmpOffsetX * (1 - interpolatedTime));
}
invalidate();
}
}
// 動畫結束後需要做一些工作
//在滑動圖片結束後,需要做滑動動畫後的處理,重新設置當前圖片和當前圖片的上一張和下一張的狀態,為下次滑動做准備
@Override
protected void onAnimationEnd() {
if (isFlingRight) { // 向右滑動,position減1
nBitmap = bitmap;
bitmap = fBitmap;
fBitmap = null;
postion = postion - 1;
} else if (isFlingLeft) { // 向左滑動,position加1
fBitmap = bitmap;
bitmap = nBitmap;
nBitmap = null;
postion = postion + 1;
}
isFlingRight = false;
isFlingLeft = false;
isFling = false;
offsetX = 0;
if (fBitmap == null && offsetX == 0) { // 如果前一張圖片為空(向右滑),則重置前一張圖片(position
// - 1)
if (postion > 0) {
fBitmap = getBitmap(postion - 1);
}
} else if (nBitmap == null && offsetX == 0) { // 如果後一張圖片為空(向左滑),則重置後一張圖片(position
// + 1)
if (postion < bitmaps.length - 1) {
nBitmap = getBitmap(postion + 1);
}
}
clearAnimation();
}
/** 獲得當前位置的圖片 */
public Bitmap getBitmap(int currentPos) {
if (currentPos > bitmaps.length - 1) {
return null;
}
Bitmap currBitmap = bitmaps[currentPos];
offsetX = 0;
offsetY = 0;
return currBitmap;
}
//獲取來自Activity中的手勢速度
public void onFling(int paramFloat1) {
if (offsetX > MainActivity.deviceScreenWidth / 5) {
if (fBitmap != null) {
isFling = true;
isFlingRight = true;
}
} else if (offsetX < -MainActivity.deviceScreenWidth / 5) {
if (nBitmap != null) {
isFling = true;
isFlingLeft = true;
}
}
// 開始動畫效果
startAnimation(new MyAnimation());
}
}
下面是MainActivity.java主界面文件:(沒layout文件)
public class MainActivity extends Activity implements OnGestureListener {
private FlingView flingView;
private GestureDetector myGesture;
public static int deviceScreenWidth;
public static int deviceScreenHeight;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 獲得手機的寬帶和高度像素單位為px
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
deviceScreenWidth = dm.widthPixels;
deviceScreenHeight = dm.heightPixels;
Log.i("mActivity", "deviceScreenWidth = " + deviceScreenWidth + "; deviceScreenHeight = " + deviceScreenHeight);
Bitmap[] bitmaps = {
BitmapFactory.decodeResource(getResources(), R.drawable.img1),
BitmapFactory.decodeResource(getResources(), R.drawable.img2),
BitmapFactory.decodeResource(getResources(), R.drawable.img3),
BitmapFactory.decodeResource(getResources(), R.drawable.img4),
BitmapFactory.decodeResource(getResources(), R.drawable.img5) };
myGesture = new GestureDetector(this);
flingView = new FlingView(this, bitmaps);
setContentView(flingView);
}
//Activity中,通過onTouchEvent() 注冊 myGesture.onTouchEvent(event)
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
flingView.onFling(0); // 手指抬起後,重置滑動距離offsetX = 0
break;
}
return myGesture.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.i("mActivity", "velocityX = " + velocityX + "; velocityY = " + velocityY);
flingView.onFling((int) - velocityX);
return true;
}
@Override
public void onLongPress(MotionEvent e) {
}
//獲取滑動的x軸距離
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.i("mActivity", "distanceX = " + distanceX + "; distanceY = " + distanceY);
flingView.handleScroll(-1 * (int) distanceX);
return true;
}
//獲取手勢的速度
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
}
android 賬戶管理和同步機制
在用微信的時候,發現微信建立了自己的獨立賬戶管理,同時在聯系人中,可以直接點擊發送信息,查看朋友圈等功能,感覺挺方便了 然後就做了相關方面的調研,主要從兩個方面,進行了研
android Activity線性布局和表格布局實例講解
實驗中只需要編寫相應的xml的代碼,java代碼不需要更改,因為我們這裡只是練習android的界面設計。線性布局:線性布局就是將各種控件按照行或者列依次進行排列。其中本
Android內存洩露測試
在進行Android內存洩露分析時,面對成千上萬個對象,你是否藍瘦,香菇?作為測試人員你在進行內存洩露測試之後,是否有勇氣告訴開發同事程序已經沒有內存洩露,可以放心發布了
Android簡易實戰教程--第七話《在內存中存儲用戶名和密碼》
首先是配置文件: 活動中的代碼如下: package com.itydl.rwinrom;import jav