9.自定义控件

来源:互联网 发布:软件质量属性 编辑:程序博客网 时间:2024/06/08 07:29

需求:

实现这样的自定义Toolbar控件

这里写图片描述

过程分析:
1.安卓Activity的默认主题中有ActionBar控件,为了不会出现两个ToolBar的情况,隐藏默认的
2.每一个控件都有对应的布局文件来设置显示的布局,所以我们新建一个布局文件,来设置我们的ToolBar布局
3.有了布局,我们可以在想要用到该控件的Activity的布局文件引入就可以了,但是里面子控件的点击事件的监听
就要在引入该布局的Activity中设置,很显然,到现在我们写的还只是一个布局文件,当我们程序中所有的Activity
都要用该控件,还要每个都设置一次监听???
4.所以我们要用一个JAVA文件来对该布局中所有的子控件进行监听和设置,就是真的控件了

结论:所有的控件由布局文件还有一个JAVA文件来初始化该界面和管理该布局文件里面的子控件,控件=布局+管理的JAVA文件

代码分析:
1.原来是有ActionBar的控件,为了隐藏这里有两种实现方法
1.单个Activity设置:获取ActionBar实例,设置隐藏,但是该方法只是在你设置了该代码的Activity有效

        ActionBar actionBar=getSupportActionBar();           if(actionBar!=null){                actionBar.hide();        }
    2.全局设置:        打开目录:app/src/res/values/style.xml            设置主题,代码:
                <resources>                <!--这里设置没有ActionBar-->                <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">                <!--这一句是设置全屏显示-->                <item name="android:windowFullscreen">true</item>                <item name="colorPrimary">@color/colorPrimary</item>                <item name="colorPrimaryDark">@color/colorPrimaryDark</item>                <item name="colorAccent">@color/colorAccent</item>                </style>                </resources>

2.既然是控件,肯定要有布局文件,那我们先弄好布局文件,在res/layout目录下新建一个title.xml文件
代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    <!--设置控件的高度为默认的ActionBar高度-->    android:layout_height="?attr/actionBarSize"    <!--设置控件的背景色是color文件里名为colorPrimary颜色,其实就是默认ActionBar的颜色-->    android:background="@color/colorPrimary"    <!--我们从图里可以看到,布局是水平分布的,这里要设置布局分布默认是水平-->    android:orientation="horizontal">    <TextView        android:id="@+id/back"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        <!--设置这一个TextView的位置是垂直放向上的中心-->        <!--因为外层布局已经设置了是水平的,所以水平方向珊瑚的设置已经失效-->        android:layout_gravity="center"        android:layout_margin="10dp"        android:text="Back"        android:textSize="20sp"        <!--设置字体风格-->        android:textStyle="bold" />    <TextView        <!--由于水平方向上的设置已经失效,所以我们可以设置TextView控件所占的比例使其居中显示-->        <!--设置了什么,你可以对比上面的TextView-->        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:layout_weight="1"        <--设置文字居中显示-->        android:gravity="center"        android:text="Title"        android:textSize="20sp"        android:textStyle="bold" />    <TextView        android:id="@+id/menu"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:layout_margin="10dp"        android:text="Memu"        android:textSize="20sp"        android:textStyle="bold" /></LinearLayout>

3.接下来我们先在MainActivity的布局文件中引入该布局来看看效果,在MainActivity布局文件中添加下面这一句

<include layout="@layout/title"/>

现在你运行下程序,你会发现已经成功实现效果了,要为TextView设置点击事件只要在Activity通过
ID中找到对应的就可以了设置了。但是!!!我们要的自定义控件就是这样吗???当然不!!!这
只是写一个布局在外面,然后在相应的Activity的布局文件中引入即可,这样的写法也是有好处的,
比如为了让一个Activity中的布局文件看起来更加的清晰,就可以把不同控件的布局代码提出来,放
在不同布局文件中,然后在对应的Activity导入即可,可是我们要用的控件,比如TextView不是这样
引入的啊!!!还有,我所有的Activity中都要注册一次监听吗????接下来就真的开始把布局变成控件了!!!

我想你肯定想到了,注册监听啊,还有对这个控件里面的东西进行管理,肯定是通过JAVA代码实现的,那这一
部分的代码该怎么写??

其实你翻翻安卓本身提供的控件源码就知道了。

先看看控件以及布局的继承关系

所有的控件布局的父类都是View类

                                           View         TextView                        ImageView                           ViewGroup  EditText      Button                                          LinearLayout   RelativeLayout    ....

可以看到ViewGroup是所有布局的父类
所以我们写的控件的JAVA文件应该继承谁???翻上去看,我们title.xml的文件的最外层是LinearLayout,所以我们继承LinearLayouyt是可以的

代码:

public class Title extends LinearLayout{    //LinearLayout的构造函数,要求传入context, AttributeSet 两个参数,所以在这里调用父类的构造函数传入    public Title(final Context context, AttributeSet attributeSet){        super(context,attributeSet);        //加载布局,这里的context是上下文,你可以理解成Activity,这里的意思是,从使用该控件的Activyt        //构建一个LayoutInflater对象,通过该对象的inflater方法加载布局文件到指定的布局中,这里我们传入this        LayoutInflater.from(context).inflate(R.layout.title,this);        TextView back=(TextView)findViewById(R.id.back);        TextView menu=(TextView)findViewById(R.id.menu);        back.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(context,"back",Toast.LENGTH_SHORT).show();            }        });        menu.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(context,"back",Toast.LENGTH_SHORT).show();            }        });    }}

怎么使用???控件你怎么用,就怎么用,注意,一定要把完整的包名写出来
代码:

<com.example.ljh99.saveactivitydatademo.Title        android:layout_width="match_parent"        android:layout_height="wrap_content"/>

完啦!!!现在该知道举一反三了吧!!!!