文档章节

实现TextView的onClick的xml配置

亓斌哥哥
 亓斌哥哥
发布于 2014/10/11 10:04
字数 965
阅读 63
收藏 0
点赞 0
评论 0

看到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() {
@Override
public 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配置,所以必须要自定义属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyTextView">
        <attr name="onClick" format="string" />
    </declare-styleable>
</resources>

这里我们定义了一个名称为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() {
@Override
public 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已经写完了,接下来就是使用了:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:click="http://schemas.android.com/apk/res/com.example.onclick"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >
    <com.example.onclick.MyTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dip"
        android:background="@android:color/darker_gray"
        android:text="I am Custom TextView..."
        click:onClick="click" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dip"
        android:background="@android:color/darker_gray"
        android:onClick="click2"
        android:text="I am TextView..." />
</LinearLayout>

我们定义了两个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 {
@Override
protected 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();
}
}




© 著作权归作者所有

共有 人打赏支持
亓斌哥哥

亓斌哥哥

粉丝 28
博文 34
码字总数 12346
作品 13
莱芜
程序员
Android开发中onClick事件的几种实现,分析,对比

作者:黄少卿 一、实现环境 操作系统平台:Windows XP 开发IDE:MyEclipse 8.M 使用SDK版本:Android SDK 2.3.3(API 10) 手机模拟器环境: Battery Support && SD Card Support(90M) 其它设...

晨曦之光 ⋅ 2012/03/14 ⋅ 0

android Activity实现从底部弹出或滑出选择菜单或窗口

本例使用activity实现弹出滑动窗口或菜单,主要是使用了一些设置activity的样式来实现弹出窗口和滑动效果,实现如下:第一步:设计要弹出窗口的xml布局: 第二步:创建SelectPicPopupWindow类...

ForingY ⋅ 2016/08/24 ⋅ 0

Android Butterknife

开发中找到xml中对应的ui并设置对应的事件,一般用findViewById,然后设置onClick事件来实现,这样写起来比较麻烦,有没更简单的?Butterknife本场的主角闪亮登场. Butterknife作用: 通过注...

wongstar ⋅ 2017/11/28 ⋅ 0

PopupWindow弹窗详解以及相关方法说明

最近做到在项目中用到,在这个分享给大家 layoutdetailtraffic_item.xml文件中:其中text随便填就好,我这里是引用string.xml文件中的 <?xml version="1.0" encoding="utf-8"?> <LinearLayout...

陈中雨 ⋅ 2016/11/21 ⋅ 0

SlidingMenu侧滑菜单栏的使用

实现简单的slidingmenu。 话不多说,直接上图。 实现简单的slidingmenu需要进行的步骤 下载slidelibrary包(下面有提供下载) 将下载的slidingmenu_library包导入你的Androidworkplace,就是...

15192761251 ⋅ 2015/10/20 ⋅ 0

Android UI控件和基本事件的响应

在任何一个 GUI 系统中,控制界面上的控件(通常称为控件)都是一个基本的内容。对于 Android 应用程序,控件称为 View。 在 Android 中,在处理 UI 中的各种元素的时候,两个程序中的要点为: „ ...

wxxzy ⋅ 2014/03/22 ⋅ 0

点击事件XML里的写法

对于控件点击事件的写法,我平常更倾向于在Activity里用setOnClickListener的写法来实现,不过这代码量较大,也不太符合代码书写的逻辑,更好的方式是在xml文件里使用android:onClick=“”和...

fantasiter ⋅ 2015/02/26 ⋅ 0

Android 4.4 关于新增的Scene 的Bug?求解

今天测试了下新的SDK,Scene 类真的很赞,可以实现酷的移动效果。。。但有些BUG很让人无语。。。。求解啊。。 这个使部分代码 xml 部分,因为有Scene 所以TextView分开写在两个merg 里面, ...

青鸾之旅 ⋅ 2014/02/05 ⋅ 0

AsyncTask(1)一个使用AsyncTask实现简单异步刷新的功能。

一个使用AsyncTask实现简单异步刷新的功能。 实现该功能的过程,前提是您能在eclipse下建立简单android项目。如果您未做过任何的android开发就可能看起来比较吃力了。下面我将开发的代码分块...

acebing ⋅ 2012/11/15 ⋅ 0

系出名门Android(3) - 对话框(Dialog)和通知(Notification)

系出名门Android(3) - 对话框(Dialog)和通知(Notification) 作者:webabcd 介绍 在 Android 中种对话框及各种通知效果的应用 常用对话框的使用,弹出式对话框、日期选择对话框、时间选择对话...

庸人谷 ⋅ 2012/12/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringCloud 微服务 (六) 服务通信 RestTemplate

壹 通信的方式主要有两种,Http 和 RPC SpringCloud使用的是Http方式通信, Dubbo的通信方式是RPC 记录学习SpringCloud的restful方式: RestTemplate (本篇)、Feign 贰 RestTemplate 类似 Http...

___大侠 ⋅ 12分钟前 ⋅ 0

React创建组件的三种方式

1.无状态函数式组建 无状态函数式组件,也就是你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑。 无状态函数式组...

kimyeongnam ⋅ 19分钟前 ⋅ 0

react 判断实例类型

今天在写组件的时候想通过判断内部子元素不同而在父元素上应用不同的class,于是首先要解决的就是如何判断子元素的类型。 这里附上一个讲的很全面的文章: https://www.cnblogs.com/onepixel...

球球 ⋅ 26分钟前 ⋅ 0

Centos7备份数据到百度网盘

一、关于 有时候我们需要进行数据备份,如果能自动将数据备份到百度网盘,那将会非常方便。百度网盘有较大的存储空间,而且不怕数据丢失,安全可靠。下面简单的总结一下如何使用 bypy 实现百...

zctzl ⋅ 40分钟前 ⋅ 0

开启远程SSH

SSH默认没有开启账号密码登陆,需要再配置表中修改: vim /etc/ssh/sshd_configPermitRootLogin yes #是否可以使用root账户登陆PasswordAuthentication yes #是都开启密码登陆ser...

Kefy ⋅ 42分钟前 ⋅ 0

Zookeeper3.4.11+Hadoop2.7.6+Hbase2.0.0搭建分布式集群

有段时间没更新博客了,趁着最近有点时间,来完成之前关于集群部署方面的知识。今天主要讲一讲Zookeeper+Hadoop+Hbase分布式集群的搭建,在我前几篇的集群搭建的博客中已经分别讲过了Zookeep...

海岸线的曙光 ⋅ 50分钟前 ⋅ 0

js保留两位小数方法总结

本文是小编针对js保留两位小数这个大家经常遇到的经典问题整理了在各种情况下的函数写法以及遇到问题的分析,以下是全部内容: 一、我们首先从经典的“四舍五入”算法讲起 1、四舍五入的情况...

孟飞阳 ⋅ 今天 ⋅ 0

python log

python log 处理方式 log_demo.py: 日志代码。 #! /usr/bin/env python# -*- coding: utf-8 -*-# __author__ = "Q1mi""""logging配置"""import osimport logging.config# 定义三种......

inidcard ⋅ 今天 ⋅ 0

mysql 中的信息数据库以及 shell 查询 sql

Information_schema 是 MySQL 自带的信息数据库,里面的“表”保存着服务器当前的实时信息。它提供了访问数据库元数据的方式。 什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,...

blackfoxya ⋅ 今天 ⋅ 0

maven配置阿里云镜像享受飞的感觉

1.在maven目录下的conf/setting.xml中找到mirrors添加如下内容,对所有使用改maven打包的项目生效。 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.al......

kalnkaya ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部