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);
    	    }
    	}
    }
    
    








  • 相关阅读:
    想要提高自己的写作水平?吃透这篇文章就够了
    Linux(Ubuntu)下搭建ASP.NET Core环境
    详解ASP.NET Core Docker部署
    《你有多少问题要请示》精华集粹
    5年,我从文员一路晋升到总监,薪资翻了5倍[转]
    《设计你的人生》的部分经典语录
    深入浅出Redis-redis哨兵集群[转]
    什么是全栈开发者
    Asp.net mvc中应用autofac
    js unicode处理
  • 原文地址:https://www.cnblogs.com/season-peng/p/6713549.html
Copyright © 2011-2022 走看看