zoukankan      html  css  js  c++  java
  • 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);
    	    }
    	}
    }
    
    








  • 相关阅读:
    Window 窗口类
    使用 Bolt 实现 GridView 表格控件
    lua的table库
    Windows编程总结之 DLL
    lua 打印 table 拷贝table
    使用 xlue 实现简单 listbox 控件
    使用 xlue 实现 tips
    extern “C”
    COleVariant如何转换为int double string cstring
    原来WIN32 API也有GetOpenFileName函数
  • 原文地址:https://www.cnblogs.com/season-peng/p/6713549.html
Copyright © 2011-2022 走看看