zoukankan      html  css  js  c++  java
  • Android基于GridView实现的翻牌游戏效果

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

      一、整体介绍 

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

      (1)目录结构

      

      (2)效果图

        

      二、详细介绍

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

      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:实在吝啬或是没有积分也没关系,请到这里下载,当然也希望你Star一下,或是Fork;

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

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

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

  • 相关阅读:
    扑克牌大小
    简单错误记录
    聊天室
    GMM的EM算法实现
    Spark SQL 源代码分析之 In-Memory Columnar Storage 之 in-memory query
    JSP简单练习-使用JDOM创建xml文件
    PowerDesigner使用教程
    setsockopt()使用方法(參数具体说明)
    SQL注入原理解说,非常不错!
    Offer是否具有法律效力?
  • 原文地址:https://www.cnblogs.com/page-of-Hyman/p/4715116.html
Copyright © 2011-2022 走看看