热门标签 | 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程序设计有所帮助。


推荐阅读
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • SQL中UPDATE SET FROM语句的使用方法及应用场景
    本文详细介绍了SQL中UPDATE SET FROM语句的使用方法,通过具体示例展示了如何利用该语句高效地更新多表关联数据。适合数据库管理员和开发人员参考。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 精选30本C# ASP.NET SQL中文PDF电子书合集
    欢迎订阅我们的技术博客,获取更多关于C#、ASP.NET和SQL的最新资讯和资源。 ... [详细]
  • 本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
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社区 版权所有