ym——Android从零开始(21)(自定义控件)(新)
来源:互联网 发布:iphone离线看书软件 编辑:程序博客网 时间:2024/05/16 08:06
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!
前言
在开发中,很多UI设计出来的样式我们原生控件无法满足自身的要求,所以我们就需要自定义一个控件,接下来我们来学习一下如何自定义一个控件吧。
自定义控件
自定义控件基本步骤
继承View 重写 三个构造
public class MyView extends View { privatePaint mPaint; publicMyView(Context context, AttributeSet attrs, int defStyle) { } publicMyView(Context context, AttributeSet attrs) { } publicMyView(Context context) { }
这三个构造是自动匹配调用
重写onDraw
onDraw方法给我们提过canvas(画布) 我们自己要生成画笔(Paint)以及给画笔设置颜色和字体大小
@Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); Paint mPaint = new Paint(); mPaint.setTextSize(dimension); mPaint.setColor(color); mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); canvas.drawText("我被画出来了", 50, 100, mPaint); }
在布局xml里面我们只需要全类名使用即可
<com.cym.custom.MyView // 全类名使用即可 android:layout_width="fill_parent" android:layout_height="wrap_content" />
如果想要给自定义控件添加自定义属性
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:myView="http://schemas.android.com/apk/res/com.cym.custom" android:layout_width="fill_parent" android:layout_height="fill_parent" androidrientation="vertical" > <com.cym.custom.MyView android:layout_width="fill_parent" android:layout_height="wrap_content" myView:color="@color/white" myView:fontsize="@dimen/fontsize" />
我们就要为自定义属性写xml
Attrs.xml:
<?xmlversion="1.0"encoding="utf-8"?><resources><declare-styleablename="myView"> 标识名 <attrname="color"format="color"/> 制定名字及属性格式 <attrname="fontsize"format="dimension"/> 制定名字及属性格式 </declare-styleable></resources>选择属性项Colors.xml<?xmlversion="1.0"encoding="utf-8"?><resources><colorname="white">#ffffffff</color> 制定相应属性内容 </resources>Domenson.xml<?xmlversion="1.0"encoding="utf-8"?><resources> <dimenname="fontsize">100dp</dimen> 制定相应属性内容 </resources>
获得自定义属性内容
public MyView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint();//从属性布局文件拿到所有布局属性TypedArray array =context.obtainStyledAttributes(attrs, R.styleable.myView);//根据不同的属性资源ID拿取相应的值float dimension =array.getDimension(R.styleable.myView_fontsize,10);int color =array.getColor(R.styleable.myView_color,Color.RED); mPaint.setTextSize(dimension); mPaint.setColor(color); array.recycle(); }
自定义音量条
public class MyView extends View{ private Paint paint; // 画笔 private Context context; // 上下文 private AudioManager am; // 音量管理器 private int musicMax; // 最大音量 private Bitmap bitmap; // 绿色图片 private Bitmap bitmap1; // 灰色图片 //图片宽高 private int bitmapWidth; private int bitmapHeight; // 控件宽高 private int w; private int h; public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); paint = new Paint(); this.context = context; init(); // TODO Auto-generated constructor stub } public MyView(Context context, AttributeSet attrs) { super(context, attrs); paint = new Paint(); this.context = context; init(); // TODO Auto-generated constructor stub } public MyView(Context context) { super(context); paint = new Paint(); this.context = context; init(); // TODO Auto-generated constructor stub } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); // 当前音量 int index = am.getStreamVolume(AudioManager.STREAM_MUSIC); int reverseIndex = musicMax - index; //画灰色的格子 for(int i = 0;i<reverseIndex;i++){ canvas.drawBitmap( bitmap1, null, new Rect(0, 10*i, bitmapWidth, bitmapHeight+10*i), paint); } for(int i =reverseIndex;i!=musicMax;i++){ canvas.drawBitmap( bitmap, null, new Rect(0, 10*i, bitmapWidth, bitmapHeight+10*i), paint); } } // 定义一个初始化方法 private void init(){ // 得到音量管理器 am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); // 得到最大音量 musicMax = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.sound_line); bitmap1 = BitmapFactory.decodeResource(getResources(),R.drawable.sound_line1); bitmapWidth = bitmap.getWidth(); bitmapHeight = bitmap.getHeight(); } // 对要绘制的控件进行测量 调用两次 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec,heightMeasureSpec); w = resolveSize(w, widthMeasureSpec); h = resolveSize(h, heightMeasureSpec); // 设置数据 setMeasuredDimension(w, h); } //当布局被加载完成的时候,会调用一个方法 @Override protected void onFinishInflate() { // TODO Auto-generated method stub super.onFinishInflate(); w = bitmapWidth; h = bitmapHeight * 15 + 5 * 14; } // 触摸事件 @Override public boolean onTouchEvent(MotionEventevent) { // TODO Auto-generated method stub float y = event.getY(); int index = (int)y/9; int contol_index = 15 -index; if(contol_index > -1&& contol_index <= 15){ am.setStreamVolume(AudioManager.STREAM_MUSIC, contol_index, AudioManager.FLAG_PLAY_SOUND); // 控件重绘 invalidate(); } return true; }}
课后问题
为什么要自定义控件?
因为系统提供的控件无法满足我们的需求,所以要使用自定义控件.
自定义控件的步骤?
重写三个构造,重写onDraw(绘制)方法,如果要自定义属性的话,要写配置属性xml,属性选择项xml,使用时在布局文件里面声明引用,才可以使用自定义属性。
如果业务稍微复杂还重写到?
onFinishInflate(布局加载后调用该方法)
onMeasure(对绘制控件进行测量)
以及频繁修改视图则会用到?
Invalidate()控件重绘
1 0
- ym——Android从零开始(21)(自定义控件)(新)
- ym——Android从零开始(3)(常用控件+下拉框视图)(新)
- ym——Android从零开始(4)(自动补全+列表+网格+自定义适配器)(新)
- ym——Android从零开始(13)(常用对话框、自定义对话框)(新)
- ym——Android从零开始(7)(SQLite数据库)(新)
- ym——Android从零开始(9)(ContentProvider内容提供者)(新)
- ym——Android从零开始(17)(多线程下载-上)(新)
- ym——Android从零开始(18)(多线程下载-下)(新)
- ym——Android从零开始(20)(TabHost+ExpandableListView)(新)
- ym——Android从零开始(19)(BroadcastReceiver)(新)
- ym——Android从零开始(22)(service、aidl)(新)
- ym——Android从零开始(23)(Notification+ Animation)(新)
- ym——Android从零开始(24)(多媒体播放器)(新)
- ym——Android从零开始(27)(山寨版微信-上)(新)
- ym——Android从零开始(27)(山寨版微信-下)(新)
- ym——Android从零开始(29)(Bluetooth2.0+4.0)(新)
- ym——Android从零开始(30)(WIFI、传感器)(新)
- ym——Android从零开始(31)(AppWidget、快捷图标)(新)
- java 自动拆箱与装箱
- jsp中的路径问题
- LabVIEW串口操作--labview高亮单步显示时串口缓冲区能够正常接收,直接执行时不能接收
- python使用MySQLdb,往库表内添加中文字段要做的修改
- PHP ORM-持久层框架解决方案
- ym——Android从零开始(21)(自定义控件)(新)
- addLoadEvent(func):把多个javascript函数绑定到onload事件
- javascript的设计模式实现05之Composite
- datatables and requireJS 正确使用
- 软件设计准则
- 如何查看数据库是否是rac,如何查看数据库是否是单实例
- ym——Android从零开始(19)(BroadcastReceiver)(新)
- C++Primer 学习笔记之指针和引用
- IT民工,你的未来在哪里?