1. 程式人生 > >Android學習:Gallery的相簿應用

Android學習:Gallery的相簿應用

0.前言

這個學期有嵌入式的課程,需要做一個嵌入式的成品,本來我不想做帶系統的東西,但老師說了,上海是服務型的城市,我知道你們怕帶系統的東西,做帶系統的比較好Balabalabala……好吧,按老師的要求,我們準備做安卓下的電子相簿,圖片從外部儲存SD卡上讀取(很搞笑誒,做個相簿需要用安卓麼,純粹為了學習)

之前一直沒接觸過安卓,前期查了點資料,開始起步學習Android,準備用控制元件Gallery,之後發現該控制元件“Deprecated since API level16“也就是Android4.1.2,但網路上Gallery的資料比較多,對於我這個新手比較好入手,大體效果如下:

測試系統:MIUI-4.4.4,Android-4.1.1

1.佈局

首先在佈局檔案中加入兩個Gallery,上面的叫biggallery,由於原有的Gallery一滑動就會滑過許多格,要實現一次滑一屏的效果,我們寫了自定義的myGallery類,繼承Gallery,下面縮圖的是原有的Gallery

佈局檔案如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.test.MainActivity$PlaceholderFragment" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <com.example.test.myGallery   
        android:id="@+id/biggalleryid"    
        android:layout_width="fill_parent"    
        android:background="#000000"    
        android:layout_height="fill_parent"    
        android:layout_alignParentTop="true"      
        android:layout_alignParentLeft="true"    
        android:gravity="center_vertical"    
        android:spacing="5dip"/> 
    <Gallery
        android:id="@+id/galleryid"    
        android:layout_width="fill_parent"    
        android:background="#000000"    
        android:layout_height="80dip"    
        android:layout_alignParentBottom="true"      
        android:layout_alignParentLeft="true"    
        android:gravity="center_vertical"    
        android:spacing="1dip"/>     

</RelativeLayout>


新建一個myGallery類繼承Gallery:

package com.example.test;

import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.Gallery;

public class myGallery extends Gallery {                        

	public myGallery(Context context) {
        super(context);
        this.setStaticTransformationsEnabled(true);
	}
	public myGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setStaticTransformationsEnabled(true);
	}
	public myGallery(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
       this.setStaticTransformationsEnabled(true);
	}        
	private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) {
		return e2.getX() > e1.getX();
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		// e1是按下的事件,e2是擡起的事件
		int keyCode;
		if (isScrollingLeft(e1, e2)) {
			keyCode = KeyEvent.KEYCODE_DPAD_LEFT;
		} else {
			keyCode = KeyEvent.KEYCODE_DPAD_RIGHT;
		}
		onKeyDown(keyCode, null);
		return true;
	}                    
	
}  
3.讀取圖片
建立好了兩個Gallery,接下來,我們需要讀取外部SD卡中的圖片了,我是通過把圖片的路徑放入一個List中實現的,由getpicpath(String sdpath)來實現。我感覺這個應用比較難的地方是順暢地載入圖片,我們知道從外部SD卡讀取圖片是慢的,從快取中直接讀是比較快的,還有一點就是現在的相機畫素都比較高,載入照片就容易慢。對於載入慢的這個問題,我們可以在程式onCreat()的時候先把縮圖載入進記憶體(注意要是縮圖,不然容易造成記憶體溢位),供下面的Gallery使用;之前,我不是這麼做的,我是在滑動的時候進行圖片解碼decodeSampledBitmapFromFile(),這樣的話,滑動一次就要解碼載入一次,快速滑動的話會連續載入沿路的圖片,還會更加地卡。

4.載入介面卡

我們載入好圖片、建立好Gallery之後,怎麼把這兩者聯絡起來呢,一個是資料來源,一個是檢視View,這中間要有一個介面卡,我們可以使用一個繼承自BaseAdapter類的派生類ImageAdapter來裝這些圖片。

  在ImageAdapter類中我們需要實現Adapter類中的如下四個抽象方法:

  (1)public int getCount();

  (2)public Object getItem(int position);

  (3)public long getItemId(int position);

  (4)public View getView(int position, View convertView, ViewGroup parent);

  其中,getCount()方法用於獲取ImageAdapter介面卡中圖片個數;getItem()方法用於獲取圖片在ImageAdapter介面卡中的位置;getItemId()方法用於獲取圖片在ImageAdapter介面卡中位置;getView()用於獲取ImageAdapter介面卡中指定位置的檢視物件。

MainActivity類如下:

package com.example.test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar.LayoutParams;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.util.LruCache;
import android.support.v7.app.ActionBarActivity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.Gallery;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;


public class MainActivity extends ActionBarActivity /*implements ViewFactory*/{
	
	private List<String> photolist = new ArrayList<String>();
	private myGallery biggallery;
	private Gallery gallery;
	private ImageAdapter imageAdapter;
	private BigImageAdapter bigimageAdapter;  
	private int galleryItemBackground; 
	private String newFilePath; 
	private int downX,upX; 
	private LruCache<String, Bitmap> dateCache;
	private int motionStatus;
	private SensorManager sensormanager;
	private Sensor lightsensor,orientationsensor,accelerometersensor;
	private String sen;
	private int delay;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        
        //獲得感測器列表
        sensormanager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        List<Sensor> sensors = sensormanager.getSensorList(Sensor.TYPE_ALL);
        for(Sensor sensor:sensors)
        	sen = sensor.getName();
        lightsensor = (Sensor)sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT);
        accelerometersensor = (Sensor)sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        orientationsensor = (Sensor)sensormanager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        
        
        
        //獲得所有圖片路徑
        String sdpath = Environment.getExternalStorageDirectory()+"/DCIM/Camera/";
        getpicpath(sdpath);
        
        //gallery設定背景
        TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);  
        galleryItemBackground = a.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 0);
        a.recycle(); 
        
        //new一個快取
        dateCache = new LruCache<String, Bitmap>(photolist.size());
        

        gallery = (Gallery)findViewById(R.id.galleryid);
        biggallery = (myGallery)findViewById(R.id.biggalleryid);
        imageAdapter = new ImageAdapter(photolist,this,galleryItemBackground);  
        gallery.setAdapter(imageAdapter); 
        bigimageAdapter = new BigImageAdapter(photolist,this,0);  
        biggallery.setAdapter(bigimageAdapter); 

        gallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){    
            public void onItemSelected(AdapterView<?> arg0, View arg1,int position, long when){
            	imageAdapter.setSelectItem(position);
            	biggallery.setSelection(position);
            	
            }    
            public void onNothingSelected(AdapterView<?> arg0) {}    
        }); 
        
        
        
        biggallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){    
            public void onItemSelected(AdapterView<?> arg0, View arg1,int position, long when){
//            	gallery.setSelection(position);
            }    
            public void onNothingSelected(AdapterView<?> arg0) {}    
        }); 
    }
    protected void onResume() {
    	sensormanager.registerListener(new SensorEventListener(){
        	public void onSensorChanged(SensorEvent event){
        	//	float value0 = event.values[0];
        	//	float value1 = event.values[1];
        		float value2 = event.values[2];
        		System.out.println("value2:"+value2);
        		delay += value2; 
        		if((value2<10)&&(value2>-10))delay=0;
        		if(delay>100){
        			delay=0;
        			if(imageAdapter.getShowingIndex()!=0)
        				gallery.setSelection(imageAdapter.getShowingIndex()-1);
        		}
        		if(delay<-100){
        			delay=0;
        			if(imageAdapter.getShowingIndex()!=imageAdapter.getCount()-1)
        				gallery.setSelection(imageAdapter.getShowingIndex()+1);
        		}
        	}
        	public void onAccuracyChanged(Sensor sensor,int accuracy){
        		
        	}
        },orientationsensor,sensormanager.SENSOR_DELAY_UI);
    	super.onResume();
    }
    
    protected void onPause() {
    	//登出所有感測器的監聽
    //	sensormanager.unregisterListener();
    	super.onPause();
    	}
    private class MyTask extends AsyncTask<Void, Void, Void> {
		@Override
		protected Void doInBackground(Void... params) {
			/*int showing = adapter.getShowingIndex();// 記錄當前正在顯示圖片的id
			Bitmap[] bitmaps = adapter.getNearBitmaps();//獲得Adapter中的快取圖片陣列
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 2;
			if(motionStatus==-1){//向前滑動,bitmaps[0]載入新的圖片
				bitmaps[2]=bitmaps[1];
				bitmaps[1]=bitmaps[0];
				if(showing>=2)
				bitmaps[0]=BitmapFactory.decodeResource(getResources(), imagesId[showing - 2],
						options);
			}
			if(motionStatus==1){//向後滑動,bitmaps[2]載入新的圖片
				bitmaps[0]=bitmaps[1];
				bitmaps[1]=bitmaps[2];
				if(showing<=imagesId.length-3)
				bitmaps[2]=BitmapFactory.decodeResource(getResources(), imagesId[showing + 2],
						options);
			}
			adapter.setShowingIndex(showing+motionStatus);*/
			return null;
		}
	}
    
    /*
     * 註冊一個觸控事件  
     */    
    private OnTouchListener touchListener = new View.OnTouchListener() {    
        public boolean onTouch(View v, MotionEvent event) {    
             if(event.getAction()==MotionEvent.ACTION_DOWN)      
                {      
                    downX=(int) event.getX();//取得按下時的座標      
                    return true;      
                }      
                else if(event.getAction()==MotionEvent.ACTION_UP)      
                {      
                    upX=(int) event.getX();//取得鬆開時的座標      
                    int index=0;      
                    if(upX-downX>70)//從左拖到右,即看前一張      
                    {      
                        //如果是第一,則去到尾部      
                        if(gallery.getSelectedItemPosition()==0)      
                           index=gallery.getCount()-1;      
                        else      
                           index=gallery.getSelectedItemPosition()-1; 
                        
                        //改變gallery圖片所選,自動觸發ImageSwitcher的setOnItemSelectedListener 
                        biggallery.setSelection(index, true);                    }      
                    else if(downX-upX>70)//從右拖到左,即看後一張      
                    {      
                        //如果是最後,則去到第一      
                        if(gallery.getSelectedItemPosition()==(gallery.getCount()-1))      
                            index=0;      
                        else      
                            index=gallery.getSelectedItemPosition()+1;
                        gallery.setSelection(index, true);
                    }      
                         
                          
                    return true;      
                }      
                return false;      
            }    
    };    
    
    //以下三個函式的作用:獲取所有圖片的路徑,並放入LIST中
    private String isSdcard(){
        File sdcardDir=null;
        boolean isSDExist=Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if(isSDExist){
        	sdcardDir=Environment.getExternalStorageDirectory(); 
        	return sdcardDir.toString();
        }
        else{
        	return null;
        }
    }
    //
	public void getpicpath(String sdpath){
	    //開啟SD卡目錄
		File file = new File(sdpath);
		//獲取SD卡目錄列表
		File[] files =file.listFiles();
		for(int z=0;z<files.length;z++){
			File f = files[z];
			if(f.isFile()){
				isfile(f);         
			}
			/*else{
	      	notfile(f);        
	   		}*/
		}
	}
	//若是檔案
	public void isfile(File file){
		String filename=file.getName();
	    int idx = filename.lastIndexOf(".");
	 
        if (idx <= 0) {
            return;
        }
        String suffix =filename.substring(idx+1, filename.length());
        if (suffix.toLowerCase().equals("jpg") ||
        suffix.toLowerCase().equals("jpeg") ||
        suffix.toLowerCase().equals("bmp") ||
        suffix.toLowerCase().equals("png") ||
        suffix.toLowerCase().equals("gif") ){
        //	mapsd.put("imagepath",file.getPath().toString());
	        String filestring = file.getPath().toString();
			photolist.add(filestring);
	    }
	}
}