您的位置:首页 > 移动开发 > Android开发

Android的创建复合控件

2017-05-13 20:38 507 查看
新建工程,在values新建resour flie,取名为attrs(attr是attribute 属性的简写,因为有多个属性,所以就取名为attrs )。

先举个栗子

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myTop">
<attr name="mTitleText" format="string"/>
<attr name="mTitleTextColor" format="color"/>
<attr name="mTitleTextSize" format="dimension"/>
<attr name="leftBackground" format="color|reference"/>
<attr name="leftText" format="string"/>
<attr name="leftTextColor" format="color"/>
<attr name="rightBackground" format="color|reference"/>
<attr name="rightText" format="string"/>
<attr name="rightTextColor" format="color"/>
</declare-styleable>
</resources>


解释一下代码,resources是根节点,不用管,创建就会自动生成。
declare-styleable
标签声明了使用自定义属性,并通过name属性来确定引用的名称.

然后declare下面有多个attr,即为定义的多个属性,每个自定义属性都有name和format,name不用说,format即为属性的类型。

属性定义好了,就要自定义一个View了

创建一个Class,取名为MyView,继承自ViewGroup(或者RelativeLayout或者LinearLayout),然后重写带两个参数的方法

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}


然后在方法里写

TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.myTop);


通过TypeArray这样的数据结构来获取自定义属性集

再通过get×××获得属性值(这里属性太多,我就只写了一条获取属性值的例子)

String rightText = typedArray.getString(R.styleable.myTop_rightText);


全部属性都获取完成之后,那么TypeArray就已经没用了,所以最后执行

typedArray.recycle();//来完成资源的回收,避免重新创建的时候发生错误


然后再将属性值赋给控件的实例(这里的context即为上面两个参数的构造函数里面的一个参数)

Button rightBtn = new Button(context);
rightBtn.setText(rightText);


OK!到现在我们已经自定义了多个属性,并把属性赋给了新建的控件,然后该为组件设置布局了吧

private LayoutParams titleParam;

titleParam= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

addView(title,titleParam);


到此为止,自定义View就差不多结束了。该去layout里面使用了吧

进入activity_main.xml 可以看到这样一行代码

xmlns:android="http://schemas.android.com/apk/res/android"


xmlns即xml namespace。这里指定了名字控件为”android”,所以在下面的代码里才可以使用android:layout_width、android:layout_height等等以android开头的。所以,我们在下面加上一行

xmlns:myview="http://schemas.android.com/apk/res-auto"


这样我们就可以使用我们的自定义属性了,myview是名字,可以随便起。最后的res-auto是Android Studio里面使用的,而在eclipse里面需要加完整的包名。

下面我们就可以定义属性的值了

<com.example.antact.myview.MyView
android:id="@+id/my_view"
android:layout_width="match_parent"
android:layout_height="40dp"
myview:mTitleText="自定义标题"
myview:mTitleTextColor="#123456"
myview:mTitleTextSize="8sp"
myview:leftBackground="#678905"
myview:leftText="左按钮"
myview:leftTextColor="#456789"
myview:rightBackground="#678905"
myview:rightText="右按钮"
myview:rightTextColor="#456789">

</com.example.antact.myview.MyView>


到这里就自定义View就结束了。最后展示一下效果图



如果我们想为左右Button添加点击事件,你肯定想直接在MyView里面

leftBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v
4000
iew) {
//Toast
}
});


但是这样写就把代码写死了,不一定每个调用这个View的leftButton的功能都是一样的。所以这里需要定义一个接口,并把接口暴露给调用者

private OnMyViewClickListener listener;

public interface OnMyViewClickListener{
void leftClick();
void rightClick();
}

public void setOnMyViewClickListener(OnMyViewClickListener mListener){
listener = mListener;
}


所以下面的Button只用写

leftBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
listener.leftClick();
}
});


具体的方法在MainActivity里面实现

MyView myView = (MyView)findViewById(R.id.my_view);
myView.setOnMyViewClickListener(new MyView.OnMyViewClickListener() {
@Override
public void leftClick() {
Toast.makeText(MainActivity.this,"leftButton",Toast.LENGTH_LONG).show();
}

@Override
public void rightClick() {
Toast.makeText(MainActivity.this,"rightButton",Toast.LENGTH_LONG).show();
}
});


通过如上所示的代码,我们可以在其他布局文件中,直接通过include使用模板。

到这里,所有的总结完成了。

最后,贴一下源码

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myTop">
<attr name="mTitleText" format="string"/>
<attr name="mTitleTextColor" format="color"/>
<attr name="mTitleTextSize" format="dimension"/>
<attr name="leftBackground" format="color|reference"/>
<attr name="leftText" format="string"/>
<attr name="leftTextColor" format="color"/>
<attr name="rightBackground" format="color|reference"/>
<attr name="rightText" format="string"/>
<attr name="rightTextColor" format="color"/>
</declare-styleable>
</resources>


MyView.java

package com.example.antact.myview;

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

/**
* Created by Antact on 2017/5/13.
*/

public class MyView extends RelativeLayout{

private TextView title;
private Button leftBtn;
private Button rightBtn;
private RelativeLayout.LayoutParams titleParam,leftParam,rightParam;

private OnMyViewClickListener listener; public interface OnMyViewClickListener{ void leftClick(); void rightClick(); } public void setOnMyViewClickListener(OnMyViewClickListener mListener){ listener = mListener; }

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.myTop);
int titleTextColor = typedArray.getColor(R.styleable.myTop_mTitleTextColor, 0);
String titleText = typedArray.getString(R.styleable.myTop_mTitleText);
float titleTextSize = typedArray.getDimension(R.styleable.myTop_mTitleTextSize, 0);
Drawable leftBackground = typedArray.getDrawable(R.styleable.myTop_leftBackground);
String leftText = typedArray.getString(R.styleable.myTop_leftText);
int leftColor = typedArray.getColor(R.styleable.myTop_leftTextColor, 0);
Drawable rightBackground = typedArray.getDrawable(R.styleable.myTop_rightBackground);
String rightText = typedArray.getString(R.styleable.myTop_rightText);
int rightColor = typedArray.getColor(R.styleable.myTop_rightTextColor, 0);
typedArray.recycle();

title = new TextView(context);
leftBtn = new Button(context);
rightBtn = new Button(context);

title.setTextColor(titleTextColor);
title.setText(titleText);
title.setTextSize(titleTextSize);

leftBtn.setBackground(leftBackground);
leftBtn.setText(leftText);
leftBtn.setTextColor(leftColor);

rightBtn.setBackground(rightBackground);
rightBtn.setText(rightText);
rightBtn.setTextColor(rightColor);

titleParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
titleParam.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
addView(title,titleParam);

leftParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
leftParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);
addView(leftBtn,leftParam);

rightParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
rightParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);
addView(rightBtn,rightParam);

leftBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { listener.leftClick(); } });

rightBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
listener.rightClick();
}
});

}

}


activity_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myview="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.example.antact.myview.MyView android:id="@+id/my_view" android:layout_width="match_parent" android:layout_height="40dp" myview:mTitleText="自定义标题" myview:mTitleTextColor="#123456" myview:mTitleTextSize="8sp" myview:leftBackground="#678905" myview:leftText="左按钮" myview:leftTextColor="#456789" myview:rightBackground="#678905" myview:rightText="右按钮" myview:rightTextColor="#456789"> </com.example.antact.myview.MyView>

</RelativeLayout>


MainActivity.java

package com.example.antact.myview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyView myView = (MyView)findViewById(R.id.my_view); myView.setOnMyViewClickListener(new MyView.OnMyViewClickListener() { @Override public void leftClick() { Toast.makeText(MainActivity.this,"leftButton",Toast.LENGTH_LONG).show(); } @Override public void rightClick() { Toast.makeText(MainActivity.this,"rightButton",Toast.LENGTH_LONG).show(); } });
}
}


/参考自Android群英传
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android