Android 自定义View 实例

Android 相关自定义View基本知识可以参考 Android View 自定义属性, 本篇博客博主将和大家一起实践Android自定义View,我们知道,在应用中最常见的就是TitleBar,他们形式上保持一致,一般均是左边回退按钮,中间说明文本,右边功能按钮。所以很适合抽取作为自定义View模板,废话少说,直接上干货。

自定义View-attrs

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TitleBarCustom">
        <attr name="center_text" format="string"/>
        <attr name="center_size" format="dimension"/>
        <attr name="center_color" format="color"/>
        <attr name="center_ground" format="reference|color"/>
        <attr name="left_text" format="string"/>
        <attr name="left_size" format="dimension"/>
        <attr name="left_color" format="color"/>
        <attr name="left_ground" format="reference|color"/>
        <attr name="right_text" format="string"/>
        <attr name="right_size" format="dimension"/>
        <attr name="right_color" format="color"/>
        <attr name="right_ground" format="reference|color"/>
    </declare-styleable>
</resources>

自定义View类

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class TitleBar extends RelativeLayout
{
    private Button mRightButton, mLeftButton;
    private TextView mCenterTextView;
    private int mCenterColor, mRightColor, mLeftColor;
    private Drawable mCenterBackground, mRightBackground, mLeftBackground;
    private float mCenterSize, mRightSize, mLeftSize;
    private String mCenterText, mRightText, mLeftText;

    public void setOnTitleBarClickListener(OnTitleBarClickListener mOnTitleBarClickListener)
    {
        this.mOnTitleBarClickListener = mOnTitleBarClickListener;
    }

    private OnTitleBarClickListener mOnTitleBarClickListener;

    public TitleBar(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitleBarCustom);

        final int N = a.getIndexCount();

        for (int i = 0; i < N; i++)
        {
            int attr = a.getIndex(i);

            switch (attr)
            {
                case R.styleable.TitleBarCustom_center_color:

                    mCenterColor = a.getColor(attr, -1);
                    break;

                case R.styleable.TitleBarCustom_center_size:

                    mCenterSize = a.getDimension(attr, 0);
                    break;

                case R.styleable.TitleBarCustom_center_text:

                    mCenterText = a.getString(attr);
                    break;

                case R.styleable.TitleBarCustom_center_ground:

                    mCenterBackground = a.getDrawable(attr);
                    break;

                case R.styleable.TitleBarCustom_left_color:

                    mLeftColor = a.getColor(attr, -1);
                    break;

                case R.styleable.TitleBarCustom_left_size:

                    mLeftSize = a.getDimension(attr, 0);
                    break;

                case R.styleable.TitleBarCustom_left_text:

                    mLeftText = a.getString(attr);
                    break;

                case R.styleable.TitleBarCustom_left_ground:

                    mLeftBackground = a.getDrawable(attr);
                    break;

                case R.styleable.TitleBarCustom_right_color:

                    mRightColor = a.getColor(attr, -1);
                    break;

                case R.styleable.TitleBarCustom_right_size:

                    mRightSize = a.getDimension(attr, 0);
                    break;

                case R.styleable.TitleBarCustom_right_text:

                    mRightText = a.getString(attr);
                    break;

                case R.styleable.TitleBarCustom_right_ground:

                    mRightBackground = a.getDrawable(attr);
                    break;
            }
        }

        mRightButton = new Button(context);
        mRightButton.setText(mRightText);
        mRightButton.setTextSize(mRightSize);
        mRightButton.setTextColor(mRightColor);
        mRightButton.setBackgroundDrawable(mRightBackground);
        RelativeLayout.LayoutParams rightParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        rightParams.addRule(ALIGN_PARENT_RIGHT, TRUE);
        rightParams.addRule(CENTER_VERTICAL, TRUE);
        rightParams.setMargins(0, 0, 10, 0);
        mRightButton.setLayoutParams(rightParams);
        addView(mRightButton);
        mRightButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (mOnTitleBarClickListener != null)
                {
                    mOnTitleBarClickListener.rightButtonClick();
                }

            }
        });

        mLeftButton = new Button(context);
        mLeftButton.setText(mLeftText);
        mLeftButton.setTextSize(mLeftSize);
        mLeftButton.setTextColor(mLeftColor);
        mLeftButton.setBackgroundDrawable(mLeftBackground);
        RelativeLayout.LayoutParams leftParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        leftParams.addRule(ALIGN_PARENT_LEFT, TRUE);
        leftParams.addRule(CENTER_VERTICAL, TRUE);
        leftParams.setMargins(10, 0, 0, 0);
        mLeftButton.setLayoutParams(leftParams);
        addView(mLeftButton);

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

            }
        });

        mCenterTextView = new TextView(context);
        mCenterTextView.setText(mCenterText);
        mCenterTextView.setTextSize(mCenterSize);
        mCenterTextView.setTextColor(mCenterColor);
        mCenterTextView.setBackgroundDrawable(mCenterBackground);
        RelativeLayout.LayoutParams centerParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        centerParams.addRule(CENTER_IN_PARENT, TRUE);
        leftParams.setMargins(10, 0, 10, 0);
        mCenterTextView.setLayoutParams(centerParams);
        addView(mCenterTextView);

        a.recycle();
    }

    @SuppressWarnings("unused")
    public void setRightButtonVisiablity(boolean isVisiable)
    {
        if (mRightButton == null) return;

        if (isVisiable)
        {
            mRightButton.setVisibility(View.VISIBLE);
        }
        else
        {
            mRightButton.setVisibility(View.GONE);
        }
    }

    @SuppressWarnings("unused")
    public void setLeftButtonVisiablity(boolean isVisiable)
    {
        if (mLeftButton == null) return;

        if (isVisiable)
        {
            mLeftButton.setVisibility(View.VISIBLE);
        }
        else
        {
            mLeftButton.setVisibility(View.GONE);
        }
    }

    @SuppressWarnings("unused")
    public void setCenterTextVisiablity(boolean isVisiable)
    {
        if (mCenterTextView == null) return;

        if (isVisiable)
        {
            mCenterTextView.setVisibility(View.VISIBLE);
        }
        else
        {
            mCenterTextView.setVisibility(View.GONE);
        }
    }

    public interface OnTitleBarClickListener
    {
        void leftButtonClick();

        void rightButtonClick();
    }
}

使用自定义View

首先在UI中定义

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:linroid="http://schemas.android.com/apk/res-auto"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <studio.neulion.com.tasktest.TitleBar
            android:layout_width="match_parent"
            android:layout_height="60dp"
            linroid:center_color="#FF0000"
            linroid:center_text="This is Title"
            linroid:center_size="12dp"
            linroid:center_ground="#00FF00"
            linroid:right_color="#00FF00"
            linroid:right_text="Click"
            linroid:right_size="10dp"
            linroid:right_ground="#0000FF"
            linroid:left_color="#0000FF"
            linroid:left_text="Back"
            linroid:left_size="10dp"
            linroid:left_ground="#FF0000"
            android:id="@+id/title_bar" />

</LinearLayout>

然后在代码中使用

public class SixActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_title);

        initView();
    }

    private void initView()
    {
        final TitleBar titleBar = (TitleBar) findViewById(R.id.title_bar);

        if (titleBar != null)
        {
            titleBar.setOnTitleBarClickListener(new OnTitleBarClickListener()
            {
                @Override
                public void leftButtonClick()
                {
                    Toast.makeText(SixActivity.this, "Left button click!", Toast.LENGTH_LONG).show();
                }

                @Override
                public void rightButtonClick()
                {
                    Toast.makeText(SixActivity.this, "Right button click!", Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}

这样就完成了整个TitleBar的自定义View,虽然很粗糙,但是基本的模型已经出来了,这是个典型的组合自定义型View的例子,其他自定义型View后续会更新。

时间: 2024-10-06 10:47:33

Android 自定义View 实例的相关文章

Android 自定义View合集

自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/Mr-XiaoLiang 自定义控件三部曲 http://blog.csdn.net/harvic880925?viewmode=contents Android 从0开始自定义控件之View基础知识与概念 http://blog.csdn.net/airsaid/article/details/5

Android 自定义View之随机生成图片验证码

本篇文章讲的是Android自定义View之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义View的开发过程以及一些需要注意的地方. 按照惯例先看看效果图: 一.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 其中onMesure方法不一定要重写,但大部分情况下还是需要重写的 二.View 的几个构造函数 1.public CustomV

Android自定义view学习笔记02

Android自定义view学习笔记02 本文代码来自于张鸿洋老师的博客之Android 自定义View (二) 进阶 学习笔记,对代码进行些许修改,并补充一些在coding过程中遇到的问题.学习的新东西. 相关代码 //CustomImageView.java package mmrx.com.myuserdefinedview.textview; import android.content.Context; import android.content.res.TypedArray; im

android 自定义view 前的基础知识

本篇文章是自己自学自定义view前的准备,具体参考资料来自 Android LayoutInflater原理分析,带你一步步深入了解View(一) Android视图绘制流程完全解析,带你一步步深入了解View(二) Android视图状态及重绘流程分析,带你一步步深入了解View(三) Android自定义View的实现方法,带你一步步深入了解View(四) 这位大哥的系列博文,相当于自己看这些的一个思考吧. 一.首先学layoutInflater. 相信接触Android久一点的朋友对于La

android自定义View (五)view.requestLayout() 与 invalidate()

一.要点 If in the course of processing the event, the view's bounds may need to be changed, the view will call requestLayout(). Similarly, if in the course of processing the event the view's appearance may need to be changed, the view will call invalida

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

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

Android 自定义 View 详解

View 的绘制系列文章: Android View 绘制流程之 DecorView 与 ViewRootImpl Android View 的绘制流程之 Measure 过程详解 (一) Android View 的绘制流程之 Layout 和 Draw 过程详解 (二) Android View 的事件分发原理解析 对于 Android 开发者来说,原生控件往往无法满足要求,需要开发者自定义一些控件,因此,需要去了解自定义 view 的实现原理.这样即使碰到需要自定义控件的时候,也可以游刃有

Android自定义View探索(一)—生命周期

Activity代码: public class FiveActivity extends AppCompatActivity { private MyView myView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("log", "Activity生命周期:onCreate"); setConte

Android 自定义View视图

创建全新的视图将满足我们独特的UI需求. 本文介绍在指南针开发中会用到的罗盘的界面UI,通过继承View类实现的自定义视图,以此来深刻了解自定义视图. 实现效果图: 源代码: 布局文件activity_main(其中CompassView继承View类): <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.