Android自定义View系列(二)——打造一个仿2K游戏摇杆

本文介绍了如何在Android中自定义一个仿2K游戏的摇杆View,涵盖从XML属性定义到事件处理和监听器的构建。通过数学知识和三角函数的应用,实现摇杆的用户交互及数据回调功能。文章详细解析了摇杆的测量绘制、触摸事件处理以及监听器构造的实现过程。
摘要由CSDN通过智能技术生成

写作原因:Android进阶过程中有一个绕不开的话题——自定义View。这一块是安卓程序员更好地实现功能自主化必须迈出的一步。下面这个系列博主将通过实现几个例子来认识安卓自定义View的方法。从自定义View到自定义ViewGroup,View事件处理再到View深入分析(这一章如果水平未到位可能今后再补充),其中会涉及一些小的知识,包括Canvas的使用、动画等等。这是本系列的第二章,博主将通过定制一个摇杆的实例巩固上章的知识,并引入自定义View中实现用户交互和数据回调两个方面的功能。此外在本章中我们将看到数学知识(尤其是三角函数)在自定义View中的重要作用(这也是本例的一个难点),下面开始解放大脑和双手吧。

最终效果

本例的最终效果如下:

效果

这就是本例的最终效果,我们将实现一个虚拟游戏方向摇杆,模拟摇杆操作。此外我们将为它写一个监听器实现摇动方向和速度等数据返回(本例中只实现了监听部分代码,数据读者可以自行加上)。

基本思路

首先依然是上一篇所讲述的那几个步骤,包括自定义XML属性,引入属性,测量和绘制几个部分(没看过上一篇文章的点击博客阅读或者查看博主的简书),除了这几个部分外我们还需要重写onTouchEvent()方法进行View事件处理和利用回调写好监听器。整体思路就是这样,看起来不难,实际操作起来陷阱多多。

具体实现

前期准备

新建value/attrs.xml,在XML中声明并引入以下属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="InnerColor" format="color"/>
    <attr name="OuterColor" format="color"/>
    <declare-styleable name="NavController">
        <attr name="InnerColor" />
        <attr name="OuterColor"/>
    </declare-styleable>
</resources>

这次我们只需要两个属性,小圆颜色和大圆颜色。然后新建一个java文件,继承View命名为NavController,在java中重写构造方法并且将XML属性导入,新建画笔对象,为之设置好属性。关键代码如下:

    public NavController(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray ta = getResources().obtainAttributes(attrs,R.styleable.NavController);
        innerColor = ta.getColor(R.styleable.NavController_InnerColor,INNER_COLOR_DEFAULT);
        outerColor = ta.getColor(R.styleable.NavController_OuterColor,OUTER_COLOR_DEFAULT);
        ta.recycle();
        OUTER_WIDTH_SIZE = dip2px(context,125.0f);
        OUTER_HEIGHT_SIZE = dip2px(context,125.0f);
        outerPaint = new Paint();
        innerPaint = new Paint();
        outerPaint.setColor(outerColor);
        outerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        innerPaint.setColor(innerColor);
        innerPaint.setStyle(Paint.Style.FILL_AND_STROKE);

上面的OUTER_WIDTH_SIZE和OUTER_HEIGHT_SIZE分别是大圆在没有设置具体值下的默认大小,我们使用dip2px()方法将我们熟练掌握的dip转化为java逻辑唯一承认的px单位,具体实现:

public static int dip2px(Context context, float dpValue){
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue*scale +0.5f);
    }

这样就做好了前期准备工作,由于上篇讲述过关于onMeasure和onDraw的相关理解和用法,这里就简单阐述,将这两块写在同一个部分。

测量绘制

测量时我们分别对三种模式下的尺寸进行不同的处理,分别是返回父View给的值加上padding值(EXACTLY),返回大圆的宽高(UNSPECIFIED)和返回大圆宽高与父View允许最大值之间的最小值(AT_MOST)。然后回调onSizeChanged()中取出实际宽高值,利用该值进行View绘制。onDraw中主要是确定了两个圆的半径(大圆半径为去除padding的宽高一半下四种情况的最小值,参照代码看这句话。小圆半径为大圆的一半)和绘制了两个圆。此外小圆的中心点我们现在onSizeChanged中进行了赋值,注意小圆中心点坐标值的改变是本例的关键,通过改变它来实现效果。这样我们就把View的显示区域和View的基本形状定义完毕。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width,height);
    }

    private int measureWidth(int widthMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthVal = MeasureSpec.getSize(widthMeasureSpec);
        //处理三种模式
        
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值