我一直想出一篇关于自定义的View的文章,小伙伴们现在就可以跟着的我的小脚步,一步步来走进这个神秘的自定义View控件吧。首先我给大家带来一篇的Android 自定义UI的模块。在这一篇文章中我们可以收获到如何掌握自定义控件的属性、如何动态设计模板、以及接口的回调机制、以及如何动态创建组件。(PS:开发环境Android_Studio64 2.2)
先看一张图片吧
这张图片的看上去没有什么难的地方,这个我也承认!但是我说的这个Topber整个是一个控件。然后你会觉得这个怎么实现呢?接下我就一步步实现这个功能,并把思路一步步写下来!
先我们自定义标签,在values文件夹下面新建一个atts.xml文件里面的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Topber">
<!-- 中间的标题-->
<attr name="title" format="string" />
<!-- 标题字体的大小-->
<attr name="titleTextSize" format="dimension" />
<!-- 标题字体的颜色-->
<attr name="titleTextColor" format="color" />
<!-- 左边Button字体的颜色-->
<attr name="leftTextColor" format="color" />
<!-- 左边Button的背景颜色,这里要注意的是,背景颜色有两种,一种是#326541 还要一种是图片的类型,所以类型有两种-->
<attr name="leftBackground" format="referencecolor" />
<!-- 左边Button的字体-->
<attr name="leftText" format="string"/>
<!-- 右边Button字体-->
<attr name="rightText" format="string"/>
<!-- 右边Button字体的颜色-->
<attr name="rightTextColor" format="color"/>
<!-- 右边Button字体的背景颜色-->
<attr name="rightBackground" format="referencecolor"/>
</declare-styleable>
</resources>
**这个自定义标签的名字就是Topber**
第二步:我们来写Topber类来继承RelativeLayout 我先把代码放进去吧,然后里面的细节挨个讲解。
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* Created by OFFICE on 2016/9/26.
*/
public class Topber extends RelativeLayout{
private Button leftButton,rightButton;
private TextView tvTitile;
//左边的Button一些属性
private int leftTextColor ;
private Drawable leftBackground;
private String leftText;
//右边的Button的属性
private int rightTextColor;
private Drawable rightBackground;
private String rightText;
//中间的属性
private float titleTextSize;
private int titleTextColor;
private String title;
//布局管理器 左Button ,右边Button ,中间的TextView
private LayoutParams leftParams,rigthParams,titleParams;
//以下6行就是接口的回调!
TopberListener listener;
public interface TopberListener{
public void leftClick();
public void rigthClick();
}
public void setOnTopberClickListener(TopberListener listener){
this.listener=listener;
}
//构造方法要两个参数,一个是Context和atts参数
public Topber(Context context, AttributeSet attrs) {
super(context, attrs);
//通过TypedArray来得到布局文件的属性
TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.Topber);
//得到左边字体的颜色
leftTextColor=ta.getColor(R.styleable.Topber_leftTextColor, 0);
//得到左边的Button的背景色
leftBackground = ta.getDrawable(R.styleable.Topber_leftBackground);
//得到左边的Button的字体
leftText = ta.getString(R.styleable.Topber_leftText);
//得到右边Button的背景色
rightBackground = ta.getDrawable(R.styleable.Topber_rightBackground);
//得到右边Button字体的颜色
rightTextColor = ta.getColor(R.styleable.Topber_rightTextColor, 0);
//得到左边的Button字体
rightText = ta.getString(R.styleable.Topber_rightText);
//得到中间的文本
title = ta.getString(R.styleable.Topber_title);
//得到中间的文本的颜色
titleTextColor = ta.getColor(R.styleable.Topber_titleTextColor, 0);
//得到中间的文本的字体的大小
titleTextSize=ta.getDimension(R.styleable.Topber_titleTextSize, 0);
//回收这个TypedArray
ta.recycle();
leftButton=new Button(context);
rightButton=new Button(context);
tvTitile=new TextView(context);
//把要左边Button设置的属性都放进去
leftButton.setTextColor(leftTextColor);
leftButton.setBackground(leftBackground);
leftButton.setText(leftText);
//把要右边Button设置的属性都放进去
rightButton.setTextColor(rightTextColor);
rightButton.setBackground(rightBackground);
rightButton.setText(rightText);
//中间的TextView的一些文本的设置
tvTitile.setText(title);
tvTitile.setTextColor(titleTextColor);
tvTitile.setTextSize(titleTextSize);
tvTitile.setGravity(Gravity.CENTER);
//背景色,这个就是控件的背景色
setBackgroundColor(0xfff59563);
//把左边的Button放到布局管理器里面
leftParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); //左边对齐
addView(leftButton, leftParams);
//把右边的Button放到布局管理器里面
rigthParams=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);
rigthParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE); //右边对齐
addView(rightButton, rigthParams);
//把中间的TextView放到布局管理器里面
titleParams=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
titleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE); //居中
addView(tvTitile,titleParams);
//Button的监听 回调的时候会用到
leftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
listener.leftClick();
}
});
rightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
listener.rigthClick();
}
});
}
}
如果细心的人会发现,同过XML定义的属性怎么映射到自定义标签当中呢?对,就是通过 TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.Topber); R.styleable.Topber就是前面的自定义的标签,映射到自定义标签中,然后怎么拿到这些数据? TypedArray通过get方法可以得到相应的数据。如果你完整以后就会发现getColor(R.styleable.Topber_leftTextColor, 0) 其中的R.styleable.Topber_leftTextColor是哪里来的?哈哈,这里的话就有一个小的细节了。其中这个Topber是自定义标签的名字而leftTextColor是Topber里面的属性名字。他们一定要通过下划线才可以拿到。
setBackgroundColor(0xfff59563);这个是设置背景色,比如说Button是的背景色的白色的,当然你可以感觉自己的爱好设置自己喜欢的颜色,0xfff59563是黄色的。
leftParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);这是布局管理器,设置其中的宽和高的属性, addView(leftButton, leftParams);意思就是把这个Button添加到布局管理器中。
第三步:现在就可以在XML中应用刚刚自动的Topber
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<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:fitsSystemWindows="true"
tools:context="com.kj.baisibujie.kongyu.MainActivity">
<com.kj.baisibujie.kongyu.Topber
android:id="@+id/topbar"
android:layout_width="match_parent"
android:layout_height="40dp"
custom:leftBackground="#4EFEB3"
custom:leftText="Back"
custom:leftTextColor="#000000"
custom:rightBackground="#4EFEB3"
custom:rightText="More"
custom:rightTextColor="#000000"
custom:title="自定义标题"
custom:titleTextColor="#123412"
custom:titleTextSize="10sp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</com.kj.baisibujie.kongyu.Topber>
</RelativeLayout>
这里需要注意的事, xmlns:custom="http://schemas.android.com/apk/res-auto" 就可以使用我们自己定义的标签。当然AS里面只需要res-auto就好了,而ES里面就需要完整的路径才OK。好了,说到这里就可以完成第一张图片了。如果就是这样就完了,那么就毫无意义了。细心的读者会想,如果有点击事件那就会更加完美。
第四步:为两个Button增加点击事件的,先看两个图片的吧,然后在说怎么实现。
在MainActivity中的代码如下。
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Topber topber = (Topber) findViewById(R.id.topbar);
topber.setOnTopberClickListener(new Topber.TopberListener() {
@Override
public void leftClick() {
Toast.makeText(MainActivity.this,"您已经点击左边按钮",Toast.LENGTH_SHORT).show();
}
@Override
public void rigthClick() {
Toast.makeText(MainActivity.this,"您已经点击右边按钮",Toast.LENGTH_SHORT).show();
}
});
}
}
热门评论
Error:(102) Tag <attr> 'format' attribute value "referencecolor" not valid