Android自定义View入门级
Android入门级的自定义View,比较基础,例子也都是找的大神的博客看看敲敲的。直接上代码,代码中有详细注释。
一、Android自定义View
总结来说,自定义控件的实现有三种方式,分别是:自绘控件、组合控件和继承控件。
三个比较重要的方法:onMeasure(),onLayout(),onDraw()
二、自定义View自绘控件
(继承View的点击获取随机数显示)
博客:http://blog.csdn.net/lmj623565791/article/details/24252901/
1、在res/values/目录下新建一个attrs.xml,在里面声明属性和样式
<resources>//自定义属性<declare-styleable name="custom_view"><attr name="text_color" format="color" /><attr name="text_text" format="string" /><attr name="text_size" format="dimension" /></declare-styleable>
</resources>
2、继承View类,在构造方法中,获取我们的样式
public class MyCustomView extends View {private String mTextString;private int mTextColor;private float mTextSize;//图形和画笔private Rect mRect;private Paint mPaint;public MyCustomView(Context context) {this(context, null);}public MyCustomView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//和XML中的属性建立连接TypedArray _typeArray = context.obtainStyledAttributes(attrs, R.styleable.custom_view, defStyleAttr, 0);mTextString = _typeArray.getString(R.styleable.custom_view_text_text);mTextColor = _typeArray.getColor(R.styleable.custom_view_text_color, 0);mTextSize = _typeArray.getDimension(R.styleable.custom_view_text_size, (float) 15);//使用recycle()方法,使得可以实时获取属性值_typeArray.recycle();//画一个矩形mPaint = new Paint();mPaint.setTextSize(mTextSize);mRect = new Rect();mPaint.getTextBounds(mTextString, 0, mTextString.length(), mRect);//当前View的点击事件,显示变化的数字this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {mTextString = getRandomText();//在子线程中刷新viewpostInvalidate();}});}/*** 测量自定义view,一般在view中都是这种固定的模式** @param widthMeasureSpec* @param heightMeasureSpec*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//将测量结束的尺寸传给setMeasuredDimension方法setMeasuredDimension(getWidthDimension(widthMeasureSpec), getHeightDimension(heightMeasureSpec));}/*** 一般在自定义view中(继承View类),不需要重新布局** @param changed* @param left* @param top* @param right* @param bottom*/@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);}/*** 重写onDraw,重新绘制** @param canvas*/@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint.setColor(Color.YELLOW);canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);mPaint.setColor(mTextColor);canvas.drawText(mTextString, getWidth() / 2 - mRect.width() / 2, getHeight() / 2 + mRect.height() / 2, mPaint);}/*** 获取宽的测量尺寸** @param _widthMeasureSpec* @return*/public int getWidthDimension(int _widthMeasureSpec) {int _resultWidthDimension = 200;int _widthMode = MeasureSpec.getMode(_widthMeasureSpec);int _widthSize = MeasureSpec.getSize(_widthMeasureSpec);if (MeasureSpec.EXACTLY == _widthMode) {_resultWidthDimension = _widthSize;} else {_resultWidthDimension = Math.min(_widthSize, _resultWidthDimension);}return _resultWidthDimension;}/*** 获取高的测量尺寸** @param _heightMeasureSpec* @return*/public int getHeightDimension(int _heightMeasureSpec) {int _resultHeightDimension = 200;int _heightMode = MeasureSpec.getMode(_heightMeasureSpec);int _heightSize = MeasureSpec.getSize(_heightMeasureSpec);if (MeasureSpec.EXACTLY == _heightMode) {_resultHeightDimension = _heightSize;} else {_resultHeightDimension = Math.min(_heightSize, _resultHeightDimension);}return _resultHeightDimension;}/*** 获取一个变化的四位数** @return*/public String getRandomText() {StringBuilder _stringBuilder = new StringBuilder();Random _random = new Random();Set<Integer> _set = new HashSet<>();while (_set.size() < 4) {int _randomInt = _random.nextInt(10);_set.add(_randomInt);}for (Integer j : _set) {_stringBuilder.append(j);}return _stringBuilder.toString();}}
3、在布局中使用
重要:xmlns:mycustomview=”http://schemas.android.com/apk/res-auto”使用自定义命名空间
<com.millet.millet.CustomView.MyCustomViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"mycustomview:text_color="@color/colorPrimary"mycustomview:text_size="20dp"mycustomview:text_text="你好" />
4、效果
三、自定义View组合控件
(标题栏的组合)
参照Android群英传一书
1、在attrs.xml中声明属性和样式
<resources>//自定义组合控件<declare-styleable name="custom_view_mix"><attr name="left_text" format="string" /><attr name="left_text_size" format="dimension" /><attr name="middle_text" format="string" /><attr name="middle_text_size" format="dimension" /><attr name="right_text" format="string" /><attr name="right_text_size" format="dimension" /><attr name="bg" format="color" /></declare-styleable>
</resources>
2、继承ViewGroup,在构造方法中获取属性
public class MyCustomViewMix extends LinearLayout {private String _leftString, _middleString, _rightString;private float _leftSize, _middleSize, _rightSize;private int _colorBg;private TextView _leftText, _middleText, _rightText;private LinearLayout _linear;public MyCustomViewMix(Context context) {this(context, null);}public MyCustomViewMix(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyCustomViewMix(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//和XML中的属性建立连接TypedArray _typeArray = context.obtainStyledAttributes(attrs, R.styleable.custom_view_mix, defStyleAttr, 0);_leftString = _typeArray.getString(R.styleable.custom_view_mix_left_text);_middleString = _typeArray.getString(R.styleable.custom_view_mix_middle_text);_rightString = _typeArray.getString(R.styleable.custom_view_mix_right_text);_leftSize = _typeArray.getDimension(R.styleable.custom_view_mix_left_text_size, (float) 15);_middleSize = _typeArray.getDimension(R.styleable.custom_view_mix_middle_text_size, (float) 15);_rightSize = _typeArray.getDimension(R.styleable.custom_view_mix_right_text_size, (float) 15);_colorBg = _typeArray.getColor(R.styleable.custom_view_mix_bg, getResources().getColor(R.color.colorPrimaryDark));//使用recycle()方法,使得可以实时获取属性值_typeArray.recycle();initView(context);}public void initView(Context _context) {LayoutInflater.from(_context).inflate(R.layout.my_custom_view_mix, this, true);_leftText = (TextView) findViewById(R.id.my_custom_view_mix_left);_middleText = (TextView) findViewById(R.id.my_custom_view_mix_middle);_rightText = (TextView) findViewById(R.id.my_custom_view_mix_right);_linear = (LinearLayout) findViewById(R.id.my_custom_view_mix_bg);_linear.setBackgroundColor(_colorBg);_leftText.setText(_leftString);_middleText.setText(_middleString);_rightText.setText(_rightString);_leftText.setTextSize(_leftSize);_middleText.setTextSize(_middleSize);_rightText.setTextSize(_rightSize);}
3、在布局中使用
重要:xmlns:apps=”http://schemas.android.com/apk/res-auto”使用自定义命名空间
<com.millet.millet.CustomView.MyCustomViewMixandroid:layout_width="match_parent"android:layout_height="wrap_content"apps:bg="@android:color/holo_green_dark"apps:left_text="left"apps:left_text_size="8dp"apps:middle_text="middle"apps:middle_text_size="8dp"apps:right_text="right"apps:right_text_size="8dp" />
4、图片效果
四、自定义View继承控件
(ListView的滑动删除)
博客:http://blog.csdn.net/guolin_blog/article/details/17357967
1、先准备一个删除的布局样式delete_button.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/delete_button"android:layout_width="match_parent"android:layout_height="60dp"android:background="@color/colorPrimaryDark"android:text="删除" />
2、继承ListView类,进行添加滑动删除的功能
public class MyCustomViewExtends extends ListView implements GestureDetector.OnGestureListener, View.OnTouchListener {//手势private GestureDetector mGestureDetector;private onDeleteListener mOnDeleteListener;//当前选择的第几个private int mSelectedItem;//是否显示了删除按钮private boolean mIsDeleteShown;//ListView的Itemprivate ViewGroup mItemLayout;//删除布局private View mDeleteButton;public MyCustomViewExtends(Context context) {this(context, null);}public MyCustomViewExtends(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyCustomViewExtends(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//初始化手势以及注册手势事件mGestureDetector = new GestureDetector(context, this);//注册touch事件setOnTouchListener(this);}//对外留一个注册删除回调接口public void setOndeleteListener(onDeleteListener _l) {mOnDeleteListener = _l;}/*以下属于Touch事件的回调方法*/@Overridepublic boolean onTouch(View v, MotionEvent event) {//判断删除按钮是否可见,如果可见,则从ListView的Item中移除删除按钮if (mIsDeleteShown) {mItemLayout.removeView(mDeleteButton);mDeleteButton = null;mIsDeleteShown = false;return false;} else {//调用手势的点击事件return mGestureDetector.onTouchEvent(event);}}/*以下属于手势的回调方法*/@Overridepublic boolean onDown(MotionEvent e) {//假如没有显示删除的布局,我们根据点击事件来计算当前点击的布局Itemif (!mIsDeleteShown) {mSelectedItem = pointToPosition((int) e.getX(), (int) e.getY());}return false;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {//根据是否显示和在横向滑动的情况下处理if (!mIsDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {//初始化删除按钮布局mDeleteButton = LayoutInflater.from(getContext()).inflate(R.layout.delete_button, null);//初始化ListView的ItemmItemLayout = (ViewGroup) getChildAt(mSelectedItem - getFirstVisiblePosition());//在ListView的Item中放置删除按钮RelativeLayout.LayoutParams _param = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);_param.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);_param.addRule(RelativeLayout.CENTER_VERTICAL);mItemLayout.addView(mDeleteButton, _param);//设置删除按钮为可见状态mIsDeleteShown = true;//点击删除按钮事件mDeleteButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//点击删除按钮,在ListView中移除删除按钮mItemLayout.removeView(mDeleteButton);mDeleteButton = null;//设置删除按钮为不可见mIsDeleteShown = false;//使用回调对外传出对第几个Item进行了删除mOnDeleteListener.onDelete(mSelectedItem);}});}return false;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}//删除监听接口public interface onDeleteListener {void onDelete(int _index);}
}
3、在布局中使用
<com.millet.millet.CustomView.MyCustomViewExtendsandroid:id="@+id/activity_my_custom_list_view"android:layout_width="match_parent"android:layout_height="match_parent"android:dividerHeight="2dp" />
4、在Activity中使用
public class MyCustomListView extends BaseActivity {private MyCustomViewExtends mMyCustomViewExtends;private MyCustomListViewAdapter mMyCustomListViewAdapter;private List<String> mList = new ArrayList<>();@Overridepublic void initData(Bundle savedInstanceState) {for (int i = 0; i < 20; i++) {mList.add("Millet" + i);}}@Overridepublic void initView(Bundle savedInstanceState) {setContentView(R.layout.activity_my_custom_list_view);mMyCustomViewExtends = (MyCustomViewExtends) findViewById(R.id.activity_my_custom_list_view);mMyCustomListViewAdapter = new MyCustomListViewAdapter(this, 0, mList);mMyCustomViewExtends.setAdapter(mMyCustomListViewAdapter);mMyCustomViewExtends.setOndeleteListener(new MyCustomViewExtends.onDeleteListener() {@Overridepublic void onDelete(int _index) {mList.remove(_index);mMyCustomListViewAdapter.notifyDataSetChanged();}});}@Overridepublic void loadData(Bundle savedInstanceState) {}public class MyCustomListViewAdapter extends ArrayAdapter {public MyCustomListViewAdapter(Context context, int resource, List<String> objects) {super(context, resource, objects);}@NonNull@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View _view;if (null == convertView) {_view = getLayoutInflater().inflate(R.layout.my_list_view_item, null);} else {_view = convertView;}TextView _textView = (TextView) _view.findViewById(R.id.my_list_view_item_text);_textView.setText((String) getItem(position));return _view;}}}
5、图片效果
Android自定义View入门级相关推荐
- Android自定义View —— TypedArray
在上一篇中Android 自定义View Canvas -- Bitmap写到了TypedArray 这个属性 下面也简单的说一下TypedArray的使用 TypedArray 的作用: 用于从该结 ...
- Android 自定义View —— Canvas
上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...
- android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...
转载:http://blog.csdn.net/xiabing082/article/details/48781489 1. 大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...
- Android自定义View:ViewGroup(三)
自定义ViewGroup本质是什么? 自定义ViewGroup本质上就干一件事--layout. layout 我们知道ViewGroup是一个组合View,它与普通的基本View(只要不是ViewG ...
- android 自定义图形,Android自定义View之图形图像(模仿360的刷新球自定
概述: 360安全卫士的那个刷新球(姑且叫它刷新球,因为真的不知道叫什么好,不是dota里的刷新球!!),里面像住了水一样,生动可爱,看似简单,写起来不太简单,本例程只是实现了它的部分功能而已,说实话 ...
- android代码实现手机加速功能,Android自定义View实现内存清理加速球效果
Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...
- android中仿qq最新版抽屉,Android 自定义View实现抽屉效果
Android 自定义View实现抽屉效果 说明 这个自定义View,没有处理好多点触摸问题 View跟着手指移动,没有采用传统的scrollBy方法,而是通过不停地重新布局子View的方式,来使得子 ...
- Android 自定义 圆环,Android自定义view实现圆环效果实例代码
先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...
- android自定义抽奖,Android自定义view制作抽奖转盘
本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...
- android view 渐变动画,Android自定义view渐变圆形动画
本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...
最新文章
- 面试官:你能聊聊高并发下的接口幂等性如何实现吗?
- CSS中绝对定位依据谁进行定位?
- 数据类型,运算符和表达式03 - 零基础入门学习C语言04
- mysql数据自动备份_每天自动备份MySQL数据库的shell脚本
- 最新卡通渲染效果图(附带一张次世代帅哥)
- 如何下载php-5.5.38.tar.gz_搭建PHP服务器php-5.3.28.tar.gz
- 图解设计模式-Chain Of Responsibility模式
- 学术搜索,Web Of Science 核心合集检索方法,SCI分区及影响因子查看方法
- MATLAB编程算矩阵,MatLab矩阵计算
- 太极root权限_太极框架免root版下载
- 最新《择善教育》C/C++黑客编程项目实战教程
- java排球计分表窗口_排球计分程序(五)—— Controller的设计与实现
- 搭建嵌入式开源开发环境
- jenkins 触发 Rancher实现自动部署 流水线一键操作
- 常用的十种数据分析方法
- 电商运营中的五个数据陷阱
- NuxtJS 项目部署如何部署到nginx
- 泉州计算机编程培训班,泉州编程小学生培训班
- 【四足机器人】学习笔记 欧拉角与旋转矩阵之间的转化关系
- python增强对比度_OpenCV-Python-(4)-对比度增强
热门文章
- SylixOS arm64 异常向量表
- kotlin在线转java_Kotlin转Java记录
- 以太坊 node data write error_那个坚持写了四年《每周以太坊》的劳模分享关于以太坊的最新看法...
- java版AES加密算法实现
- VIM空格和TAB转换
- spark rdd详解一(rdd入门)
- dijkstra + 优先队列(C++)
- mysql数据库一般多大_数据库一般多大
- 51nod1185威佐夫博弈+大数乘法模拟
- php后台修改_ThinkPHP实现在可视化后台管理永久修改_php