android幻燈片效果實現-Gallery

    最近下載幾款手機應用研究了下,發了有些自定義控件驚人的類似,因此我以爲在之後的開發中,對一些控件的複用確定是不少的,在首頁(非載入頁)通常都會有一個幻燈片效果,既能夠放廣告也能夠放推薦,若是圖片設計的好看,效果通常都會不錯,既然用到了Gallery,也附帶把相框效果的例子寫一寫(淘寶詳情界面的商品圖片滑動展現) java

1、效果圖展現 android

    (1)幻燈片效果展現:
            
            
            
     ide

(2)商品圖片滑動展現
            
            
            
        查看大圖:
             post

2、部分代碼說明 測試

    (1)幻燈片效果的實現:
        自定義Gallery:DetailGallery.java
        可視界面:ImgSwitchActivity.java
        適配類:GalleryIndexAdapter.java
        1)自定義Gallery主要重寫onFling經過按下和鬆手的位置不一樣比較是向右移動仍是向左移動,部分代碼以下: this

private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) {
		return e2.getX() > e1.getX();
	}
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		int kEvent;
		if (isScrollingLeft(e1, e2)) {
			kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
		} else {
			kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
		}
		onKeyDown(kEvent, null);
		return true;
	}
        2)在適配類 GalleryIndexAdapter主要完成幻燈片的循環播放,在getCount裏面返回值返回Integer.MAX_VALUE,而後在getView裏面根據position與傳進來初始圖片個數進行餘數計算獲得每次循環到哪張圖片。部分代碼以下:
@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return Integer.MAX_VALUE;
		}

		……

		@Override
		public View getView(int position, View convertView, ViewGroup arg2) {
			// TODO Auto-generated method stub
			ImageView imageView = new ImageView(context);
			imageView.setBackgroundResource(imagList.get(position%imagList.size()));
			imageView.setScaleType(ScaleType.FIT_XY);
			imageView.setLayoutParams(new Gallery.LayoutParams(Gallery.LayoutParams.FILL_PARENT
					, Gallery.LayoutParams.WRAP_CONTENT));
			return imageView;
		}
         3)在可視界面裏面實現邏輯控制,經過定時器定時刷新幻燈片,定時器經過定時發送消息,消息接受處理機制接收到消息以後,就模擬滑動事件,調用Gallery的onFling方法實現圖片自動切換效果。選擇按鈕的顯示效果(RadioButton)須要在Gallery的setOnItemSelectedListener進行處理。  
//定時器和事件處理5秒刷新一次幻燈片
/** 展現圖控制器,實現展現圖切換 */
	final Handler handler_gallery = new Handler() {
		public void handleMessage(Message msg) {
			/* 自定義屏幕按下的動做 */
			MotionEvent e1 = MotionEvent.obtain(SystemClock.uptimeMillis(),
					SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,
					89.333336f, 265.33334f, 0);
			/* 自定義屏幕放開的動做 */
			MotionEvent e2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
					SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN,
					300.0f, 238.00003f, 0);
			
			myGallery.onFling(e2, e1, -800, 0);
			/* 給gallery添加按下和放開的動做,實現自動滑動 */
			super.handleMessage(msg);
		}
	};
	protected void onResume() {
		autogallery();
		super.onResume();
	};
	private void autogallery() {
		/* 設置定時器,每5秒自動切換展現圖 */
		Timer time = new Timer();
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				Message m = new Message();
				handler_gallery.sendMessage(m);
			}
		};
		time.schedule(task, 8000, 5000);
	}
//指示按鈕和gallery初始化過程以及事件監聽添加過程
//初始化
	void init(){
		myGallery = (DetailGallery)findViewById(R.id.myGallery);
		gallery_points = (RadioGroup) this.findViewById(R.id.galleryRaidoGroup);
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(R.drawable.banner1);
		list.add(R.drawable.banner2);
		list.add(R.drawable.banner3);
		list.add(R.drawable.banner4);
		GalleryIndexAdapter adapter = new GalleryIndexAdapter(list, context);
		myGallery.setAdapter(adapter);
		//設置小按鈕
		gallery_point = new RadioButton[list.size()];
		for (int i = 0; i < gallery_point.length; i++) {
			layout = (LinearLayout) inflater.inflate(R.layout.gallery_icon, null);
			gallery_point[i] = (RadioButton) layout.findViewById(R.id.gallery_radiobutton);
			gallery_point[i].setId(i);/* 設置指示圖按鈕ID */
			int wh = Tool.dp2px(context, 10);
			RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(wh, wh); // 設置指示圖大小
			gallery_point[i].setLayoutParams(layoutParams);
			layoutParams.setMargins(4, 0, 4, 0);// 設置指示圖margin值
			gallery_point[i].setClickable(false);/* 設置指示圖按鈕不能點擊 */
			layout.removeView(gallery_point[i]);//一個子視圖不能指定了多個父視圖
			gallery_points.addView(gallery_point[i]);/* 把已經初始化的指示圖動態添加到指示圖的RadioGroup中 */
		}
	}
	//添加事件
	void addEvn(){
		myGallery.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// TODO Auto-generated method stub
				gallery_points.check(gallery_point[arg2%gallery_point.length].getId());
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
				
			}
		});
	}

    (2)商品圖片滑動實現過程:
        圖片滑動效果和上面的幻燈片效果很是的相似,只是在邏輯處理和界面上有一些小小的區別。
        1)適配器類GalleryAdapter.java上面進行了圖片縮放處理,節省了內存開銷,又可把圖片按照本身的要求縮放。 spa

//因爲是測試case,因此圖片都是寫死的爲了區別,在position = 1的時候換了一張圖片
public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			ImageView imageView = (ImageView) LayoutInflater.from(context).inflate(R.layout.img,
					null);
			Bitmap bitmap = null;
			try {
				if(position == 1 ){
					bitmap = BitmapFactory.decodeStream(assetManager.open("xpic11247_s.jpg"));
					imageView.setTag("xpic11247_s.jpg");
				}
				else{
					bitmap = BitmapFactory.decodeStream(assetManager.open("item0_pic.jpg"));
					imageView.setTag("item0_pic.jpg");
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 加載圖片以前進行縮放
			int width = bitmap.getWidth();
			int height = bitmap.getHeight();
			float newHeight = 200;
			float newWidth = width*newHeight/height;
			float scaleWidth = ((float) newWidth) / width;
			float scaleHeight = ((float) newHeight) / height;
			// 取得想要縮放的matrix參數
			Matrix matrix = new Matrix();
			matrix.postScale(scaleWidth, scaleHeight);
			// 獲得新的圖片
			Bitmap newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
			System.out.println(newbm.getHeight()+"-----------"+newbm.getWidth());
			imageView.setImageBitmap(newbm);
			// }
			return imageView;

		}
         2)添加了一個相框效果,若是圖片加載失敗,就會出現一個圖片壓縮以後大小相等的相框圖片。
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/waterfall_image"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/image_border"
    >
</ImageView>

3、開發中遇到一些問題
    (1)layout.removeView(gallery_point[i]);//一個子視圖不能指定了多個父視圖
        若是須要把當前子childview添加到另一個view裏面去,則必須在當前的父View裏面移除掉當前的childView,若是不進行這樣處理則會拋出Caused by: java.lang.IllegalStateException異常,提示The specified child already has a parent. You must call removeView() on the child's parent first.
    (2)在進行圖片縮放的時候,記得處理好dp和px直接的轉換。
幻燈片效果實現源碼下載地址
相關文章
相關標籤/搜索