1. android自定义控件 怎样设置内边距
自定义控件,实质是重写某个控件的方法和属性,同时也继承父控件的方法和属性,比如内边距,设置自定义控件内边距的方法: 在xml布局文件中使用标签: android:padding="", android:paddingLeft="", android:paddingTop="", android:bottom="" 如果想要设置外边距,使用下面标签: android:layout_margin="",android:layout_marginLeft,android:layout_marginRight,android:layout_marginTop,android:layout_marginBottom
2. Android自定义控件之可平移、缩放、旋转图片控件
先上效果图
单点拖动图片对图片进行平移操作。双手缩放图片大小和旋转图片到一定的角度。图片缩放的时候 不能大于最大的缩放因子和小于最小的缩放因子。大于最大缩放因子或者小于最小缩放因子需要对图像进行回弹。图片旋转的角度只能为90度的倍数,不满足90度要进行回弹。图片回弹要一个渐变的效果。
大体思路: 首先,Android中提供了Matrix类可以对图像进行处理。其次,要显示一张图片最容易想到的就是ImageView。回弹要求渐变的过程,可以通过属性动画进行设置。所以大体的思路是:继承ImageView,重写onTouchEvent()方法,判断事件类型,在对应的事件使用Matrix对图像进行变换。
Matrix是一个已经封装好的矩阵,最重要的作用就是对坐标点进行变换。
举个栗子:
1.某个点(x0,y0,1)通过单位矩阵E映射得到的点还是(x0,y0,1)。
3.点(x0,y0,1)通过矩阵T映射得到的点就会做如下的变换
可以看到点(x0,y0,1)经过T矩阵在x轴方向上平移了dx,在y轴方向上平移了dy。
通过以上的变换可以得到具体的思路: 我们维护一个图像对应的矩阵mCurrentMatrix,该矩阵主要是对ImageView中的图像的各个点进行映射。ImageView在容器位置摆放完成之后,置mCurrentMatrix矩阵为单位矩阵。当onTouchEvent()方法中触发单点触控并且手指进行平移的时候,调用矩阵mCurrentMatrix的postTranslate(dx,dy),对mCurrentMatrix进行变换。当手指抬起,利用变换结束后的矩阵对图像的各个点进行映射,从而得到平移变换后的图像。同理可得,在两只手指进行缩放旋转的时候,我们对矩阵mCurrentMatrix进行各种变换,当缩放旋转的事件结束再利用变换完的矩阵去映射图像的各个点,从而得到缩放、旋转后的图像。
安卓自定义View进阶 - Matrix原理
安卓自定义View进阶 - Matrix详解
首先理清事件的逻辑:
初始化图像大小和位置
缩放图像大小和控件大小自适应,平移图像中心和控件中心重合
onTouchEvent()函数
平移操作
将图像对应的矩阵进行变换。
缩放操作
mBoundRectF为记录图像边界的矩形。缩放的时候选取图像的中心进行缩放。
旋转操作
旋转的时候旋转的旋转中心也是图像的中心
图像中各个点的映射
调用ImageView的setImageMatrix(Matrix matrix)会让ImageView根据设置的matrix去重新绘制图像。
更新图像的矩形边界
获得图像的矩形,并根据矩阵映射矩形各个点的坐标。
缩放回弹
旋转回弹
一些计算方法
要求图像的变换是一个渐变的过程,很容易想到的就是属性动画。因为属性动画本身就是对值进行不断set的过程。而我们维护的矩阵也是一个值,所以很自然可以想到,如果得到回弹之前的矩阵的值以及回弹之后矩阵的值,就可以根据动画监听器中动画当前的系数值去改变矩阵的值。
对animator对象设置完监听器之后,就可以在手指抬起的时候调用属性动画的start()方法开启动画。
自定义可平移、缩放、旋转的控件主要点有两个方面:一是onTouchEvent()中判断平移、旋转、缩放的触发条件,平移位移量、缩放比例因子、旋转角度的计算。二是Matrix矩阵的应用。
3. Tasker beta如何实现Android 11电源菜单控件的自定义图块添加
Tasker beta 5.9.4及以上版本可以通过以下步骤实现Android 11电源菜单控件的自定义图块添加:
确保Tasker版本:
进入Tasker设置:
创建或选择任务:
自定义电源菜单图块:
保存并应用设置:
进一步定制:
通过以上步骤,你就可以在Android 11设备上,通过Tasker beta实现电源菜单控件的自定义图块添加了。
4. 【Android】自定义Spinner控件及其使用
一、简单使用
1. 写选项值
在res/values/文件夹下新建一个 arrays.xml 文件:
2. 在界面文件中添加Spinner控件
activity_main.xml 文件:
2.1 dropdown模式
效果:
2.2 dialog模式
效果:
二、自定义dropdown样式
1. 修改点击样式和下拉框样式
在res/drawable/文件夹下新建两个文件:
(1)shape_for_custom_spinner.xml 文件(用来定义下拉框的样式):
(2)selector_for_custom_spinner文件(用来定义Spinner控件本身的样式,带选择器,有点击效果):
在界面文件中的Spinner控件中引用它们:
效果:
2. 增加下划线
在res/values/文件夹下新建一个style.xml文件:
说明: (1)customTheme——自定义主题样式,引用它自定义下划线才能正常显示。 (2)customSpinnerStyle——自定义的Spinner样式,和上面的主题样式一样在界面文件中引用。 (3)android:divider——分割线颜色。 (4)android:dividerHeight——分割线宽度。
在界面文件中的Spinner控件中引用它:
效果:
三、动态配置Spinner选项
1. 删除界面文件中引入的字符串组
即,删除这一行:
2. 增加一个自定义的layout文件来配置列表样式
在res/layout/文件夹下新建一个item_for_custom_spinner.xml文件:
3. 在java文件中对Spinner控件进行配置
MainActivity.java文件:
说明: 不想自己自定义列表样式可以选择直接使用Android自带的support_simple_spinner_dropdown_item 效果:
四、Spinner选择事件
1. 增加一个简单的选择监听器
可以发现有两个问题: (1)初始化监听器的时候事件被调用了。 (2)重复点击同一选项事情不会被重复调用。
2. 不希望监听器动作初始化时就被调用
办法很简单,就是定义一个flag用来确认监听器是否是第一次被调用,是则忽略它:
这样一来,界面初始化时就不会出现监听器动作被执行了一次的情况了。
3. 不希望重复点击同一选项时没有动作
需要重写Spinner控件的部分代码。
(1)在java/com.example.myapplication/文件夹下新建一个ReSpinner.java文件:
(2)替换掉界面文件中的控件根名称,其他什么都不用动: 将
改为
这样一来,重复点击同一事件,也能正常多次触发监听器动作了。
五、自定义dialog样式
经过上面的修改,基本已经完成了对dropdown模式下的样式自定义和监听器动作自定义了,将spinnerMode改回dialog,增加一个prompt标签,增加dialog的标题:
(1)先在res/values/strings.xml文件中定义一个标题(必须步骤):
(2)再在边界文件中引用它:
5. Android 自定义控件 layout
Android 绘制流程
View :View主要执行layout方法,使用 serFrame 方法来设置本身 View 的四个顶点的位置,确定View本身的位置。
ViewGroup :ViewGroup主要执行onLayout方法,递归遍历所有子View,确定子View的位置。
我们来看ViewRootImpl中的 performLayout() 方法
看到这里,那host.getMeasuredWidth() / host.getMeasuredHeight()是什么?它是直接调用View中的方法,其实就是经过measure后的DecorView的测量宽度和高度。在 Android 自定义控件 measure 中有说明。
2.3.2.1 我们先来看ViewGroup中的 layout() 方法
ViewGroup里面的layout最终会调入到父类View中的layout,View的layout后面讲解。这里可以先告诉大家,最终会调用View的onLayout方法,而ViewGroup的onLayout是抽象方法,所以它的子类LinearLayout必须要实现。
2.3.2.2 我们再来看LinearLayout中的 onLayout() 方法。
2.3.2.3 挑一个纵向的吧,我们再来看LinearLayout中的 layoutVertical() 方法。
2.3.2.4 我们再来看LinearLayout中的 setChildFrame() 方法。
又一次回到了View的layout方法,接下来就看View分发的layout。
我们先来看View中的 layout() 方法。
我们先来看View中的 onLayout() 方法。
空空如也,其实View的布局由父容器决定,所以空实现是正常的,当然也可以在自定义View中进行更改。
《Android 视图模块 全家桶》
Android开发之自定义控件(二)---onLayout详解
自定义View Layout过程 - 最易懂的自定义View原理系列(3)