手记

自定义View — Android UI 自定义设计(适合中等技术人看)篇一

    我一直想出一篇关于自定义的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();
            }
        });
    }
}
10人推荐
随时随地看视频
慕课网APP

热门评论

Error:(102) Tag <attr> 'format' attribute value "referencecolor" not valid

查看全部评论