自定义View之利用组合View实现复用

来源:互联网 发布:nba直播数据统计 编辑:程序博客网 时间:2024/05/21 09:06

需求:很多UI界面中有相同的View单位,比如每个UI有相同的TitleBar。
利用androidannotations注入注解框架。

androidannotations框架的依赖导入:

//在app的build.gradle中加入apply plugin: 'com.android.application'apply plugin: 'android-apt'def AAVersion = '3.3.2'dependencies {    compile fileTree(include: ['*.jar'], dir: 'libs')    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.1.0'    apt "org.androidannotations:androidannotations:$AAVersion"    compile "org.androidannotations:androidannotations-api:$AAVersion"    }    apt {    arguments {        androidManifestFile variant.outputs[0].processResources.manifestFile        // if you have multiple outputs (when using splits), you may want to have other index than 0        // you should set your package name here if you are using different application IDs        // resourcePackageName "your.package.name".        // You can set optional annotation processing options here, like these commented options:        // logLevel 'INFO'        // logFile '/var/log/aa.log'    }}//在整个project的build.gradle中加入 dependencies {        classpath 'com.android.tools.build:gradle:2.1.2'        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'        // NOTE: Do not place your application dependencies here; they belong        // in the individual module build.gradle files    }

至此,androidannotations添加依赖完成

一个常用的需求布局,左边返回,中间一个标题,右边一个显示更多

先自定一个布局
一个线性布局,左边一个 TextView,中间一个TextView,右边一个TextView,(R.layout.custom)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/tv_left"        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="match_parent" />    <TextView        android:id="@+id/tv_middle"        android:layout_weight="6"        android:layout_width="0dp"        android:layout_height="match_parent"        android:gravity="center_horizontal"/>    <TextView        android:id="@+id/tv_right"        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="match_parent"        android:gravity="right"/></LinearLayout>

在value文件夹下建立attrs.xml文件进行属性的自定义,这里只进行字体颜色和内容的定义,可以根据需求自行添加其他需要的(命名完全自定义,只是 作为中介承接,format代表此属性的 属性)

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="TitleBar" >        <!-- 此属性用来表示右边TextView的内容 -->        <attr name="text_right" format="string"/>        <!-- 此属性用来表示左边TextView的内容 -->        <attr name="text_lfet" format="string"/>        !-- 此属性用来表示中间TextView的内容 -->        <attr name="text_title" format="string"/>        <!-- 此属性用来表示右边TextView的颜色 -->        <attr name="color_right" format="color"/>        <!-- 此属性用来表示左边TextView的颜色 -->        <attr name="color_left" format="color"/>        <!-- 此属性用来表示中间TextView的颜色 -->        <attr name="color_title" format="color"/>    </declare-styleable></resources>

然后自定义一个类继承刚才布局的根ViewGroup,这里就用到了annotations进行简洁代码了

package yidianlingzj.com.viewdemo;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;import org.androidannotations.annotations.AfterViews;import org.androidannotations.annotations.EViewGroup;import org.androidannotations.annotations.ViewById;@EViewGroup(R.layout.ui_custom)public class TitleBar extends LinearLayout {    @ViewById    TextView tv_left,tv_middle,tv_right;    String mTitle, mLeft, mRight;    int mTitle_color, mLeft_color, mRight_color;    //回调监听    TitleBarListener mLeftListener,mMiddleListener,mRightListener;    public TitleBar(Context context) {        super(context);        initRoot(null,0);    }    public TitleBar(Context context, AttributeSet attrs) {        super(context, attrs);        initRoot(attrs,0);    }    public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initRoot(attrs, defStyleAttr);    }    void initRoot(AttributeSet attrs, int defStyleAttr) {        final TypedArray typedArray=getContext().obtainStyledAttributes(                attrs,R.styleable.TitleBar,defStyleAttr,0        );        //获得对应的内容        mTitle=typedArray.getString(R.styleable.TitleBar_text_title);        mLeft=typedArray.getString(R.styleable.TitleBar_text_lfet);        mRight=typedArray.getString(R.styleable.TitleBar_text_right);        //获得对应的颜色值,默认为黑色        mTitle_color=typedArray.getColor(R.styleable.TitleBar_color_title,0xff000000);        mLeft_color=typedArray.getColor(R.styleable.TitleBar_color_left,0xff000000);        mRight_color=typedArray.getColor(R.styleable.TitleBar_color_right,0xff000000);        typedArray.recycle();    }    @AfterViews    void setupView(){        tv_left.setText(mLeft);        tv_middle.setText(mTitle);        tv_right.setText(mRight);        tv_left.setTextColor(mLeft_color);        tv_middle.setTextColor(mTitle_color);        tv_right.setTextColor(mRight_color);        setListener();    }    private void setListener(){        tv_left.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                if(mLeftListener!=null){                    mLeftListener.click(view);                }            }        });        tv_middle.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                if(mMiddleListener!=null){                    mMiddleListener.click(view);                }            }        });        tv_right.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                if(mRightListener!=null){                    mRightListener.click(view);                }            }        });    }    public void setmLeftListener(TitleBarListener mLeftListener){        this.mLeftListener=mLeftListener;    }    public void setmMiddleListener(TitleBarListener mMiddleListener){        this.mMiddleListener=mMiddleListener;    }    public void setmRightListener(TitleBarListener mRightListener){        this.mRightListener=mRightListener;    }    //监听回调    interface TitleBarListener{        void click(View view);    }}

然后就可以进行复用了,有个地方要注意,用annotations进行注解的类,annotations会自动生成一个以”“结尾的类,比如上面的TitleBar,我们使用的是注释注解生成的TitleBar
在需要用到复用这个布局
(R.layout.activity_main)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:orientation="vertical"><yidianlingzj.com.viewdemo.TitleBar_    android:id="@+id/main_tb"    android:layout_width="match_parent"    android:layout_height="65dp"    app:text_lfet="left,红色"    app:text_title="middle,默认给的是黑色"    app:text_right="right,蓝色"    app:color_left="#ff0000"    app:color_right="#0000ff"/></LinearLayout>

都这个TitleBar就是一个组合的View的复用了,现在可以在需要的地方直接用而不需要每个地方写那么长一段布局代码了

然后可以给其设置监听

@EActivity(R.layout.activity_main)public class MainActivity extends AppCompatActivity {    @ViewById    TitleBar main_tb;    @AfterViews    void setListener(){        main_tb.setmLeftListener(new TitleBar.TitleBarListener() {            @Override            public void click(View view) {                Toast.makeText(MainActivity.this, "点击了left", Toast.LENGTH_SHORT).show();            }        });        main_tb.setmMiddleListener(new TitleBar.TitleBarListener() {            @Override            public void click(View view) {                Toast.makeText(MainActivity.this, "点击了middle", Toast.LENGTH_SHORT).show();            }        });        main_tb.setmRightListener(new TitleBar.TitleBarListener() {            @Override            public void click(View view) {                Toast.makeText(MainActivity.this, "点击了right", Toast.LENGTH_SHORT).show();            }        });    }}

效果图:
这里写图片描述

其实这种方式颇有一番自定义View的风味了,只是在原有的view的基础上进行排列组合,虽然没有完全继承View进行各种方法的重写来的高大上和酷炫,但是也是很使用的一个小技巧.

新技能GET
0 0