您的位置:首页 > 其它

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

2016-07-21 21:29 621 查看
需求:很多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>




然后可以给其设置监听

@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√
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: