深入了解view以及自定义控件
参考文章: http://blog.csdn.net/guolin_blog/article/details/12921889
Android LayoutInflater原理分析,带你一步步深入了解View(一)
Android自定义View的实现方法,带你一步步深入了解View(四)
这里面总共有三种自定义控件:
自绘控件、组合控件、继承控件
- 自绘控件
- package com.example.DefineView1;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.View;
- /**
- * Created by zhuxuekui on 2015/5/18.
- */
- /**
- * 自定义组合控件之 自绘控件
- */
- public
class CounterView extends View implements View.OnClickListener { - private Paint mPaint;
- private Rect mBounds;
- private
int mCount; - public CounterView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mBounds = new Rect();
- setOnClickListener(this);
- }
- @Override
- protected
void onDraw(Canvas canvas) { - super.onDraw(canvas);
- mPaint.setColor(Color.BLUE);
- canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
- mPaint.setColor(Color.YELLOW);
- mPaint.setTextSize(30);
- String text = String.valueOf(mCount);
- mPaint.getTextBounds(text,0,text.length(),mBounds);// 获取文字区域(其实是一个mBounds)的宽度与高度,然后回调。
- float textWidth = mBounds.width();
- float textHeight = mBounds.height();
- canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2
- + textHeight / 2, mPaint); //在画布上绘制文字
- }
- @Override
- public
void onClick(View view) { - mCount++;
- invalidate(); //重绘
- }
- }
在CounterView中,我们先初始化一些数据,然后设置view的点击事件。然后调用onclick方法,这里面有invalidate方法,重绘命令。然后调用ondraw方法,开始进行视图的绘制。

- package com.example.DefineView1;
- import android.app.Activity;
- import android.os.Bundle;
- public
class MyActivity extends Activity { - /**
- * Called when the activity is first created.
- */
- @Override
- public
void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- }
- 组合控件
程序结构:

- package com.example.DefineView2;
- import android.app.Activity;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.Button;
- import android.widget.FrameLayout;
- import android.widget.TextView;
- /**
- * Created by zhuxuekui on 2015/5/18.
- */
- public
class TitleView extends FrameLayout { - private Button leftButton;
- private TextView titleText;
- public TitleView(Context context, AttributeSet attrs) {
- super(context, attrs);
- LayoutInflater.from(context).inflate(R.layout.title, this);
- titleText = (TextView)findViewById(R.id.title_text);
- leftButton = (Button)findViewById(R.id.button_left);
- leftButton.setOnClickListener(new OnClickListener() {
- @Override
- public
void onClick(View view) { - ((Activity)getContext()).finish();
- }
- });
- }
- public
void setTitleText(String text) - {
- titleText.setText(text);
- }
- public
void setLeftButtonText(String text) - {
- leftButton.setText(text);
- }
- public
void setLeftButtonListener(OnClickListener l) - {
- leftButton.setOnClickListener(l);
- }
- }
首先我们定义title.xml下面的,然后定义TextView 继承FragmentLayout ,代码如上面的所示。里面我们对xml里面的控件进行初始化,设置事件都可以。


- 继承控件
截图:

程序结构:

1)增加的小按钮,只有一个button,没有布局
Delete_button.xml 子定义的listview里面增加的内容

2)编写我们自己的mylistview类
Mylistview
- package com.example.DefineView3;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.*;
- import android.widget.ListView;
- import android.widget.RelativeLayout;
- /**
- * Created by zhuxuekui on 2015/5/18.
- */
- public
class MyListView extends ListView implements View.OnTouchListener,GestureDetector.OnGestureListener { - private GestureDetector gestureDetector;
- private OnDeleteListener listener;
- private View deleteButton;
- private ViewGroup itemLayout;
- private
int selectedItem; - private
boolean isDeleteShown; - public MyListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- gestureDetector = new GestureDetector(getContext(),this);
- setOnTouchListener(this);
- }
- public
void setOnDeleteListener(OnDeleteListener l) - {
- listener = l;
- }
- @Override
- public
boolean onTouch(View view, MotionEvent motionEvent) { - if(isDeleteShown){
- itemLayout.removeView(deleteButton);
- deleteButton = null;
- isDeleteShown = false;
- return
false; - }else{
- return gestureDetector.onTouchEvent(motionEvent);
- }
- }
- //下面几个方法是OnTouchEvent的事件处理
- /**
- * 手指按下事件处理
- * @param motionEvent
- * @return
- */
- @Override
- public
boolean onDown(MotionEvent motionEvent) { - if(!isDeleteShown)
- {
- selectedItem = pointToPosition((int)motionEvent.getX(),(int)motionEvent.getY());//判断当前选中的是listview的第几行
- }
- return
false; - }
- /**
- * 快速滑动事件处理
- * @param motionEvent
- * @param motionEvent1
- * @param X
- * @param Y
- * @return
- */
- @Override
- public
boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float X, float Y) { - // 快速滑动到某一行上,加载布局deleteButton,并将删除按钮添加到当前选中的那一行item中
- if(!isDeleteShown && Math.abs(X) > Math.abs(Y)){
- deleteButton = LayoutInflater.from(getContext()).inflate(R.layout.delete_button,null);
- deleteButton.setOnClickListener(new OnClickListener() {
- @Override
- public
void onClick(View view) { - //当点击了删除按钮,我们就去回调onDeleteListener的onDelete()方法
- itemLayout.removeView(deleteButton);
- deleteButton = null;
- isDeleteShown = false;
- listener.onDelete(selectedItem);
- }
- });
- itemLayout = (ViewGroup)getChildAt(selectedItem - getFirstVisiblePosition());
- RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
- params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
- params.addRule(RelativeLayout.CENTER_VERTICAL);
- itemLayout.addView(deleteButton, params);
- isDeleteShown = true;
- }
- return
false; - }
- @Override
- public
void onShowPress(MotionEvent motionEvent) { - }
- @Override
- public
boolean onSingleTapUp(MotionEvent motionEvent) { - return
false; - }
- @Override
- public
boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) { - return
false; - }
- @Override
- public
void onLongPress(MotionEvent motionEvent) { - }
- public
interface OnDeleteListener{ - void onDelete(int index);
- }
- }
先去执行构造方法,创建gestureDetector手势捕捉监听程序,以及注册了ontouch监听。当我们按下的时候,触屏就算,程序执行到onTouch() 中,如果删除按钮已经显示我们删除掉图标,如果没有显示删除图标,我们使用gestureDetector来处理当前手势。然后我们执行gestureDetector.onTouchEvent(motionEvent) 。这里面包含多个方法,首先是onDown(),捕捉我们的手指按在了哪一行,我们记录下,滑动的时候,执行onfling(),
当按钮没有显示,然后我们去加载delete_button.xml此布局,然后并将其现在在listview当前选择的那一行上面,当我们点击删除图标的时候,执行回调方法,执行相应的逻辑。这部分逻辑在主界面中完成。
3)建立listview里面的子项
至此,新建上面的mylistview里面的每一个子项,my_list_view_item.xml.
My_list_view_item.xml listview 的子项

4)建立适配器类,继承ArrayAdapter
下一步就是新建适配器类
- package com.example.DefineView3;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ArrayAdapter;
- import android.widget.TextView;
- import java.util.List;
- /**
- * Created by zhuxuekui on 2015/5/18.
- */
- public
class MyAdapter extends ArrayAdapter<String> { - public MyAdapter(Context context, int resource, List<String> objects) {
- super(context, resource, objects);
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View view;
- if(convertView == null)
- {
- view = LayoutInflater.from(getContext()).inflate(R.layout.my_list_view_item,null);
- }else{
- view = convertView;
- }
- TextView textView = (TextView)view.findViewById(R.id.text_view);
- textView.setText(getItem(position));
- return view;
- }
- }
这一步主要就是重载ArrayAdapter,并重写构造方法和getview方法。
5)编写主界面的布局,使用自定义的listview控件
Mail.xml 布局自定义的listview

6)写主界面myactivity.java
- package com.example.DefineView3;
- import android.app.Activity;
- import android.os.Bundle;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * 自定义控件3 之 继承控件
- */
- public
class MyActivity extends Activity { - private MyListView myListView;
- private MyAdapter adapter;
- private List<String> contentList = new ArrayList<String>();
- /**
- * Called when the activity is first created.
- */
- @Override
- public
void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- initList();
- myListView = (MyListView)findViewById(R.id.my_list_view);
- myListView.setOnDeleteListener(new MyListView.OnDeleteListener() {
- @Override
- public
void onDelete(int index) { - contentList.remove(index);
- adapter.notifyDataSetChanged();
- }
- });
- adapter = new MyAdapter(this,0,contentList);
- myListView.setAdapter(adapter);
- }
- private
void initList(){ - contentList.add("Content Item 1");
- contentList.add("Content Item 2");
- contentList.add("Content Item 3");
- contentList.add("Content Item 4");
- contentList.add("Content Item 5");
- contentList.add("Content Item 6");
- contentList.add("Content Item 7");
- contentList.add("Content Item 8");
- contentList.add("Content Item 9");
- contentList.add("Content Item 10");
- contentList.add("Content Item 11");
- contentList.add("Content Item 12");
- contentList.add("Content Item 13");
- contentList.add("Content Item 14");
- contentList.add("Content Item 15");
- contentList.add("Content Item 16");
- contentList.add("Content Item 17");
- contentList.add("Content Item 18");
- contentList.add("Content Item 19");
- contentList.add("Content Item 20");
- }
- }
深入了解view以及自定义控件的更多相关文章
- view之自定义控件
转载自:http://blog.163.com/ppy2790@126/blog/static/103242241201382210910473/ 开发自定义控件的步骤: 1.了解View的工作原理 ...
- 安卓自定义控件(三)实现自定义View
前面两篇博客,把View绘制的方法说了一下,但是,我们只在onDraw里面做文章,控件都是直接传入一个Context,还不能在布局文件里使用自定义View.这一篇博客,就不再讲绘制,在我们原先的基础上 ...
- Android自定义控件View(一)
虽然Android API给我们提供了众多控件View来使用,但是鉴于Android的开发性,自然少不了根据需求自定义控件View了.比如说QQ头像是圆形的,但是纵观整个Android控件也找不到一个 ...
- android自定义控件一站式入门
自定义控件 Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理. 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自View的类,这包括展示最终内容的非 ...
- Android之自定义View的实现
对于学习Android开发的小童鞋对于自定义View一定不会陌生,相信大家对它是又爱又恨,爱它可以跟随我们的心意设计出漂亮的效果:恨它想要完全流畅掌握,需要一定的功夫.对于初学者来说确实很不容易,网上 ...
- Andriod 自定义控件之音频条
今天我们实现一个直接继承于View的全新控件.大家都知道音乐播放器吧,在点击一首歌进行播放时,通常会有一块区域用于显示音频条,我们今天就来学习下,播放器音频条的实现. 首先我们还是先定义一个类,直接继 ...
- Android自定义控件
开发自定义控件的步骤: 1.了解View的工作原理 2. 编写继承自View的子类 3. 为自定义View类增加属性 4. 绘制控件 5. 响应用户消息 6 .自定义回调函数 一.Vie ...
- Android 自定义View 三板斧之三——重写View来实现全新控件
通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 本文来讨论最难的一种 ...
- Android 自定义控件(一)
本文用一个简单的例子来说明一下自定义控件的步骤实现,自定义控件有几种实现类型,分别为继承自view完全自定义,继承现有的 控件实现特定效果,继承viewgroup实现布局类等: 本文研究的是继承自vi ...
随机推荐
- iOS菜单滚动联动内容区域功能实现
平时开发APP中关于此功能还是比较经常碰到,本实例借用三个开源的插件,并对其中一个进行修改调整实现出想要的效果:本文重点介绍修改的内容跟三个插件的运用,这三个插件还可以各自扩展到其它项目的运用: 效果 ...
- 【读书笔记】iOS-NSString的length
NSString的length方法能够准确无误地处理国际字符串,如含有俄文,中文或者日本文字符的字符串,以及使用Unicode国际字符标准的字符串.在C语言中处理这些国际字符串是件令人非常头疼的事情 ...
- iOS支付宝集成时遇到的问题整理(1)
1.模拟器上运行正常,但是真机调试时报编译链接错误 :ld: '/Users/wangqipeng/Desktop/iOS支付宝官方文档/AlixPayDemo/libcrypto.a(bio_lib ...
- session失效后跳转到登陆页面
一.编写Filter拦截器类 package com.pv.utils; import java.io.IOException; import java.io.PrintWriter; import ...
- 烂泥:【解决】word复制windows live writer没有图片
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在使用windows live writer发表博客,博客先是在是word2013中进行编辑,编辑完毕后我会复制到windows live writer ...
- nyoj 120 校园网络
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=120 思路:先将原图强连通缩点为新图,统计新图中入度,出度为0的点的个数,两者取最大值即为 ...
- ubuntu16.04 安装网易云音乐
最爱的播放器 网易云音乐 哈哈,刚刚折腾了双系统,立马开始了软件安装. 网易云音乐从官网下载对应的 64 位版本,我下载的是 netease-cloud-music_1.0.0_amd64_ubunt ...
- 【转载】chromium浏览器开发系列第一篇:如何获取最新chromium源码
背景: 最近摊上一个事儿,领导非要让写一篇技术文章,思来想去,自己接触chrome浏览器时间也不短了,干脆就总结一下吧.于是乎,本文顺理成章.由于有些细节必需描述清楚,所以这次先讲如何拿到ch ...
- 深入理解UIApplication和ios程序启动过程
在深入理解UIApplication前我们先了解ios程序的启动过程: UIApplication类在ios里面为app的管理和协调提供一个集中的点,每一个app有一个UIApplication的实例 ...
- 设计模式笔记感悟 - Creational篇
body,td,p { // 这对大括号里描述网页的背景 margin-left:40px; margin-right:40px; font-size: 10pt; } div.vim { width ...