android自定义View&&简单布局&&回调方法

一、内容描述

根据“慕课网”上的教程,实现一个自定义的View,且该View中使用自定义的属性,同时为该自定义的View定义点击事件的回调方法。

二、定义自定义的属性

在res/valus/ 文件夹下创建一个 attrs.xml 的属性定义文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="HeadBar">
        <attr name="leftButtonText" format="string" />
        <attr name="leftButtonTextColor" format="color|reference" />
        <attr name="leftButtonTextSize" format="dimension"></attr>
        <attr name="centerTextViewText" format="string"></attr>
        <attr name="centerTextViewTextSize" format="dimension"></attr>
        <attr name="centerTextViewColor" format="color|reference"></attr>
        <attr name="rightButtonText" format="string" />
        <attr name="rightButtonTextColor" format="color|reference" />
        <attr name="rightButtonTextSize" format="dimension"></attr>
    </declare-styleable>

<attr name="backgroud_color" format="string"></attr>
   <attr name="bc" format="color|reference"></attr>

</resources>

三、定义使用它的布局文件

这里使用MainActivity的activity_main.xml,内容如下,

其中  xmlns:lib="http://schemas.android.com/apk/res-auto"  一行是定义一个第三方库的名字空间,本例中即为了可以使用自定义的属性

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.baidu.lulei.customview.HeadBar
        xmlns:lib="http://schemas.android.com/apk/res/com.baidu.lulei.customview"
        android:id="@+id/headbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        lib:backgroud_color="backgroud_color"
        lib:bc="#000011"
        lib:centerTextViewColor="#ff00ff"
        lib:centerTextViewText="标题"
        lib:centerTextViewTextSize="20sp"
        lib:leftButtonText="返回"
        lib:leftButtonTextColor="#ff0000"
        lib:leftButtonTextSize="20sp"
        lib:rightButtonText="分享"
        lib:rightButtonTextColor="#0000ff"
        lib:rightButtonTextSize="20sp" >
    </com.baidu.lulei.customview.HeadBar>

</RelativeLayout>

四、自定义 HeadBar  类型的View

本例中是它继承自RelativeLayout,因为本例中自定义的View本质上它类似一个容器,为了方便布局,这里使用才集成字RelativeLayout,当然你也可以继承自其它类型的ViewGroup

istener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.leftButtonClick(v);
            }
        });

        rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.rightButtonClick(v);
            }
        });

        this.centerText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.centerTextViewClick(v);
            }
        });
    }

    public static interface ClickListerner {
        public void leftButtonClick(View v);

        public void rightButtonClick(View v);

        public void centerTextViewClick(View v);
    }
}

五、测试它

从上面的activity_main.xml 布局文件中可以看到,它内部使用了一个自定义类型的HeadBar的View,所以可以在MainActivity中测试它,可以看到我们可以在外部定一个回调方法给自定义的View使用。

package com.baidu.lulei.customview;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class HeadBar extends RelativeLayout {
    private Button leftButton;
    private Button rightButton;
    private TextView centerText;

    private ClickListerner listener;

    public void setListener(ClickListerner listener) {
        this.listener = listener;
    }

    public HeadBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        leftButton = new Button(context);
        rightButton = new Button(context);
        centerText = new TextView(context);
        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.HeadBar);

        String backgroundcolor = attrs
                .getAttributeValue(
                        "http://schemas.android.com/apk/res/com.baidu.lulei.customview",
                        "backgroud_color");
        int bc = attrs
                .getAttributeIntValue(
                        "http://schemas.android.com/apk/res/com.baidu.lulei.customview",
                        "bc", 0xff0000ff);
        Log.e("Log", "bc :" + bc);
        Log.e("Log", "backgroundcolor :" + backgroundcolor);
        // 初始化左边的那个button
        int leftButtonTextColor = ta.getColor(
                R.styleable.HeadBar_leftButtonTextColor, 0x000011);
        String leftButtonText = ta
                .getString(R.styleable.HeadBar_leftButtonText);

        float leftButtonTextSize = ta.getDimension(
                R.styleable.HeadBar_leftButtonTextSize, 20);

        leftButton.setText(leftButtonText);
        leftButton.setTextSize(leftButtonTextSize);
        leftButton.setTextColor(leftButtonTextColor);

        // 初始化右边的那个button

        int rightButtonTextColor = ta.getColor(
                R.styleable.HeadBar_rightButtonTextColor, 0xff0000ff);
        String rightButtonText = ta
                .getString(R.styleable.HeadBar_rightButtonText);

        float rightButtonTextSize = ta.getDimension(
                R.styleable.HeadBar_rightButtonTextSize, 20);
        rightButton.setText(rightButtonText);
        rightButton.setTextSize(rightButtonTextSize);
        rightButton.setTextColor(rightButtonTextColor);

        // 初始化中间的TextView
        int centerTextColor = ta.getColor(
                R.styleable.HeadBar_centerTextViewColor, 0xff000000);
        String centerText = ta
                .getString(R.styleable.HeadBar_centerTextViewText);
        float centerTextSize = ta.getDimension(
                R.styleable.HeadBar_centerTextViewTextSize, 20);
        this.centerText.setText(centerText);
        this.centerText.setTextSize(centerTextSize);
        this.centerText.setTextColor(centerTextColor);
        // 释放TypedArray
        ta.recycle();

        // 开始布局

        RelativeLayout.LayoutParams leftButtonLayoutParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        leftButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        leftButton.setLayoutParams(leftButtonLayoutParams);

        RelativeLayout.LayoutParams rightButtonLayoutParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        rightButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        rightButton.setLayoutParams(rightButtonLayoutParams);

        RelativeLayout.LayoutParams centerTextLayoutParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        centerTextLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        centerTextLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);

        this.centerText.setLayoutParams(centerTextLayoutParams);
        Log.e("Tag", "" + leftButton.getId());
        // 将布局好的三个控件放入自定义的view中去
        addView(leftButton);
        addView(rightButton);
        addView(this.centerText);

        // 添加点击事件
        leftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.leftButtonClick(v);
            }
        });

        rightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.rightButtonClick(v);
            }
        });

        this.centerText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null)
                    listener.centerTextViewClick(v);
            }
        });
    }

    public static interface ClickListerner {
        public void leftButtonClick(View v);

        public void rightButtonClick(View v);

        public void centerTextViewClick(View v);
    }
}

六、效果

  

七、注意

1. 常见自定义属性的值类型有哪些?


属性类型


使用demo


<attr name = "background" format = "reference" />


android:background = "@drawable/图片ID"


<attr name = "textColor" format = "color" />


android:textColor = "#00FF00"


<attr name = "focusable" format = "boolean" />


android:focusable = "true|false"


<attr name = "layout_width" format = "dimension" />


android:layout_width = "42dip|42sp|42px"


<attr name = "fromAlpha" format = "float" />


android:fromAlpha = "1.0"


<attr name = "frameDuration" weight="integer" />


android:weight = "12"


<attr name = "apiKey" format = "string" />


android:apiKey = "this_is_a_string"


<attr name = "pivotX" format = "fraction" />


android:pivotX = "200%"


<attr name="orientation">

<enum name="horizontal" value="0" />

<enum name="vertical" value="1" />

</attr>


android:orientation = "vertical"


<attr name="windowSoftInputMode">

<flag name = "stateUnspecified" value = "0" />

<flag name = "stateUnchanged" value = "1" />

<flag name = "stateHidden" value = "2" />

<flag name = "stateAlwaysHidden" value = "3" />

<flag name = "stateVisible" value = "4" />

<flag name = "stateAlwaysVisible" value = "5" />

</attr>


android:windowSoftInputMode = "stateHidden">

2. attrs.xml中自己使用<attr/>标签的属性怎么获取?

如下两个属性,声明在declare-styleable之外,获取它的值呢?

声明:

<attr name="backgroud_color" format="string"></attr>
<attr name="bc" format="color|reference"></attr>

使用:

注意现在lib是 名字空间   xmlns:lib="http://schemas.android.com/apk/res/"+"应用包名"   的形式

lib:bc="#000011"
lib:backgroud_color="backgroud_color"

获取:

String backgroundcolor = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.baidu.lulei.customview","backgroud_color");
int bc = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/com.baidu.lulei.customview","bc", 0xff0000ff);

3. 读取自定义属性时使用的自定义空间命名规则如何?

如果都是在declare-styleable中声明的属性,那么名字空间可以使用

http://schemas.android.com/apk/res/+”应用包名” 或者 http://schemas.android.com/apk/res-auto

而如果你使用自定义属性是在attr中单独定义的,那么请你使用前者。

4. 附源代码下载  https://github.com/LuLei2013/CustomView.git

时间: 2024-10-01 03:28:36

android自定义View&&简单布局&&回调方法的相关文章

Android自定义View 简单实现多图片选择控件

前言 相信很多朋友在开发中都会遇到图片上传的情况,尤其是多图上传,最 经典的莫过于微信的图片选择了.所有很多情况下会使用到多图选择. 所以就有了这篇文章,今天抽点时间写了个控件. 支持自定义选择图片的样式 支持设置图片选择数量 支持图片预览,删除 支持图片拍照 先来看看效果 实现分析 假如不定义控件,我们要实现这样一个功能,无非是写个GridView在item点击的时候去显示图片进行选择,在返回界面的时候进行GridView的数据刷新.我们把这些逻辑写在我们自定义的GridView中,就成了一个

Android零基础入门第24节:自定义View简单使用

当我们开发中遇到Android原生的组件无法满足需求时,这时候就应该自定义View来满足这些特殊的组件需求. 一.概述 很多初入Android开发的程序员,对于Android自定义View可能比较恐惧,但这又是高手进阶的必经之路,这里先不做过多学习,只是简单了解.关于高阶的内容会在后续课程陆续进行学习,欢迎关注分享达人秀(ShareExpert)获取第一手教程. 如果说要按类型来划分的话,自定义View的实现方式大概可以分为三种:自绘控件.组合控件.以及继承控件. 自绘控件:内容都是开发者自己绘

【Android自定义View实战】之超简单SearchView

[Android自定义View实战]之超简单SearchView 在Android开发中我们经常会用到搜索框,而系统提供的又不尽完美.所以自定义一个比较简单的SearchView. 效果图 实现代码 package cn.bluemobi.dylan.searchview; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.ut

Android 自定义View需要重写ondraw()等方法

Android  自定义View需要重写ondraw()等方法,这篇博客给大家说说自定义View的写法,需要我们继承View,然后重写一些 方法,方法多多,看你需要什么方法 首先写一个自定义的View 继承View package com.example.engineerjspview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import and

Android自定义View(CustomCalendar-定制日历控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeasure 4onDraw 绘制月份 绘制星期 绘制日期及任务 5事件处理 源码下载 ??应项目需求,需要做一个日历控件,效果图如下: ???? ??接到需求后,没有立即查找是否有相关开源日历控件可用.系统日历控件是否能满足 ,第一反应就是这个控件该怎么画?谁叫咱自定义控件技术牛逼呢O(∩_∩)O哈哈~

android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索

我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的Android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体上来说,左边是一个ListView,右边是一个自定义View,但是左边的ListView和我们平常使用的ListView还有一点点不同,就是在ListView中我对所有的联系人进行了分组,那么这种效果的实现最常见的就是两种思路: 1.使用ExpandableListView来实现这种分组效果 2.使

Android自定义View——自定义搜索框(SearchView)

概述 在Android开发中,当系统数据项比较多时,常常会在app添加搜索功能,方便用户能快速获得需要的数据.搜索栏对于我们并不陌生,在许多app都能见到它,比如豌豆荚 在某些情况下,我们希望我们的自动补全信息可以不只是纯文本,还可以像豌豆荚这样,能显示相应的图片和其他数据信息,因此Android给我们提供的AutoCompleteTextView往往就不够用,在大多情况下我们都需要自己去实现搜索框. 分析 根据上面这张图,简单分析一下自定义搜索框的结构与功能,有 1. 搜索界面大致由三部门组成

【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑][下文简称(五),请先阅读完(五)再阅读本文],我们通过示例和log来分析了Android的事件分发机制.这些,我们只是看到了现象,如果要进一步了解事件分发机制,这是不够的,我们还需要透过现象看本质,去研究研究源码.本文将从源码(基

android 自定义View【2】对话框取色&amp;色盘取色的实现

android 自定义View[2]对话框取色&色盘取色的实现    上一篇文章基本介绍了android自定义view的流程:继承view,复写view的一些方法.实现简单的自定义view.这篇文章主要介绍的是系统对话框取色功能,然后顺便介绍升级版,色盘取色[类似于ps中的吸管,对图片点击相应位置,获取那个位置的颜色]. 一.概述:通过该例子了解以下内容: 1.进一步了解android 自定义view. 2.知道如何获取图片上的颜色值. 3.监听屏幕touch,实现移动的时候自动取色.[onDr