Android仿Win8界面开发

本文将要模仿Win8界面的一个设计,一个一个的方块。方法很简单。这里自己把图片改改就可以成为自己想要的界面了。

1、首先来看看自定义的MyImageView:

package com.example.win8test;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView; 

@SuppressLint("HandlerLeak")
public class MyImageView extends ImageView {
 public static final int Rotate_Handler_Message_Start = 1;
 public static final int Rotate_Handler_Message_Turning = 2;
 public static final int Rotate_Handler_Message_Turned = 3;
 public static final int Rotate_Handler_Message_Reverse = 6; 

 public static final int Scale_Handler_Message_Start = 1;
 public static final int Scale_Handler_Message_Turning = 2;
 public static final int Scale_Handler_Message_Turned = 3;
 public static final int Scale_Handler_Message_Reverse = 6; 

 private boolean isAntiAlias = true;
 private boolean scaleOnly = false;
 private boolean isSizeChanged = false;
 private boolean isShowAnimation = true;
 private int rotateDegree = 10;
 private boolean isFirst = true;
 private float minScale = 0.95f;
 private int vWidth;
 private int vHeight;
 private boolean isAnimationFinish = true, isActionMove = false,
   isScale = false;
 private Camera camera;
 boolean XbigY = false;
 float RolateX = 0;
 float RolateY = 0;
 OnViewClick onclick = null; 

 public MyImageView(Context context) {
  super(context);
  camera = new Camera();
 } 

 public MyImageView(Context context, AttributeSet attrs) {
  super(context, attrs);
  camera = new Camera();
 } 

 public void SetAnimationOnOff(boolean oo) {
  isShowAnimation = oo;
 } 

 public void setOnClickIntent(OnViewClick onclick) {
  this.onclick = onclick;
 } 

 @SuppressLint("DrawAllocation")
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (isFirst) {
   isFirst = false;
   init();
  }
  canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
    | Paint.FILTER_BITMAP_FLAG));
 } 

 public void init() {
  vWidth = getWidth() - getPaddingLeft() - getPaddingRight();
  vHeight = getHeight() - getPaddingTop() - getPaddingBottom();
  Drawable drawable = getDrawable();
  BitmapDrawable bd = (BitmapDrawable) drawable;
  bd.setAntiAlias(isAntiAlias);
 } 

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  super.onTouchEvent(event);
  if (!isShowAnimation)
   return true; 

  switch (event.getAction() & MotionEvent.ACTION_MASK) {
  case MotionEvent.ACTION_DOWN:
   float X = event.getX();
   float Y = event.getY();
   RolateX = vWidth / 2 - X;
   RolateY = vHeight / 2 - Y;
   XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false; 

   isScale = X > vWidth / 3 && X < vWidth * 2 / 3 && Y > vHeight / 3
     && Y < vHeight * 2 / 3;
   isActionMove = false; 

   if (isScale) {
    if (isAnimationFinish && !isSizeChanged) {
     isSizeChanged = true;
     scale_handler.sendEmptyMessage(Scale_Handler_Message_Start);
    }
   } else {
    if (scaleOnly) {
     scale_handler.sendEmptyMessage(Scale_Handler_Message_Start);
    } else {
     rotate_Handler
       .sendEmptyMessage(Rotate_Handler_Message_Start);
    }
   }
   break;
  case MotionEvent.ACTION_MOVE:
   float x = event.getX();
   float y = event.getY();
   if (x > vWidth || y > vHeight || x < 0 || y < 0) {
    isActionMove = true;
   } else {
    isActionMove = false;
   } 

   break;
  case MotionEvent.ACTION_UP:
   if (isScale) {
    if (isSizeChanged)
     scale_handler
       .sendEmptyMessage(Scale_Handler_Message_Reverse);
   } else {
    rotate_Handler.sendEmptyMessage(Rotate_Handler_Message_Reverse);
   }
   break;
  }
  return true;
 } 

 public interface OnViewClick {
  public void onClick();
 } 

 @SuppressLint("HandlerLeak")
 private Handler rotate_Handler = new Handler() {
  private Matrix matrix = new Matrix();
  private float count = 0; 

  // private boolean clickGuolv = false;
  @Override
  public void handleMessage(Message msg) {
   super.handleMessage(msg);
   matrix.set(getImageMatrix());
   switch (msg.what) {
   case Rotate_Handler_Message_Start:
    count = 0;
    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
    rotate_Handler.sendEmptyMessage(Rotate_Handler_Message_Turning);
    break;
   case Rotate_Handler_Message_Turning:
    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
    count++;
    if (count < getDegree()) {
     rotate_Handler
       .sendEmptyMessage(Rotate_Handler_Message_Turning);
    } else {
     isAnimationFinish = true;
    }
    break;
   case Rotate_Handler_Message_Turned:
    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
    if (count > 0) {
     rotate_Handler
       .sendEmptyMessage(Rotate_Handler_Message_Turned);
    } else {
     isAnimationFinish = true;
     if (!isActionMove && onclick != null) {
      onclick.onClick();
     }
    }
    count--;
    count--;
    break;
   case Rotate_Handler_Message_Reverse:
    count = getDegree();
    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
    rotate_Handler.sendEmptyMessage(Rotate_Handler_Message_Turned);
    break;
   }
  }
 }; 

 private synchronized void beginRotate(Matrix matrix, float rotateX,
   float rotateY) {
  // Bitmap bm = getImageBitmap();
  int scaleX = (int) (vWidth * 0.5f);
  int scaleY = (int) (vHeight * 0.5f);
  camera.save();
  camera.rotateX(RolateY > 0 ? rotateY : -rotateY);
  camera.rotateY(RolateX < 0 ? rotateX : -rotateX);
  camera.getMatrix(matrix);
  camera.restore();
  // 控制中心点
  if (RolateX > 0 && rotateX != 0) {
   matrix.preTranslate(-vWidth, -scaleY);
   matrix.postTranslate(vWidth, scaleY);
  } else if (RolateY > 0 && rotateY != 0) {
   matrix.preTranslate(-scaleX, -vHeight);
   matrix.postTranslate(scaleX, vHeight);
  } else if (RolateX < 0 && rotateX != 0) {
   matrix.preTranslate(-0, -scaleY);
   matrix.postTranslate(0, scaleY);
  } else if (RolateY < 0 && rotateY != 0) {
   matrix.preTranslate(-scaleX, -0);
   matrix.postTranslate(scaleX, 0);
  }
  setImageMatrix(matrix);
 } 

 private Handler scale_handler = new Handler() {
  private Matrix matrix = new Matrix();
  private float s;
  int count = 0; 

  @Override
  public void handleMessage(Message msg) {
   super.handleMessage(msg);
   matrix.set(getImageMatrix());
   switch (msg.what) {
   case Scale_Handler_Message_Start:
    if (!isAnimationFinish) {
     return;
    } else {
     isAnimationFinish = false;
     isSizeChanged = true;
     count = 0;
     s = (float) Math.sqrt(Math.sqrt(minScale));
     beginScale(matrix, s);
     scale_handler
       .sendEmptyMessage(Scale_Handler_Message_Turning);
    }
    break;
   case Scale_Handler_Message_Turning:
    beginScale(matrix, s);
    if (count < 4) {
     scale_handler
       .sendEmptyMessage(Scale_Handler_Message_Turning);
    } else {
     isAnimationFinish = true;
     if (!isSizeChanged && !isActionMove && onclick != null) {
      onclick.onClick();
     }
    }
    count++;
    break;
   case Scale_Handler_Message_Reverse:
    if (!isAnimationFinish) {
     scale_handler
       .sendEmptyMessage(Scale_Handler_Message_Reverse);
    } else {
     isAnimationFinish = false;
     count = 0;
     s = (float) Math.sqrt(Math.sqrt(1.0f / minScale));
     beginScale(matrix, s);
     scale_handler
       .sendEmptyMessage(Scale_Handler_Message_Turning);
     isSizeChanged = false;
    }
    break;
   }
  }
 }; 

 private synchronized void beginScale(Matrix matrix, float scale) {
  int scaleX = (int) (vWidth * 0.5f);
  int scaleY = (int) (vHeight * 0.5f);
  matrix.postScale(scale, scale, scaleX, scaleY);
  setImageMatrix(matrix);
 } 

 public int getDegree() {
  return rotateDegree;
 } 

 public void setDegree(int degree) {
  rotateDegree = degree;
 } 

 public float getScale() {
  return minScale;
 } 

 public void setScale(float scale) {
  minScale = scale;
 }
}

2、下来,来看看布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@drawable/d"
 android:orientation="vertical"
 tools:context=".MainActivity" > 

 <LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="horizontal" > 

  <com.example.win8test.MyImageView
   android:id="@+id/MyImageView01"
   android:layout_width="108dp"
   android:layout_height="108dp"
   android:layout_margin="16dp"
   android:scaleType="matrix"
   android:src="@drawable/fen" /> 

  <com.example.win8test.MyImageView
   android:id="@+id/MyImageView02"
   android:layout_width="108dp"
   android:layout_height="108dp"
   android:layout_margin="16dp"
   android:scaleType="matrix"
   android:src="@drawable/fen" />
 </LinearLayout> 

 <LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="horizontal" > 

  <com.example.win8test.MyImageView
   android:id="@+id/MyImageView03"
   android:layout_width="108dp"
   android:layout_height="108dp"
   android:layout_margin="16dp"
   android:scaleType="matrix"
   android:src="@drawable/fen" /> 

  <com.example.win8test.MyImageView
   android:id="@+id/MyImageView04"
   android:layout_width="108dp"
   android:layout_height="108dp"
   android:layout_margin="16dp"
   android:scaleType="matrix"
   android:src="@drawable/fen" />
 </LinearLayout> 

 <LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="horizontal" > 

  <com.example.win8test.MyImageView
   android:id="@+id/MyImageView05"
   android:layout_width="108dp"
   android:layout_height="108dp"
   android:layout_margin="16dp"
   android:scaleType="matrix"
   android:src="@drawable/fen" /> 

  <com.example.win8test.MyImageView
   android:id="@+id/MyImageView06"
   android:layout_width="108dp"
   android:layout_height="108dp"
   android:layout_margin="16dp"
   android:scaleType="matrix"
   android:src="@drawable/fen" />
 </LinearLayout> 

</LinearLayout> 

3、上面的图片按钮的用法,这里只给一张图片按钮添加了事件:

MyImageView image_3D_1 = (MyImageView)findViewById(R.id.MyImageView01);
  image_3D_1.setOnClickIntent(new MyImageView.OnViewClick() {
  @Override
  public void onClick() {
   Toast.makeText(MainActivity.this, "clicked", 100)
     .show();
  }
 }); 

4、效果
手指按在中间是缩小,手指按在边上是有角度的卷动

手指一直按着的时候,被按下的那个图像变小,并且手指一直按着移动,此时其它图片按钮不响应

希望本文所述对大家学习Android软件编程有所帮助。

(0)

相关推荐

  • Android仿Win8的metro的UI界面(上)

    手机下载了一些APP,发现现在仿win8的主界面越来越多,在大家见惯了类GridView或者类Tab后,给人一种耳目一新的感觉.今天在eoe上偶然发现已经有人实现了这个功能的源码(地址:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=327557),马上下载跑了一下,效果很炫,但是有些bug,比如点击速度特别快时图像会被放大,以及点击时会触发两次点击事件. 本例子基于eoe中这位大神的实现,做了一些简化,和bug的修复. 效果: 首先

  • Android Metro菜单实现思路及代码

    今天继续说一下安卓的菜单,之前介绍了:相信大家对于Metro风格并不陌生,下面就在安卓平台上实现一下这个效果,如图:  实现思路: 利用动画来实现移动的效果,使用的是TranslateAnimation这个方法.先看一下布局文件: activity_main.xml 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://s

  • Android开发 -- UI界面之threme和style

    Android系统的themes.xml和style.xml(位于\base\core\res\res\values\)包含了很多系统定义好的style,建议在里面挑个合适的,然后再继承修改. 一.threme android中的主题一般用于窗体级别的,用于改变窗体样式 1.Theme: 它的意思为默认状态,即如果theme这里不填任何属性的时候,默认为Theme 1.1.Theme_NoDisplay 它的意思为任何都不显示.比较适用于只是运行了activity,但未显示任何东西. 1.2.T

  • 解析Android开发优化之:对界面UI的优化详解(三)

    有时候,我们的页面中可能会包含一些布局,这些布局默认是隐藏的,当用户触发了一定的操作之后,隐藏的布局才会显示出来.比如,我们有一个Activity用来显示好友的列表,当用户点击Menu中的"导入"以后,在当前的Activity中才会显示出一个导入好友的布局界面.从需求的角度来说,这个导入功能,一般情况下用户是不使用的.即大部分时候,导入好友的布局都不会显示出来.这个时候,就可以使用延迟加载的功能. ViewStub是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文

  • Android界面效果UI开发资料汇总(附资料包)

    简介: Android界面效果UI开发资料汇总 1. Android_UI开发专题.rar 2. android界面效果全汇总.rar 对于Android平台的资源类android.content.res.Resources可能很多网友比较陌生,一起来看看SDK上是怎么介绍的吧,Contains classes for accessing application resources, such as raw asset files, colors, drawables, media or oth

  • 解析Android开发优化之:对界面UI的优化详解(二)

    如果我们在每个xml文件中都把相同的布局都重写一遍,一个是代码冗余,可读性很差:另一个是修改起来比较麻烦,对后期的修改和维护非常不利.所以,一般情况下,我们需要把相同布局的代码单独写成一个模块,然后在用到的时候,可以通过<include /> 标签来重用layout的代码. 常见的,有的应用在最上方会有一个标题栏.类似下图所示. 图 标题栏的示例 如果项目中大部分Activity的布局都包含这样的标题栏,就可以把标题栏的布局单独写成一个xml文件. 复制代码 代码如下: <Relativ

  • Android 使用XML做动画UI的深入解析

    效果: http://www.56.com/u82/v_OTM4MDk5MTk.html第一步: 创建anim文件夹放置动画xml文件在res文件夹下,创建一个anim的子文件夹. 第二步: 加载动画接着在Activity创建一个Animation类,然后使用AnimationUtils类加载动画xml 复制代码 代码如下: Animation animFadein; @Overrideprotected void onCreate(Bundle savedInstanceState) { su

  • Android 在其他线程中更新UI线程的解决方法

    方法一:Activity.runOnUiThread(Runnable )(经验之道: 这个最好用, 凡是要刷新页面的地方,Activity.runOnUiThread( new Runnable()  { public void run(){更新UI}}); 方法二:子线程调用Handler的sendMessage(message)发送事件. 复制代码 代码如下: mHandler = new Handler() {     @Override     public void handleMe

  • 解析Android开发优化之:对界面UI的优化详解(一)

    通常,在这个页面中会用到很多控件,控件会用到很多的资源.Android系统本身有很多的资源,包括各种各样的字符串.图片.动画.样式和布局等等,这些都可以在应用程序中直接使用.这样做的好处很多,既可以减少内存的使用,又可以减少部分工作量,也可以缩减程序安装包的大小. 下面从几个方面来介绍如何利用系统资源. 1)利用系统定义的id 比如我们有一个定义ListView的xml文件,一般的,我们会写类似下面的代码片段. 复制代码 代码如下: <ListView android:id="@+id/m

  • Android仿Win8界面开发

    本文将要模仿Win8界面的一个设计,一个一个的方块.方法很简单.这里自己把图片改改就可以成为自己想要的界面了. 1.首先来看看自定义的MyImageView: package com.example.win8test; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Camera; import android.graphics.Canvas; impo

  • Android WebView 应用界面开发教程

    WebView组件本身就是一个浏览器实现,Android5.0增强的WebView基于Chromium M37,直接支持WebRTC.WebAudio.WebGL.开发者可以直接在WebView中使用聚合(Polymer)和Material设计. 一.WebView浏览网页(加载线上URL) WebView提供了很多方法执行浏览器操作,常用方法如下: void goBack():后退 void goForward():前进. void goBackOrForward(int step):step

  • Android仿微信界面的导航以及右上角菜单栏效果

    下面是安卓开发仿微信界面的代码. 分为3步, 第一步是界面的编写; 第二步是导航界面; 第三步是右上角菜单栏. 开始第一步前先预览一下效果. 第一步,界面. 界面的思路是利用ViewPager+Fragment实现,所以activity_main.xml中添加一个ViewPager.顶部和底部include的顶部栏和底部栏后面再说. MainActivity的界面activity_main.xml: <?xml version="1.0" encoding="utf-8

  • Android miniTwitter登录界面开发实例

    本文要演示的Android开发实例是如何完成一个Android中的miniTwitter登录界面,下面将分步骤讲解怎样实现图中的界面效果,让大家都能轻松的做出美观的登录界面. 先贴上最终要完成的效果图: miniTwitter登录界面的布局分析 首先由界面图分析布局,基本可以分为三个部分,下面分别讲解每个部分. 第一部分是一个带渐变色背景的LinearLayout布局,关于背景渐变色就不再贴代码了,效果如下图所示: 第二部分,红色线区域内,包括1,2,3,4 如图所示: 红色的1表示的是一个带圆

  • Android仿支付宝微信支付密码界面弹窗封装dialog

    一,功能效果 二,实现过程 1,先写xml文件:dialog_keyboard.xml 注意事项 (1),密码部分用的是一个线性布局中6个TextView,并设置android:inputType="numberPassword",外框是用的一个有stroke属性的shape, (2),1-9数字是用的recycleview ,每个item的底部和右边有1dp的黑线,填充后形成分割线. (3),recycleview 要设置属性  android:overScrollMode=&quo

  • Android 仿微信图像拍摄和选择界面功能(代码分享)

    插件运行后的画面如下: 下面这张图对图像进行筛选,根据照片产生的源头分(QQ和微信和相机) 点击某文件夹后,可以查看该文件夹下包含的所有的图片 图片选择界面 选中后就跳到已经选择界面的窗口,并且可以对该吃图片上传进行简要的描述 首先我想说明的是这个插件默认是不进行图片筛选的,打开app后会有几十个文件夹,但是个人认为开发中常用的图片基本都来自于QQ中拍摄的照片,微信中拍摄的照片,以及相机直接拍摄的照片,因此我对这个插件进行过滤以及文件夹名称的更改,具体做法,主要是对AlbumHelper类bui

  • Android仿zaker用手向上推动的特效开发【推动门效果】(附demo源码下载)

    本文实例讲述了Android仿zaker用手向上推动的特效开发.分享给大家供大家参考,具体如下: 最近在商店下载了zaker ,闲暇时拿来看看新闻!发现每次打开软件进入主界面时有个界面,需要你把它往上滑到一定距离才能进入到主界面.每次进入软件时它的背景可能不一样,在往上拨的时候你会看见主界面,好似向上推的门一样!打开它你就可以看到外面的世界.与窗帘有点不同的是在你没有拉开足够距离时,它会俏皮的关闭自己不让你看到外面的美景. 说这么多想像起来挺模糊的,那让我们看看实际效果图,我现在打开zaker截

  • android 仿ios数字密码解锁界面的实例

    如下所示: 每个Android开发人员都知道,现在android的解锁最常用的就是九宫格解锁,ios的解锁常用的是数字密码解锁.而我们在开发工程中,很多时候,都需要android和ios进行结合.有的时候我们就需要把我们的解锁界面弄成像ios一样的数字键盘. 这里我就实现了一个仿照ios的数字密码解锁界面.在这里我采用了两种方式来实现,第一种就是使用自定义控件的形式,第二种就是使用我们的布局来实现的.这里我就着重讲一下使用自定义控件形式实现的思路.至于使用布局文件实现的方式,我就不进行具体的讲解

  • Android仿通话来电界面效果

    Android仿通话来电界面,供大家参考,具体内容如下 简介:开发中需要模拟来电时的通话界面,仿照来电界面实现来电时播放铃声,界面通过动画模拟来电动效. 效果图: 自定义图片背景,图片由小变大的动态效果. shap_circle.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/androi

随机推荐