国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android自定義Gallery控件實(shí)現(xiàn)3D圖片瀏覽器

2019-10-22 18:12:47
字體:
供稿:網(wǎng)友

本篇文章主要介紹如何使用自定義的Gallery控件,實(shí)現(xiàn)3D效果的圖片瀏覽器的效果。

話不多說,先看效果。

Android,Gallery,圖片瀏覽器

上面是一個(gè)自定義的Gallery控件,實(shí)現(xiàn)倒影和仿3D的效果,下面是一個(gè)圖片查看器,點(diǎn)擊上面的小圖片,可以在下面查看大圖片。

下面重點(diǎn)說一下,實(shí)現(xiàn)圖片查看器的思路。

1.手機(jī)中圖片路徑的獲取

首先,先不管圖片如何展示,如果我們想實(shí)現(xiàn)圖片查看器的功能,我們首先需要做的是獲取到所有的圖片的路徑信息,只有這樣,我們才能實(shí)現(xiàn)對(duì)圖片的查看。

我們可以使用下面的代碼實(shí)現(xiàn)

private List<String> getImagesFromSD() {     List<String> imageList = new ArrayList<String>();     File f = Environment.getExternalStorageDirectory();     if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {       f = new File(Environment.getExternalStorageDirectory().toString());     } else {       Toast.makeText(MainActivity.this, R.string.sdcarderror, Toast.LENGTH_LONG).show();       return imageList;     }      File[] files = f.listFiles();     if (files == null || files.length == 0)       return imageList;      for (int i = 0; i < files.length; i++) {       File file = files[i];       if (isImageFile(file.getPath()))         imageList.add(file.getPath());     }     return imageList;   } 

上面這個(gè)方法的作用,就是獲取SD卡中,所有文件的后綴名滿足圖片后綴名的文件的路徑,然后放到List容器中返回。

isImageFile方法是這樣實(shí)現(xiàn)的

private boolean isImageFile(String fName) {     String end = fName.substring(fName.lastIndexOf(".") + 1, fName.length()).toLowerCase();     if (end.equals("jpg") || end.equals("gif") || end.equals("png") || end.equals("jpeg") || end.equals("bmp")) {       return true;     }     return false;    } 

2.上方小圖片3D效果展示的實(shí)現(xiàn)

在完成了圖片路徑的獲取之后,我們下面要做的就是將圖片展示在上面的有3D效果的自定義Gallery控件上面。現(xiàn)在版本中Gallery控件已經(jīng)不再推薦使用,取而代之的ViewPager和HorizonalScrollView控件。
下面介紹具有自定義Gallery控件的實(shí)現(xiàn)

/**  * 3D效果Gallery實(shí)現(xiàn)  *  * @time 2014年6月26日 下午9:10:47  */ @SuppressWarnings("deprecation") public class GalleryFlow extends Gallery {    private Camera mCamera = new Camera();   // 兩側(cè)圖片最大旋轉(zhuǎn)角度   private int mMaxRotationAngle = 60;   private int mMaxZoom = -120;   private int mCoveflowCenter;    public GalleryFlow(Context context) {     super(context);     this.setStaticTransformationsEnabled(true);   }    public GalleryFlow(Context context, AttributeSet attrs) {     super(context, attrs);     this.setStaticTransformationsEnabled(true);   }    public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {     super(context, attrs, defStyle);     this.setStaticTransformationsEnabled(true);   }    // 設(shè)置最大旋轉(zhuǎn)角   public void setMaxRotationAngle(int maxRotationAngle) {     mMaxRotationAngle = maxRotationAngle;   }    // 獲取當(dāng)前控件中心點(diǎn)x軸位置   private int getCenterOfCoverflow() {     return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();   }    // 獲取view控件的x軸位置   private static int getCenterOfView(View view) {     return view.getLeft() + view.getWidth() / 2;   }    // 默認(rèn)返回值是false,若設(shè)置城true,則每次gallery生成子控件的時(shí)候,都會(huì)調(diào)用這個(gè)方法,所以我們可以將返回值設(shè)置為true,然后完成child的旋轉(zhuǎn)等變形操作   protected boolean getChildStaticTransformation(View child, Transformation t) {      final int childCenter = getCenterOfView(child);     final int childWidth = child.getWidth();     int rotationAngle = 0;     t.clear();     t.setTransformationType(Transformation.TYPE_MATRIX);      // 如果child控件在中心位置,則不旋轉(zhuǎn)     if (childCenter == mCoveflowCenter) {       transformImageBitmap((ImageView) child, t, 0);      } else {       // 否則,將當(dāng)前child控件旋轉(zhuǎn)一定角度       rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);       if (Math.abs(rotationAngle) > mMaxRotationAngle) {         rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;       }       transformImageBitmap((ImageView) child, t, rotationAngle);     }      return true;   }    //重新計(jì)算控件的x軸位置   protected void onSizeChanged(int w, int h, int oldw, int oldh) {     mCoveflowCenter = getCenterOfCoverflow();     super.onSizeChanged(w, h, oldw, oldh);   }    // 將child控件旋轉(zhuǎn)rotationAngle方法的實(shí)現(xiàn)   private void transformImageBitmap(ImageView child, Transformation t, int rotationAngle) {      mCamera.save();     final Matrix imageMatrix = t.getMatrix();     final int imageHeight = child.getLayoutParams().height;     final int imageWidth = child.getLayoutParams().width;     final int rotation = Math.abs(rotationAngle);      // 在Z軸上正向移動(dòng)camera的視角,實(shí)際效果為放大圖片。 如果在Y軸上移動(dòng),則圖片上下移動(dòng);X軸上對(duì)應(yīng)圖片左右移動(dòng)。     mCamera.translate(0.0f, 0.0f, 100.0f);     if (rotation < mMaxRotationAngle) {       float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));       mCamera.translate(0.0f, 0.0f, zoomAmount);     }      // 在Y軸上旋轉(zhuǎn),對(duì)應(yīng)圖片豎向向里翻轉(zhuǎn)。如果在X軸上旋轉(zhuǎn),則對(duì)應(yīng)圖片橫向向里翻轉(zhuǎn)。     mCamera.rotateY(rotationAngle);     mCamera.getMatrix(imageMatrix);     imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));     imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));      // 恢復(fù)相機(jī)原狀態(tài)     mCamera.restore();   } } 

通過自定義gallery控件,現(xiàn)在我們已經(jīng)實(shí)現(xiàn)了當(dāng)滑動(dòng)Gallery里面的圖片時(shí),兩側(cè)的圖片會(huì)發(fā)生一定角度的旋轉(zhuǎn),也就是完成了3D效果的第一部,下一步,就需要我們?cè)贕allery的Adapter里面,對(duì)getView方法,進(jìn)行改造,從而完成預(yù)覽小圖片的倒影效果

3.實(shí)現(xiàn)Adapter,完成倒影效果

要完成倒映效果,我們需要在getView方法中,對(duì)穿進(jìn)來的圖片進(jìn)行處理,具體代碼如下

@SuppressWarnings({ "deprecation", "unused" }) public class ImageAdapter extends BaseAdapter {    private Context mContext;   //用于存放圖片的路徑   private List<String> imageFileList;   //原始圖片   private Bitmap originalImage;   //反射的倒影圖片,高度為原始圖片一半   private Bitmap reflectionImage;   //用于存放處理后的整個(gè)圖片,高度為原始圖片的1.5倍   private Bitmap bitmapWithReflection;   //圖片的寬高   private int width;   private int height;   //矩陣   private Matrix matrix;   //畫布   private Canvas canvas;   //原始圖像與反射的倒影圖像之間的間隔高度   final int reflectionGap = 4;   //用于getView返回   private ImageView imageView;   //倒影的陰影模糊效果   private LinearGradient shader;      public ImageAdapter(Context c, List<String> _imageFileList) {      mContext = c;     imageFileList = _imageFileList;     matrix = new Matrix();     //設(shè)置為x軸翻轉(zhuǎn)     matrix.preScale(1, -1);        }      @Override   public int getCount() {     return imageFileList.size();   }    @Override   public Object getItem(int position) {     return position;   }    @Override   public long getItemId(int position) {     return position;   }    //返回經(jīng)過處理的ImageView對(duì)象   @Override   public View getView(int position, View convertView, ViewGroup parent) {     return createReflectedImages(imageFileList.get(position));   }      //這是最主要的方法,完成了對(duì)圖片的倒映效果處理   public ImageView createReflectedImages(String filePath) {      //獲取原始圖片     originalImage = BitmapFactory.decodeFile(filePath);          width = originalImage.getWidth();     height = originalImage.getHeight();          //創(chuàng)建倒影圖像,高度是原始圖像的一半,并且使用矩陣進(jìn)行了x軸反轉(zhuǎn),也就是倒影效果     reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false);     //初始化Bitmap對(duì)象,用于存放處理后的圖片,高度為原始圖片的1.5倍     bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888);     //根據(jù)bitmapWithReflection對(duì)象,創(chuàng)建一個(gè)畫布     canvas = new Canvas(bitmapWithReflection);     //先把原始圖像畫上     canvas.drawBitmap(originalImage, 0, 0, null);          Paint paint = new Paint();     //畫出原始圖像與反射圖像之間的小空隙,高度為reflectionGap     canvas.drawRect(0, height, width, height + reflectionGap, paint);          //畫出倒影     canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);     //設(shè)置畫筆的陰影效果     shader = new LinearGradient(0, originalImage.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff,         TileMode.CLAMP);     paint.setShader(shader);     paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));      //在倒影圖上用帶陰影的畫筆繪制矩形     canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);     //初始化一個(gè)ImageView對(duì)象     imageView = new ImageView(mContext);     //將處理后的圖像設(shè)置為圖片資源     imageView.setImageBitmap(bitmapWithReflection);     imageView.setLayoutParams(new Gallery.LayoutParams(120, 160));     imageView.setScaleType(ScaleType.CENTER_INSIDE);     return imageView;   }     } 

最主要的還是理解如何實(shí)現(xiàn)的倒影效果。注釋應(yīng)該是很詳細(xì)了,不過多解釋。

4.如何使用自定義的Gallery控件實(shí)現(xiàn)最終的圖片查看器

下面,我們看一下,如何使用這個(gè)控件,實(shí)現(xiàn)我們最終的效果。
布局文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="fill_parent"   android:layout_height="fill_parent"   android:background="#F9F900"   android:gravity="center_horizontal"   android:orientation="vertical" >    <com.examole.gallery.GalleryFlow     android:id="@+id/mygallery"     android:layout_width="match_parent"     android:layout_height="100dp"     android:layout_marginTop="20dp"     android:gravity="center_vertical" />    <ImageSwitcher     android:id="@+id/switcher"     android:layout_width="wrap_content"     android:layout_height="match_parent"     android:layout_gravity="center_horizontal" />  </LinearLayout> 

我們?cè)谶@里使用了一個(gè)很陌生的類,那就是ImageSwicher,我們看一下,在Activity如何使用

public class MainActivity extends Activity implements AdapterView.OnItemSelectedListener, ViewSwitcher.ViewFactory {    private List<String> ImageList;   private ImageSwitcher mSwitcher;   private Gallery gallery;    @Override   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     // 獲取圖片路徑     ImageList = getImagesFromSD();     mSwitcher = (ImageSwitcher) findViewById(R.id.switcher);     gallery = (Gallery) findViewById(R.id.mygallery);     // ImageSwitcher控件必須實(shí)現(xiàn)ViewSwitcher.ViewFactory接口,然后在makeView方法中,返回我們需要顯示的控件即可     mSwitcher.setFactory(this);     // 設(shè)置圖片的進(jìn)入和離開的動(dòng)畫效果     mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left));     mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right));     // 給gallery設(shè)置適配器     gallery.setAdapter(new ImageAdapter(this, ImageList));     gallery.setOnItemSelectedListener(this);    }    private List<String> getImagesFromSD() {     List<String> imageList = new ArrayList<String>();     File f = Environment.getExternalStorageDirectory();     if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {       f = new File(Environment.getExternalStorageDirectory().toString());     } else {       Toast.makeText(MainActivity.this, R.string.sdcarderror, Toast.LENGTH_LONG).show();       return imageList;     }      File[] files = f.listFiles();     if (files == null || files.length == 0)       return imageList;      for (int i = 0; i < files.length; i++) {       File file = files[i];       if (isImageFile(file.getPath()))         imageList.add(file.getPath());     }     return imageList;   }    @SuppressLint("DefaultLocale")   private boolean isImageFile(String fName) {     String end = fName.substring(fName.lastIndexOf(".") + 1, fName.length()).toLowerCase();     if (end.equals("jpg") || end.equals("gif") || end.equals("png") || end.equals("jpeg") || end.equals("bmp")) {       return true;     }     return false;    }    @Override   public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {     // 當(dāng)點(diǎn)擊上面的小圖片的時(shí)候,獲取圖片的絕對(duì)路徑,然后設(shè)置給mSwitcher     String photoURL = ImageList.get(position);     mSwitcher.setImageURI(Uri.parse(photoURL));   }    @Override   public void onNothingSelected(AdapterView<?> parent) {    }    @Override   public View makeView() {     ImageView i = new ImageView(this);     i.setBackgroundColor(0x00000000);     i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);     i.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));     return i;   } } 

除了ImageSwitcher這個(gè)控件,其他的應(yīng)該都很熟悉了,經(jīng)過這幾個(gè)步驟,我們終于實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的仿3D效果的圖片查看器。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 天等县| 长春市| 松潘县| 化州市| 嘉禾县| 桐城市| 灵川县| 肇源县| 泾阳县| 共和县| 武安市| 乾安县| 科尔| 军事| 临猗县| 子长县| 旬邑县| 潍坊市| 沧州市| 景洪市| 赤壁市| 体育| 聊城市| 襄汾县| 齐河县| 益阳市| 高雄县| 余姚市| 宣恩县| 全椒县| 沾益县| 新和县| 安新县| 牙克石市| 东丽区| 元朗区| 巴青县| 泾源县| 长春市| 黄冈市| 拉萨市|