转载

Android基于GridView实现的翻牌游戏效果

好久没有写博客了,上一篇博文距现在都有七个多月了,实在是惭愧。但是这段时间仍然是在忙于项目或是自我充电。这几天实现了一个基于GridView的翻牌动画效果,这里就将其整理出来同各位分享。

一、整体介绍

GridView设置15个Item(5*3),刚好满屏显示(没有ScrollBar),没有点击某个Item前可以使用摇一摇功能对GridView中的图片进行切换,点击某个Item时对应的图片放大,然后实现“翻牌”效果,并将该Item中显示的图片切换为对应的文字。随后所有其他的Item也自动实现翻牌效果。

(1)目录结构

Android基于GridView实现的翻牌游戏效果

(2)效果图

Android基于GridView实现的翻牌游戏效果 Android基于GridView实现的翻牌游戏效果

二、详细介绍

按上面的目录结构从上致下

1、GridAdapter 继承至 BaseAdapter

重点代码:

(1)自定义的一个Item touch事件监听接口

1  public interface  OnItemTouchedListener { 2         public boolean onItemTouch (View v, MotionEvent event, int position); 3  }

(2)设置OnItemTouchedListener

1  public void setOnItemTouchedListener(OnItemTouchedListener onItemTouchedListener) { 2         this.listener = onItemTouchedListener; 3  }

(3)getView()函数中动态设置 Item的高、宽加载网络图片为每个Item设置OnTouchListener

1 @Override  2     public View getView(final int position, View convertView, ViewGroup parent) {  3         LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  4         convertView = inflater.inflate(R.layout.grid_item, parent, false);  5   6         LayoutParams layoutParams = convertView.getLayoutParams();  7         layoutParams.width = viewWidth;  8         layoutParams.height = viewHeight;  9         convertView.setLayoutParams(layoutParams); 10         ImageView imageView = (ImageView) convertView.findViewById(R.id.grid_image); 11  12         DisplayImageOptions options = new DisplayImageOptions.Builder()// 13                 .cacheInMemory(true)// 14                 .cacheOnDisc(true)// 15                 .bitmapConfig(Config.RGB_565)// 16                 .build(); 17         ImageLoader.getInstance().displayImage(urlArray.get(position), 18                 imageView, options); 19         convertView.setOnTouchListener(new OnTouchListener() { 20  21             @Override 22             public boolean onTouch(View v, MotionEvent event) { 23  24                 return listener.onItemTouch(v, event, position); 25             } 26         }); 27  28         return convertView; 29     }

2、RotateAnimation

参考于github上jianghejie的 3DNumberRotate 项目中的NumberRotate3DAnimation类,基于Camera实现数字3D翻转动画。

3、自定义的Application类

项目中使用了 universal-image-loader 加载网络图片,在这里对 ImageLoader进行初始化:

 1 private void initImageLoader() {  2   3         DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() //  4                 .showImageForEmptyUri(R.mipmap.empty_img) //  5                 .showImageOnFail(R.mipmap.empty_img) //  6                 .cacheInMemory(true) //  7                 .cacheOnDisc(true) //  8                 .build();//  9  10         File cacheDir = StorageUtils.getCacheDirectory(getApplicationContext()); 11         ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder( 12                 getApplicationContext())// 13                 .memoryCache(new LruMemoryCache(5 * 1024 * 1024))// 14                 .memoryCacheSize(10 * 1024 * 1024)// 15                 .defaultDisplayImageOptions(defaultOptions)// 16                 .discCache(new UnlimitedDiscCache(cacheDir))// 17                 .discCacheFileNameGenerator(new HashCodeFileNameGenerator())// 18                 .build(); 19         ImageLoader.getInstance().init(config); 20     }

4、util包中的几个工具类

(1)Constants:放一些常量,这里我存放的是GridView中网络图片的路径;

(2)DisplayUtil:这是关于显示的一个工具类,包括获取屏幕高宽、dp转px等功能;

(3)ItemCenterMeasure:这个类是设计用来根据GridView高宽计算Item尺寸的,其实可以省去,或者直接归并到DisplayUtil中;

5、MainActivity中功能较多写的比较杂乱

主要代码:

(1)Adapter设置自定义的 OnItemTouchedListener

 1  mAdapter.setOnItemTouchedListener(new GridAdapter.OnItemTouchedListener() {  2   3             @Override  4             public boolean onItemTouch(View v, MotionEvent event, int position) {  5                 mView = v;  6                 currentPos = position;  7                 if(event.getAction() == MotionEvent.ACTION_DOWN){  8                     if (isClicked) {  9                         Toast toast = Toast.makeText(context, getString(R.string.warning), 10                                 Toast.LENGTH_SHORT); 11                         toast.setGravity(Gravity.CENTER, 0, 0); 12                         toast.show(); 13                         return false; 14                     } else{ 15                         //play sound 16                         soundPool.play(music, 1, 1, 0, 0, 1); 17                         //trigger zoom animation on items 18                         ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.1f, 1.0f, 1.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 19                         scaleAnimation.setDuration(500); 20                         AnimationSet animationSet = new AnimationSet(true); 21                         animationSet.addAnimation(scaleAnimation); 22                         animationSet.setFillAfter(true); 23                         animationSet.setAnimationListener(new Animation.AnimationListener() { 24  25                             @Override 26                             public void onAnimationStart(Animation animation) { 27  28                             } 29  30                             @Override 31                             public void onAnimationRepeat(Animation animation) { 32  33                             } 34  35                             @Override 36                             public void onAnimationEnd(Animation animation) { 37                                 enableRefreshFirst = true; 38                                 RotateAnimation rotateAnim = null; 39  40                                 float cX = mView.getWidth() / 2.0f; 41                                 float cY = mView.getHeight() / 2.0f; 42                                 rotateAnim = new RotateAnimation(cX, cY); 43  44                                 if (rotateAnim != null) { 45                                     rotateAnim.setInterpolatedTimeListener(MainActivity.this, mView); 46                                     rotateAnim.setFillAfter(true); 47                                     rotateAnim.setAnimationListener(new Animation.AnimationListener() { 48  49                                         @Override 50                                         public void onAnimationStart(Animation animation) { 51  52                                         } 53  54                                         @Override 55                                         public void onAnimationRepeat(Animation animation) { 56  57                                         } 58  59                                         @Override 60                                         public void onAnimationEnd(Animation animation) { 61                                             handler.postDelayed(new Runnable() { 62  63                                                 @Override 64                                                 public void run() { 65                                                     otherItemRotate(); 66                                                 } 67                                             }, 500); 68                                         } 69                                     }); 70                                     mView.startAnimation(rotateAnim); 71  72                                 } 73  74                                 isClicked = true; 75                             } 76                         }); 77                         v.startAnimation(animationSet); 78                     } 79                 } 80  81                 return false; 82             } 83         });

(2)动态创建一个TextView,并算出GridView的高、宽

其中计算GridView的高度这一句(DisplayUtil.SCREEN_HEIGHT_PIXELS - DisplayUtil.dp2px(16) * 2 - tvBmHeight - 80)在我设备(分辨率:1920*1080)上要减去80px才能使所有的Item整好全部显示出来,不知道为什么,如果不减去80px,GridViw 中的最后一行Item将会显示不完全也就是说要通过滑动ScrollBar才能看全。这一点还望大神能给予指点。

 1 private void createCRTextView() {  2         LinearLayout ll = (LinearLayout) findViewById(R.id.logo_ly);  3         tvBm = new TextView(context);  4         tvBm.setText(getResources().getString(R.string.logo));  5         tvBm.setTextAppearance(context, R.style.logoTextView);  6         LinearLayout.LayoutParams crParams = new LinearLayout.LayoutParams(GridLayout.LayoutParams.WRAP_CONTENT, GridLayout.LayoutParams.WRAP_CONTENT);  7         crParams.topMargin = 5;  8         crParams.bottomMargin = 10;  9         crParams.gravity = Gravity.CENTER; 10         tvBm.setLayoutParams(crParams); 11  12         tvBm.setOnClickListener(new View.OnClickListener() { 13  14             @Override 15             public void onClick(View v) { 16                 ScaleAnimation  scaleAnim = new ScaleAnimation(1.0f, 1.2f, 1.0f, 1.2f, 17                         Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 18                 scaleAnim.setDuration(500); 19                 scaleAnim.setFillAfter(false); 20                 tvBm.startAnimation(scaleAnim); 21             } 22         }); 23  24         ll.addView(tvBm); 25         int tvBmHeight = crParams.height + 5 + 10; 26  27  28         gridWidthPix = DisplayUtil.SCREEN_WIDTH_PIXELS - DisplayUtil.dp2px(16) * 2; 29         //I am not sure why the right of next equality should minus 80px to display all items in the gridview without scrollbar in my devices (1       920*1080), 30         //this may make a bad adaption for various devices with different resolution ratio 31         gridHeightPix = DisplayUtil.SCREEN_HEIGHT_PIXELS - DisplayUtil.dp2px(16) * 2 - tvBmHeight - 80; 32  33  34     }

(3)摇一摇触发的时候更新GridView中的图片路径

 @Override public void onSensorChanged(SensorEvent event) {  int sensorType = event.sensor.getType();  float[] values = event.values;  if (sensorType == Sensor.TYPE_ACCELEROMETER) {   //values[0] X axis acceleration;values[1] Y axis acceleration;values[2] Z axis acceleration   if (Math.abs(values[0]) > 17 || Math.abs(values[1]) > 17 || Math.abs(values[2]) > 17) {    if (!isClicked) {     vibrator.vibrate(500);     mAdapter.setUrls(Constants.getUrls(2));     mGridView.invalidate();    }   }  } } 

6、还有一个自定义的GridView,实现禁止滑动

重写dispatchTouchEvent方法

    @Override     public boolean dispatchTouchEvent(MotionEvent ev) {         if (ev.getAction() == MotionEvent.ACTION_MOVE) {             return true;//禁止gridview滑动         }         return super.dispatchTouchEvent(ev);     }

7、布局文件这里就不给予说明了,很简单明了的,需要参考的可以直接下源码看。

源码下载链接:

(1)CSDN:需要1个下载积分,积分有点缺您要是愿意打赏请点 这里下载

(2)GitHub:实在吝啬或是没有积分也没关系,请到 这里下载 ,当然也希望你Start一下,或是Fork;

好了到此算是写完了,如果对您有用,劳烦您点个赞或是分享一下;如果您对代码有一些建议,期待您在评论处给予指正。

最近状态有点不佳,送给自己以及各位一句话共勉:

业精于勤 荒于嬉;行成于思 毁于随

正文到此结束
Loading...