热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Android实现动态向Gallery中添加图片及倒影与3D效果示例

这篇文章主要介绍了Android实现动态向Gallery中添加图片及倒影与3D效果的方法,涉及Android针对图片的加载、显示、翻转、倒影等相关特效功能实现技巧

本文实例讲述了Android实现动态向Gallery中添加图片及倒影与3D效果的方法。分享给大家供大家参考,具体如下:

在Android中gallery可以提供一个很好的显示图片的方式,实现上面的效果以及动态添加数据库或者网络上下载下来的图片资源。我们首先实现一个自定义的Gallery类。

MyGallery.java:

package nate.android.Service;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
publicclass MyGallery extends Gallery {
private Camera mCamera =new Camera();
privateint mMaxRotatiOnAngle=45;
privateint mMaxZoom =-120;
privateint mCoveflowCenter;
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);
 }
publicint getMaxRotationAngle() {
return mMaxRotationAngle;
 }
publicvoid setMaxRotationAngle(int maxRotationAngle) {
   mMaxRotatiOnAngle= maxRotationAngle;
 }
publicint getMaxZoom() {
return mMaxZoom;
 }
publicvoid setMaxZoom(int maxZoom) {
   mMaxZoom = maxZoom;
 }
privateint getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) /2
+ getPaddingLeft();
 }
privatestaticint getCenterOfView(View view) {
return view.getLeft() + view.getWidth() /2;
 }
protectedboolean getChildStaticTransformation(View child, Transformation t) {
finalint childCenter = getCenterOfView(child);
finalint childWidth = child.getWidth();
int rotatiOnAngle=0;
   t.clear();
   t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
     transformImageBitmap((ImageView) child, t, 0);
   } else {
     rotatiOnAngle= (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
       rotatiOnAngle= (rotationAngle <0) &#63;-mMaxRotationAngle
           : mMaxRotationAngle;
     }
     transformImageBitmap((ImageView) child, t, rotationAngle);
   }
returntrue;
 }
protectedvoid onSizeChanged(int w, int h, int oldw, int oldh) {
   mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
 }
privatevoid transformImageBitmap(ImageView child, Transformation t,
int rotationAngle) {
   mCamera.save();
final Matrix imageMatrix = t.getMatrix();
finalint imageHeight = child.getLayoutParams().height;
finalint imageWidth = child.getLayoutParams().width;
finalint rotation = Math.abs(rotationAngle);
// 在Z轴上正向移动camera的视角,实际效果为放大图片。
// 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
   mCamera.translate(0.0f, 0.0f, 100.0f);
// As the angle of the view gets less, zoom in
if (rotation 

在布局文件中

<&#63;xml version="1.0" encoding="utf-8"&#63;>

















在上面的XML文件中,我们使用了自定义的MyGallery。

然后顶一个ImageAdapter类继承自BaseAdapter。

package nate.android.Service;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
import android.graphics.Shader.TileMode;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
publicclass ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private ArrayList dishImages =new ArrayList();
private ImageView[] mImages;
public ImageAdapter(Context c,ArrayList tmpDishImages) {
  mCOntext= c;
  dishImages = tmpDishImages;
  mImages =new ImageView[dishImages.size()];
 }
publicboolean createReflectedImages() {
finalint reflectiOnGap=4;
int index =0;
  System.out.println("dishImages size "+ dishImages.size());
for (int i =0; i 

在这个类中构造函数需要传入将要在gallery中绘制的图片数据,(以byte[]类型的为例,因为我在存入sqlite以及从从网络下载下来的图片demo中都将其转成byte[]),同样我们使用

代码如下:
Bitmap originalImage = BitmapFactory.decodeByteArray(dishImages.get(i), 0, dishImages.get(i).length);

在这篇文章有较详细的说明:https://www.jb51.net/article/88588.htm

将byte[]类型的图片数据“还原”。byte[]类型的图片源数据保存在一个ArrayList当中。这样我们为动态的实现在gallery中添加图片提供数据来源。

在下面的activity中使用我们自定义的baseAdapter以及Gallery。实现上图显示的效果。

使用实例类

package com.nate.wte2;
import java.io.IOException;
import java.util.ArrayList;
import nate.InfoService.DishInfo;
import nate.InfoService.StoreInfoService;
import nate.InfoService.WhichChoice;
import nate.NetConnection.GetConnectionSock;
import nate.android.Service.GalleryFlow;
import nate.android.Service.ImageAdapter;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import com.nate.wte.LocalSql.StoresInfoDB;
publicclass DishMenuActivity extends Activity {
private ArrayList dishInfoList =new ArrayList();
private TextView dishName;
private RatingBar dishScores;
private TextView dishPrice;
//3:send the dish's whole info to fill the activity(send the comments of the dish)
privateint flag3 =3;
 WhichChoice choice3 =new WhichChoice(flag3);
private StoreInfoService storeInfo;
private ProgressDialog loadingDialog;
/**
  * handler handle the dialog dismission
*/
private Handler handler =new Handler(){
  @Override
publicvoid handleMessage(Message msg) {
   loadingDialog.dismiss();
//other operation
super.handleMessage(msg);
  }
 };
/**
  * thread to load the data from local database or from the server
  * @author Administrator
  *
*/
class Loading implements Runnable{
  @Override
publicvoid run() {
try {
//这儿的sleep将换成一个循环,知道某个条件满足时候才结束循环,让dialog终止
    Thread.sleep(1500);
    handler.sendEmptyMessage(0);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
/**
  * loading the items,start the thread to load
*/
publicvoid loadingItems(){
  loadingDialog = ProgressDialog.show(DishMenuActivity.this, "", "loading...");
  Thread t =new Thread(new Loading());
  t.start();
 }
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
  setContentView(R.layout.dishmenu_gallery);
  StoresInfoDB infoDB;
int dishInfoListLength;
  ArrayList dishImages =new ArrayList();
byte[] dishImage;
  dishName = (TextView)this.findViewById(R.id.dishName);
  dishPrice = (TextView)this.findViewById(R.id.dishPrice);
  dishScores = (RatingBar)this.findViewById(R.id.dishScores);
//得到intent中从Choices类中传过来的对象
  Intent intent = getIntent();
  Bundle bundle = intent.getBundleExtra("bundleData");
  storeInfo = (StoreInfoService)bundle.getSerializable("storeInfo");
  dishInfoList = (ArrayList)bundle.getSerializable("dishInfoList");
  System.out.println("look look the info received from Choices Activity");
for(int i =0; i  arg0, View arg1,
int arg2, long arg3) {
    String showName ="菜名 : "+ dishInfoList.get((int)arg3).getDishName() +"";
    dishName.setText(showName);
    dishScores.setRating(dishInfoList.get((int)arg3).getDishScores());
    dishPrice.setText("价格 : "+ dishInfoList.get((int)arg3).getPrice() +" 元\n\n\n");
   }
   @Override
publicvoid onNothingSelected(AdapterView<&#63;> arg0) {
   }
  });
  galleryFlow.setOnItemClickListener(new OnItemClickListener(){
  @Override
publicvoid onItemClick(AdapterView<&#63;> arg0, View arg1, int arg2,
long arg3) {
   loadingItems();
   DishInfo dishInfo = dishInfoList.get((int)arg3);
try {
    GetConnectionSock.fromClient.writeObject(choice3);
    System.out.println("send the flag 3 ");
    GetConnectionSock.fromClient.writeObject(dishInfo);
    System.out.println("send the name back to server");
    DishInfo dishComments = (DishInfo)GetConnectionSock.fromServer.readObject();
    System.out.println("recv the dish comments");
    dishInfo.setDishName(dishInfoList.get((int)arg3).getDishName());
    dishInfo.setDishComments(dishComments.getDishComments());
    System.out.println("full the dish info");
   } catch (IOException e) {
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   }
   Intent intent =new Intent();
   Bundle bundle =new Bundle();
   bundle.putSerializable("dishInfo",dishInfo);
   bundle.putSerializable("storeInfo",storeInfo);
   intent.putExtra("dishBundleData",bundle);
   intent.setClass(DishMenuActivity.this,DishInfoDynamic.class);
   Toast.makeText(DishMenuActivity.this, "进入评论此道菜",Toast.LENGTH_LONG).show();
   DishMenuActivity.this.startActivity(intent);
  }
  });
  galleryFlow.setAdapter(adapter); //注意这里
 }
}

在这个activity中跟本文相关的,也就是在galley中添加图片功能,只需注意上面代码中标注出来的部分代码即可,至于数据来源得到的方式都不一样,这里只要知道数据是一个ArrayList就行了。重要的是利用上面的MyGallery以及ImageAdapter,当然,通过简单的理解,很轻松的这两个类就能够在其他的工程中重用的

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android图形与图像处理技巧总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android多媒体操作技巧汇总(音频,视频,录音等)》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
author-avatar
林禎峰佩蓉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有