安卓自定义View----且看如何巧妙地实现一个类似于电视遥控板的环形按钮效果(上)

原创 2016年08月31日 10:59:06

本文力求用最简单的方式实现这样的一个效果,并辅以详细的文字说明。
老规矩,先看图:
这里写图片描述

一个点餐界面,6种菜品,意味着6个按钮,点击‘开始点餐’ 幕布上升效果,这个动画下篇再讲。这篇的重点是这个样式的布局怎么实现。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:text="你好!"
        android:textSize="20sp" />

    <ImageView
        android:id="@+id/split_ll"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/total1111111" >
    </ImageView>

    <com.example.opendor.TrapezoidImageButton
        android:id="@+id/telId1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/a"
        android:tag="telId1" />

    <com.example.opendor.TrapezoidImageButton
        android:id="@+id/telId2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/b"
        android:tag="telId12" />

    <com.example.opendor.TrapezoidImageButton
        android:id="@+id/telId3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/c"
        android:tag="telId3" />

    <com.example.opendor.TrapezoidImageButton
        android:id="@+id/telId4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/d"
        android:tag="telId4" />

    <com.example.opendor.TrapezoidImageButton
        android:id="@+id/telId5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/e"
        android:tag="telId5" />

    <com.example.opendor.TrapezoidImageButton
        android:id="@+id/telId6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/f"
        android:tag="telId6" />

    <Button
        android:id="@+id/bill"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:layout_above="@+id/clear"
        android:layout_marginBottom="20dp"
        android:background="@drawable/local_order"
        android:gravity="center"
        android:onClick="bill"
        android:textSize="20sp" />

    <Button
        android:id="@+id/clear"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="5dp"
        android:background="@drawable/clear_data"
        android:gravity="center"
        android:onClick="clear"
        android:textSize="20sp" />

    <Button
        android:id="@+id/order"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:layout_alignBaseline="@id/clear"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="20dp"
        android:background="@drawable/start_menu"
        android:gravity="center"
        android:onClick="order"
        android:textSize="20sp" />

</RelativeLayout>

可以看到,很简单的一个相对布局,一个textview,一个大背景的imageview,然后6个自定义的view,也就是图中的6个菜品按钮,最后3个button。

接下来,关键就是这个view是怎么写的呢?

其中只有两个方法:

    public boolean onTouchEvent(MotionEvent event) {
    if (isTouchPointInView(event.getX(),event.getY())||event.getAction() != MotionEvent.ACTION_DOWN){
        return super.onTouchEvent(event);
    }else{
        return false;
    }
    }

若点击事件发生在当前view上,则实现父类的ontouchEvent方法,若没有则返回false。了解事件传递机制的同学应该知道,安卓默认都是实现的super,也即为若是默认实现,则这个事件最终会向上传递到activiy,再响应onclick。

这儿不花篇幅去讲,若是想进一步了解的同学,我推荐一篇文章
http://www.jianshu.com/p/e99b5e8bd67b

主要是isTouchPointInView这个方法的实现:

 protected boolean isTouchPointInView(float localX, float localY){
  if(bitmap!=null){
        bitmap=null;
    }
    bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_4444);
    Canvas canvas = new Canvas(bitmap);
    draw(canvas);
    int x = (int)localX;
    int y = (int)localY;
    if (x < 0 || x >= getWidth())
        return false;
    if (y < 0 || y >= getHeight())
        return false;
    int pixel = bitmap.getPixel(x,y);
    if ((pixel&0xff000000) != 0){ 
        return true;
    }else{
        return false; 
    }
    }

首先在当前点击的这个图片的view上创建一个bitmap(16位的也可以,还省内存),然后以bitmap对象创建一个画布,准备将内容都绘制在bitmap上。

X,Y即为手指点击的位置坐标(默认从屏幕左上角向右为+X坐标,向下为+Y坐标),如果触摸位置不在当前画布上,则返回false。这儿返回false即为onTouchEvent也返回false,则不触发点击事件。

然后根据bitmap对象得到位图点击位置的像素值pixel,并与一个高8位为1的ARGB颜色进行与运算,得到的结果若不为0,则返回true,否则,返回false。

下来我详解一下上面加粗的这句话,

因为ff代表全1,0xff000000=1111 1111 0000 0000 0000 0000 0000 0000

且 0&0=0
0&1=0
1&1=1

所以后面24位,无论pixel是多少都是0
前面8位,只有在pixel高8位有1时才不是0,所以(pixel&0xff000000)只有当pixel的高8位全为0时才为0。
下来我们在看一下bitmap.getPixel(x,y)常见的返回值:
BLACK:-16777216
BLUE:-16776961
GRAY:-7829368
GREEN:-16711936
TRANSPARENT :0
WHITE:-1
YELLOW :-256

因此我们此处通过getPixel(x, y) ==0 来判断该像素是否为透明(TRANSPARENT )。
但是为什么要判断点击位置是否透明呢?
下来看一张图,这张图就是上面我们的6个菜品按钮的图片,相信你看了也会明白的。这里写图片描述
图中用红颜色的框出来的其实是透明的,只有“热菜那块不透明”。

那么总结一下,上面那一大块代码的意思就是说,在当前view上,若点到“热菜”这个区域上,即点击的位置不透明,则触发点击事件。其余不触发点击。

源码我上传到github上,欢迎下载,喜欢的给个star,嘿嘿。

https://github.com/qht1003077897/Android-The-ring-button.git

下篇再讲这个其中的动画实现。

版权声明:本文为博主原创文章,转载请注明出处。

android roundView(android 环形转盘按钮)

  • 2013年12月31日 15:20
  • 5KB
  • 下载

Android 圆形按钮实现

项目中用到的圆形按钮,做个半天,用sharp形式实现,代码如下:
  • cz_arel
  • cz_arel
  • 2014年07月01日 21:47
  • 33751

Android 同心圆的遥控器的自定义

自定义的遥控器 import android.content.Context; import android.graphics.Bitmap; import android.graphic...
  • qq_28280447
  • qq_28280447
  • 2016年07月29日 16:13
  • 702

android 同心圆水波纹的实现

android 同心圆水波纹的实现 activity_main.xml
  • zpf1871
  • zpf1871
  • 2016年06月19日 20:13
  • 594

使用 自定义布局 实现灵活的万能遥控器界面

大家好,这是我的第一篇文章
  • wl532882877
  • wl532882877
  • 2016年10月20日 11:19
  • 848

我也DIY一个Android遥控器-全部开源

记得宋宝华在「设备驱动开发详解」提出一个这样的理论「软件和硬件互相渗透对方的领地」,这次证明还是确实是这样,使用上层APP软件加上简单的更为简单的硬件设计就可以完成一个遥控器了。...
  • kangear
  • kangear
  • 2014年09月18日 17:58
  • 28593

RK平台Android4.4 添加一个新的遥控器支持以及添加特殊按键

瑞芯微平台 SDK:Android4.4 好久没写博客了,最近工作中需要在SDK中添加一个新的遥控器支持,由于自己对java代码比较头大,过程也是一波三折,整个流程其实分析下来并不难,这里做个简单...
  • coding__madman
  • coding__madman
  • 2016年10月23日 20:26
  • 3721

Android开发:教你开发TVBox应用时使用遥控器组合快捷键

当我们在开发Android机顶盒,也就是TVBox应用的时候,我们可能会需要隐藏某个功能,或者隐藏某个应用,通过遥控器上按动组合快捷键来打开隐藏的功能或者应用。打个比方,可能“工厂测试FactoryT...
  • Xiong_IT
  • Xiong_IT
  • 2015年03月12日 13:54
  • 2276

Android蓝牙遥控器(字符串形式)应用例程——bluetoothdemo/BluetoothUnv

  • 2016年08月04日 23:13
  • 4.26MB
  • 下载

安卓盒子开发之遥控器调试

1、首先我们要知道需要改动遥控器的配置文件, 盒子里面的遥控器配置文件一般是在/system/etc/remote.conf和/system/usr/keylayout/Vendor_0001_Pro...
  • yun382657988
  • yun382657988
  • 2016年05月27日 16:22
  • 2368
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:安卓自定义View----且看如何巧妙地实现一个类似于电视遥控板的环形按钮效果(上)
举报原因:
原因补充:

(最多只允许输入30个字)