Android自定义View之自定义复合控件--标题栏

1 实现效果

2 例子代码讲解

2.1 attrs.xml

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

    <declare-styleable name="TopBar">
        <attr name="title" format="string" />
        <attr name="titleTextSize" format="dimension" />
        <attr name="titleTextColor" format="color" />

        <attr name="leftTextColor" format="color" />
        <attr name="leftBackground" format="reference|color" />
        <attr name="leftText" format="string" />

        <attr name="rightTextColor" format="color" />
        <attr name="rightBackground" format="reference|color" />
        <attr name="rightText" format="string" />
    </declare-styleable>

</resources>

2.2 topbar.xml

<com.xys.mytopbar.Topbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:id="@+id/topBar"
    android:layout_width="match_parent"
    android:layout_height="40dp"

    custom:leftBackground="@drawable/blue_button"
    custom:leftText="Back"
    custom:leftTextColor="#FFFFFF"

    custom:rightBackground="@drawable/blue_button"
    custom:rightText="More"
    custom:rightTextColor="#FFFFFF"

    custom:title="自定义标题"
    custom:titleTextColor="#123412"
    custom:titleTextSize="15sp">

</com.xys.mytopbar.Topbar>

2.3 TopBar.java

package com.imooc.systemwidget;

public class TopBar extends RelativeLayout {

    // 包含topbar上的元素:左按钮、右按钮、标题
    private Button mLeftButton, mRightButton;
    private TextView mTitleView;
    // 布局属性,用来控制组件元素在ViewGroup中的位置
    private LayoutParams mLeftParams, mTitlepParams, mRightParams;

    // 左按钮的属性值,即我们在atts.xml文件中定义的属性
    private int mLeftTextColor;
    private Drawable mLeftBackground;
    private String mLeftText;
    // 右按钮的属性值
    private int mRightTextColor;
    private Drawable mRightBackground;
    private String mRightText;
    // 标题的属性值
    private float mTitleTextSize;
    private int mTitleTextColor;
    private String mTitle;

    public TopBar(Context context) {
        super(context);
    }

    public TopBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public TopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 设置topbar的背景
        setBackgroundColor(0xFFF59563);

        // 1.1 通过这个方法,将你在atts.xml中定义的declare-styleable的所有属性的值存储到TypedArray中
        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.TopBar);
        // 1.2 从TypedArray中取出对应的值来为要设置的属性赋值
        mLeftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
        mLeftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
        mLeftText = ta.getString(R.styleable.TopBar_leftText);
        mRightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0);
        mRightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
        mRightText = ta.getString(R.styleable.TopBar_rightText);
        mTitleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 10);
        mTitleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);
        mTitle = ta.getString(R.styleable.TopBar_title);
        // 1.3 获取完TypedArray的值后,一般要调用recyle方法来避免重新创建的时候的错误
        ta.recycle();

        // 2.1 获取组件元素
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);
        // 2.2 为组件元素设置相应的布局元素
        mLeftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        mRightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        mTitlepParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mTitlepParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);

        // 3.1 为创建的组件元素赋值,就来源于我们在引用的attr.xml文件中给对应属性的赋值
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackground(mLeftBackground);
        mLeftButton.setText(mLeftText);
        mRightButton.setTextColor(mRightTextColor);
        mRightButton.setBackground(mRightBackground);
        mRightButton.setText(mRightText);
        mTitleView.setText(mTitle);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setGravity(Gravity.CENTER);

        // 4.1 将组件元素添加到ViewGroup
        addView(mLeftButton, mLeftParams);
        addView(mRightButton, mRightParams);
        addView(mTitleView, mTitlepParams);
        // 4.2 设置按钮的点击事件,不需要具体的实现,只需调用接口的方法,回调的时候,会有具体的实现
        mRightButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mListener.rightClick();
            }
        });
        mLeftButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mListener.leftClick();
            }
        });
    }

    /**
     * 设置监听
     */
    // 接口对象,实现回调机制,在回调方法中通过映射的接口对象调用接口中的方法
    // 而不用去考虑如何实现,具体的实现由调用者去创建
    public interface topbarClickListener {
        // 左按钮点击事件
        void leftClick();
        // 右按钮点击事件
        void rightClick();
    }

    // 映射传入的接口对象
    private topbarClickListener mListener;

    // 暴露一个方法给调用者来注册接口回调,通过接口来获得回调者对接口方法的实现
    public void setOnTopbarClickListener(topbarClickListener mListener) {
        this.mListener = mListener;
    }

    /**
     * 设置按钮的显示与否 通过id区分按钮,flag区分是否显示
     *
     * @param id   id
     * @param flag 是否显示
     */
    public void setButtonVisable(int id, boolean flag) {
        if (flag) {
            if (id == 0) {
                mLeftButton.setVisibility(View.VISIBLE);
            } else {
                mRightButton.setVisibility(View.VISIBLE);
            }
        } else {
            if (id == 0) {
                mLeftButton.setVisibility(View.GONE);
            } else {
                mRightButton.setVisibility(View.GONE);
            }
        }
    }
}

2.4 topbar_test.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp"
    tools:context=".MainActivity">

    <!-- <include layout="@layout/topbar" /> -->

    <com.imooc.systemwidget.TopBar
        android:id="@+id/topBar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        custom:leftBackground="@drawable/blue_button"
        custom:leftText="Back"
        custom:leftTextColor="#FFFFFF"
        custom:rightBackground="@drawable/blue_button"
        custom:rightText="More"
        custom:rightTextColor="#FFFFFF"
        custom:title="自定义标题"
        custom:titleTextColor="#123412"
        custom:titleTextSize="10sp"/>

</RelativeLayout>

2.5 TopBarTest.java

package com.imooc.systemwidget;

public class TopBarTest extends Activity {

    private TopBar mTopbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.topbar_test);
        // 获得我们创建的topbar
        mTopbar = (TopBar) findViewById(R.id.topBar);
        // 为topbar注册监听事件,传入定义的接口
        // 并以匿名类的方式实现接口内的方法
        mTopbar.setOnTopbarClickListener(
                new TopBar.topbarClickListener() {

                    @Override
                    public void rightClick() {
                        Toast.makeText(TopBarTest.this,
                                "right", Toast.LENGTH_SHORT)
                                .show();
                    }

                    @Override
                    public void leftClick() {
                        Toast.makeText(TopBarTest.this,
                                "left", Toast.LENGTH_SHORT)
                                .show();
                    }
                });
        // 控制topbar上组件的状态
        mTopbar.setButtonVisable(0, true);
        mTopbar.setButtonVisable(1, false);
    }
}
时间: 2024-10-24 02:06:01

Android自定义View之自定义复合控件--标题栏的相关文章

Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发,展现了andorid中大部分对话框,代码中用了一个对话框管理类来做封装,其中还定义了对话框的动画.自定义样式等等. 主布局文件(全是button) <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.co

Android 自定义View修炼-自定义加载进度动画LoadingImageView

一.概述 本自定义View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果. 支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色. 直接看下面的效果图吧. 二.效果图 废话不说,先来看看效果图吧~~ 三.实现原理方案 1.自定义View-XCLoadingImageView,继承ImageVIew来实现,这样就不用自己再处理drawable和测量的工作内容. 2.根据蒙层颜色创建一个蒙层bitmap,然后根据这个bitmap来

Android 自定义View修炼-自定义弹幕效果View

一.概述 现在有个很流行的效果就是弹幕效果,满屏幕的文字从右到左飘来飘去.看的眼花缭乱,看起来还蛮cool的 现在就是来实现这一的一个效果,大部分的都是从右向左移动漂移,本文的效果中也支持从左向右的漂移移动 效果. 二.效果图 废话不说,先来看看效果图吧~~ 三.实现原理方案 1.自定义ViewGroup-XCDanmuView,继承RelativeLayout来实现,当然也可以继承其他三大布局类哈 2.初始化若干个TextView(弹幕的item View,这里以TextView 为例,当然也

自定义View之自定义标题栏

现在,几乎在每一个APP顶部都有一个标题栏,可能会用ActionBar,也可能自己写一个xml来添加标题栏中的控件.在以往自己做项目时大多使用后者来写一个标题栏,然后使用include包含在每一个页面布局中.今天,试下使用自定义属性来自定义一个标题栏. 一般的标题栏都分为三个模块:左侧.标题.右侧,所以我们自定义的标题栏中允许用户添加左侧文字(或图片).标题.右侧文字(或图片),并且提供相应接口去调用点击事件.这里的Demo只是一个小小的例子,后面可以根据所需修改这个标题栏. 详细看下代码,功能

13:自定义view、自定义签字板

import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.g

Android查缺补漏(View篇)--自定义 View 的基本流程

View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以形成丰富多彩的交互界面,一个应用中界面交互的体验往往在应用的受欢迎程度上起了很关键得作用,所以开发者们大多会想方设法的做出一个更加精美的界面,例如:通过自定义View.深入学习View的原理以便更好的对其优化使其在操作起来更加流畅等等,也正因为如此,在面试中View也常常作为面试官重点考察的对象之一

Android 自定义View实现单击和双击事件

自定义View, 1. 自定义一个Runnable线程TouchEventCountThread ,  用来统计500ms内的点击次数 2. 在MyView中的 onTouchEvent 中调用 上面的线程 3. 自定义一个Handler, 在TouchEventHandler 中 处理 统计到的点击事件, 单击, 双击, 三击, 都可以处理 核心代码如下: public class MyView extends View { ...... // 统计500ms内的点击次数 TouchEvent

Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如onDraw,为了我们自定义的View在一个项目中能够重用,有时候我们需要自定义其属性,举个很简单的例子,我在项目中的多个界面使用我自定义的View,每个界面该自定义View

一个规范的自定义View——Android开发艺术探索笔记

欢迎转载,转载请注明原文链接http://blog.csdn.net/l664675249/article/details/50787973 一个不规范的自定义View 这个自定义的View很简单,就是画一个圆,实现一个圆形效果的自定义View. 先看一个不规范的自定义View是怎么做的 public class CircleView extends View { private int mColor = Color.RED; private Paint mPaint = new Paint(P