博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现TextView的onClick的xml配置
阅读量:6870 次
发布时间:2019-06-26

本文共 2887 字,大约阅读时间需要 9 分钟。

  hot3.png

看到button的android:onClick=""很方便,试了试TextView的,虽然可以设置onClick属性,但是点击的时候总是不能相应,onClick属性的配置是在View级别设置的,难道是TextView给屏蔽了?等看到TextView的源码再来解决这个疑问。

既然不能用, 那么咱们就仿照着View的源码自己实现个onClick

既然是增强版的TextView,那么首先建立一个类让它继承自TextView

public class MyTextView extends TextView {public MyTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyTextView, defStyle, 0);final int COUNT = ta.getIndexCount();for (int i = 0; i < COUNT; i++) {int attr = ta.getIndex(i);switch (attr) {case R.styleable.MyTextView_onClick:final String handlerName = ta.getString(attr);if(null != handlerName) {setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Method handler = null;try {handler = getContext().getClass().getMethod(handlerName, View.class);handler.invoke(getContext(), MyTextView.this);} catch (Exception e) {e.printStackTrace();}}});}break;}}ta.recycle();}}

短短几行代码,我们需要功能已经实现了,可以看到我们使用了反射机制,不用想也知道,android源码肯定也是使用了反射机制。

下面一点点的来分析吧:

首先是加载attr,因为我们要实现onClick的xml配置,所以必须要自定义属性:

    
        
    

这里我们定义了一个名称为onClick的属性,格式为string类型, 当你配置到xml布局的时候,我们还需要在自定义TextView中获取它的值,首先我们获取TypedArray对象:

TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyTextView, defStyle, 0);

接下来是获取ta的总个数:

final int COUNT = ta.getIndexCount();

接着一个熟悉的for循环,我们来取所有的我们自定义的attr,使用一个swith...case...语句来判断是不是我们需要的那个attr,当然我们只有一个attr,所以这么写有点多次一举,但是有利于以后扩展吧。

注意:

int attr = ta.getIndex(i);

这句话是获取当前attr的索引,即:R.styleable.xxx。

然后我们通过:

final String handlerName = ta.getString(attr);

获取方法名称(xxx:onClick="method")

接下来就是设置onClick事件了,因为当前我的是在一个TextView中,所以直接:

setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {}}

就ok了。关键的步骤来了,我们需要根据获取的方法名通过反射机制来调用该方法,在使用button的onClick时,我们映射的方法有一个参数是View,我们这也来一个。

通过参数名获取方法:

Method handler = getContext().getClass().getMethod(handlerName, View.class);

这里不难理解,因为该Method是在使用该xml布局的Activity中定义的,所以需要getContext()来获取上下文,getMethod的第一个参数是方法名,第二个参数是方法的参数类型。

最后一步,就是调用这个方法了:

handler.invoke(getContext(), MyTextView.this);

现在我们扩展的TextView已经写完了,接下来就是使用了:

    
    

我们定义了两个TextView,第一个是我们自定义的,第二个是一个普通的TextView,两个我们都给了onClick配置,需要注意的是:自定义TextView的onClick配置我们使用的是:

click:onClick="click"

我们使用了一个click命名空间,所以要声明该命名空间:

xmlns:click="http://schemas.android.com/apk/res/com.example.onclick"

我们的activity代码很简单:

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void click(View view) {Toast.makeText(this, "hello android", Toast.LENGTH_SHORT).show();}public void click2(View view) {Toast.makeText(this, "hello world", Toast.LENGTH_SHORT).show();}}

转载于:https://my.oschina.net/qibin/blog/326680

你可能感兴趣的文章
引用程序集没有强名称解决办法
查看>>
poj 2965 The Pilots Brothers' refrigerator
查看>>
子集生成——回溯法的准备篇
查看>>
Python列表的增删改查和元祖
查看>>
实现多线程2
查看>>
【全网最全的博客美化系列教程】03.给博客添加一只萌萌哒的小仓鼠
查看>>
内核同步机制
查看>>
重建二叉树
查看>>
消息队列
查看>>
用 Tornado 实现简单的在线代理
查看>>
函数指针和指针函数
查看>>
HTML 如何让图片全屏的问题
查看>>
silverlight 如何在浏览器的新页面里打开一个xaml
查看>>
SQL Tuning Advisor使用实例
查看>>
server-U上传中文文件乱码
查看>>
编程珠玑:用后缀数组寻找最长重复字符串
查看>>
Java写到.txt文件,如何实现换行
查看>>
通过http proxy访问git 服务
查看>>
JavaScript之isNaN()函数讲解
查看>>
MPlayer源代码分析
查看>>