Android 轻松设计UI模板

写在前面:

我们写应用的时候,常常会发现很多界面都是有相同或是相似的部分的,比如相同的Topbar或是相同的底部之类。

我们以QQ为例:

而且这些相似的部分一旦修改,就是所有的一起修改,如果就改一两个倒还好,多了你试试?都说懒惰是程序员进步的阶梯,所以懒惰的程序员们就使用模板这种东西来提高自己的生产效率,同时也提高了代码的可读性、可维护性。本文就和大家一起来实现我们自己的模板,一个Topbar。效果如下:

麻雀虽小,五脏俱全,重要的是思想。

看完本文,你可以学到:

1.declare-styleable的使用

2.自定义控件

3.在界面中复用自定义控件

一、自定义控件

现在我们要实现的是一个Topbar,根据效果图我们可以看到它是由一个左按钮、一个Title、一个右按钮组成的,我们就定义一个由这三个部件产生的布局类:

public class TopBar extends RelativeLayout {

	private Button leftButton, rightButton;
	private TextView title;

	// 左侧button属性
	private int leftTextColor;
	private Drawable leftBackground;
	private String leftText;

	// 右侧button属性
	private int rightTextColor;
	private Drawable rightBackground;
	private String rightText;

	// title属性
	private int titleTextColor;
	private float titleTextSize;
	private String titleText;

	// 布局属性
	private LayoutParams leftParams, rirhtParams, titleParams;

	private TopBarClickListener listener;

	public TopBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO 自动生成的构造函数存根    //这个方法还是空的,下面会填充!
	}

	// 点击事件监听器接口
	public interface TopBarClickListener {

		public void leftclick();

		public void rightclick();
	}

	// 设置监听器
	public void setOnTopBarClickListener(TopBarClickListener listener) {
		this.listener = listener;
	}

	public void setLeftIsVisible(boolean visible) {
		if (visible) {
			leftButton.setVisibility(View.VISIBLE);
		} else {
			leftButton.setVisibility(View.GONE);
		}
	}

	public void setRightIsVisible(boolean visible) {
		if (visible) {
			rightButton.setVisibility(View.VISIBLE);
		} else {
			rightButton.setVisibility(View.GONE);
		}
	}

}

可以看到,我们在这个布局中定义了所需要的三个控件,以及这三个控件的属性。我们还建立了接口回调机制,使用这个自定义控件的其他布局可以通过这个接口来设定监听机制。同时还可以调用setIsvisible方法来隐藏或者显示左右两边的按钮。不过现在我们还没有为这些属性赋值,所以我们继续看下去。

二、使用declare-styleable来定义属性

什么是declare-styleable?是在values文件夹下attrs.xml中用来定义属性集的。

首先来看看attrs.xml文件。

该文件是定义属性名和格式的地方,需要用<declare-styleable name="TopBar"></declare-styleable>包围所有属性。其中name为该属性集的名字,主要用途是标识该属性集。那在什么地方会用到呢?在我们的自定义控件获取某属性标识时,会用到"R.styleable.TopBar..."(稍后会看到),很显然,他在每个属性前面都加了"TopBar_"。

在来看看各种属性都有些什么类型吧:string , integer , dimension , reference , color , enum......

前面几种的声明方式都是一致的,例如:<attr name="buttonNum" format="integer"/>。

只有enum是不同的,用法举例:

<span style="color:#330000;"><attr name="testEnum">
    <enum name="fill_parent" value="-1"/>
    <enum name="wrap_content" value="-2"/>
</attr></span>

现在大家应该明白attrs.xml的用途以及写法了,我们来为自定义的Topbar写个attrs.xml(放在values文件夹下):

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<declare-styleable name="TopBar">
		<!-- 文字 -->
		<attr name="leftText" format="string" />
		<attr name="rightText" format="string" />
		<attr name="titleText" format="string" />
		<!-- 文字颜色 -->
		<attr name="leftTextColor" format="color" />
		<attr name="rightTextColor" format="color" />
		<attr name="titleTextColor" format="color" />
		<!-- 文字大小 -->
		<attr name="titleTextSize" format="dimension" />
		<!-- 背景色 -->
		<attr name="leftBackground" format="reference|color" />
		<attr name="rightBackground" format="reference|color" />

	</declare-styleable>

</resources>

然后我们补充上边Topbar类的构造函数:

public TopBar(Context context, AttributeSet attrs){

		super(context, attrs);
		//获取自定义属性和值的映射集合
		TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);

		//取出自定义属性 - 左侧
		leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, Color.BLACK);
		leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
		leftText = ta.getString(R.styleable.TopBar_leftText);

		//取出自定义属性 - 右侧
		rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, Color.BLACK);
		rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
		rightText = ta.getString(R.styleable.TopBar_rightText);

		//取出自定义属性 - 标题
		titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, Color.BLACK);
		titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 12);
		titleText = ta.getString(R.styleable.TopBar_titleText);
		//回收TypedArray(避免浪费资源,避免因为缓存导致的错误)

		ta.recycle();

		leftButton = new Button(context);
		rightButton = new Button(context);
		title = new TextView(context);

		//设置属性 - 左侧
		leftButton.setText(leftText);
		leftButton.setTextColor(leftTextColor);
		leftButton.setBackground(leftBackground);

		//设置属性 - 左侧
		rightButton.setText(rightText);
		rightButton.setTextColor(rightTextColor);
		rightButton.setBackground(rightBackground);

		//设置属性 - 标题
		title.setText(titleText);
		title.setTextSize(titleTextSize);
		title.setTextColor(titleTextColor);
		title.setGravity(Gravity.CENTER);

		//设置整体背景颜色
		setBackgroundColor(0xfff59563);

		//设置布局 - 左
		leftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
		leftParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
		addView(leftButton, leftParams);//将按钮添加进布局中

		//设置布局 - 右
		rirhtParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		rirhtParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
		rirhtParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
		addView(rightButton, rirhtParams);//将按钮添加进布局中

		//设置布局 - 标题
		titleParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
		addView(title, titleParams);//将按钮添加进布局中

		//设置监听器
		leftButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v){

				listener.leftclick();
			}
		});
		rightButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v){

				listener.rightclick();
			}
		});
	}

这个构造函数就是用传进来的值对控件的属性进行赋值,另外给控件加了监听,加入到自己的布局中。

三、在别的布局中使用我们的自定义控件

我们在MainActivity中要使用这个Topbar,那首先我们要在它的布局文件中(activity_main.xml)引用我们的自定义控件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res/com.sloop.topbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sloop.topbar.MainActivity" >

    <com.example.mytopbar.TopBar
        android:minHeight="48dp"
        android:id="@+id/topbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:leftBackground="@drawable/blue_button"
        app:leftText="左侧"
        app:titleTextSize="8sp"
        app:rightBackground="@drawable/blue_button"
        app:rightText="右侧"
        app:titleText="自定义标题"
        app:titleTextColor="#ffffff" >
   </com.example.mytopbar.TopBar>

</RelativeLayout>

在这个文件中我们为它的三个组成部分的属性赋了值,细心的朋友可能发现对button的背景使用了自定义的blue_button,以下是blue_button.xml(在drawable文件夹下):

<?xml version="1.0" encoding="utf-8"?>
<!-- shape如果不声明形状默认是正方形 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 设置圆角 -->
    <corners android:radius="2dp" >
    </corners>
    <!-- 设置填充色 -->
    <solid android:color="#4285f4" >
    </solid>
    <!-- 设置边框的颜色和宽度 -->
    <stroke
        android:width="1dp"
        android:color="#4285f4" >
    </stroke>

</shape>

要长成什么样,大家可以自己根据需求修改。

然后是MainActicity的代码:

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//获取自定义控件
		TopBar topBar = (TopBar) findViewById(R.id.topbar);  //id是在acitivity_main中定义的
		topBar.setOnTopBarClickListener(new TopBarClickListener() {
			@Override
			public void rightclick(){
				Toast.makeText(MainActivity.this, "Right Clicked", Toast.LENGTH_SHORT).show();
			}
			@Override
			public void leftclick(){
				Toast.makeText(MainActivity.this, "Left Clicked", Toast.LENGTH_SHORT).show();
			}
		});
	}
}

其中实现了Topbar中定义的接口,从而根据不同的需求来添加不同的监听。也可以调用setvisible方法来控制是否显示。

到这里,我们就实现了我们自定义的Topbar,实现了高度的可复用性。

效果如下:

========================================

写在后面:

源代码已上传到我的Github,或者到CSDN下载区下载。

任何问题,欢迎留言交流!

时间: 2024-08-11 07:47:39

Android 轻松设计UI模板的相关文章

Android MVP设计框架模板 之 漂亮ListView上拉刷新下拉加载更多

mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理.MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller. 项目中大部分是面对接口编程,通过P层可以预先将所有需要的接口功能

android自定义UI模板图文详解

不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一个标题的xml文件,然后在需要的地方直接通过include来引用,这比起在每个布局文件中写标题栏已经进化很多了,但仍然不是最简单有效的方法,我们为什么不能自定义一个标题控件呢?今天就带大家自己做一个标题栏控件.效果图如下: 开始啦: 第一步:自定义xml属性 新建一个android项目,在value

看大家android界面设计是拿Android Design UI Kit设计的,不直接在eclipse里设计,但是UI KIT怎么用呢

============问题描述============ Android 4.4 Design UI Kit (Nexus 4 version)打开十psd格式的,看网上说吧psd里面自己需要用到的东西保存为png格式,然后是要把png格式的图片当做android控件的背景使用? 其他类似的工具呢? ============解决方案1============ 一切不问是不是就问为什么的都是耍流氓,不知道你是怎么得出"android界面设计是拿Android Design UI Kit设计的,不直

9款好看又实用的手机APP UI模板

一款优秀的界面设计,最重要的两点应该是产品本身的UI和用户体验(UX),唯有将二者完美结合才能称作优秀的设计作品.但随着智能手机及各类设计工具的发展,用户对手机界面设计的要求也与日俱增.这也就解释了为什么手机应用市场有很多APP功能差不多,但我们只使用一款就够了,而这一款必定有更优的界面设计及用户体验. App界面设计出色与否将直接影响App用户的体验.要提高UI设计水平,除了经历一定的实践及积累,还可以动手临摹或欣赏一些手机UI设计作品,提高审美能力.增加设计灵感.今天小编给大家挑选了9款由国

Android Phone设计介绍

Android Phone设计介绍 在Android之rild进程启动源码分析一文中已经详细介绍了Android的电话系统架构设计,并对rild进程进行了详细的剖析.native层的rild进程负责与底层modem设备交互,比如向modem发送AT命令.从modem中接收消息,同时实时监控modem的状态:作为三层架构设计的Android电话系统:客户端的framework.服务端的rild.modem设备,rild进程还需要接收来自客户端的命令消息,将客户端的需求转发给modem设备,实现对m

安卓app设计规范整理和Android APP设计篇(转)

随着安卓智能手机不停的更新换代.安卓手机系统越来越完美,屏幕尺寸也越来越大啦!比如最近小米的miui 6的发布和魅族手机系统的更新等等. 以小米MIUI6的安卓手机来说,MIUI6进行了全新设计,坚持“内容才是本质”的设计哲学,重新提炼内容,简化图标设计. 所以,我们在进行安卓APP设计时,需要好好调整之前的设计规范和设计细节.根据目前流行的安卓手机的系统体验来完成我们的安卓APP设计规范.应该说这是整理出最全面的安卓app设计规范. 25学堂站在不断更新和完善安卓app设计规范为宗旨!利用周末

Android应用程序UI硬件加速渲染的Display List渲染过程分析

在硬件加速渲染环境中,Android应用程序窗口的UI渲染是分两步进行的.第一步是构建Display List,发生在应用程序进程的Main Thread中:第二步是渲染Display List,发生在应用程序进程的Render Thread中.Display List的渲染不是简单地执行绘制命令,而是包含了一系列优化操作,例如绘制命令的合并执行.本文就详细分析Display List的渲染过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 从前面An

《深入理解Android内核设计思想》

<深入理解Android内核设计思想> 基本信息 作者: 林学森 出版社:人民邮电出版社 ISBN:9787115348418 上架时间:2014-4-25 出版日期:2014 年5月 开本:16开 页码:687 版次:1-1 所属分类:计算机 > 软件与程序设计 > 移动开发 > Android 更多关于>>><深入理解Android内核设计思想> 编辑推荐 基于Android SDK最新版本 全面细致地剖析了进程/线程模型.内存管理.Bind

《深入理解Android内核设计思想》书本目录,及部分章节内容分享

第1篇 android编译篇 第1章 android系统简介 2  1.1 android系统发展历程 2  1.2 android系统特点 4  1.3 android系统框架 8 第2章 android源码下载及编译 10  2.1 android源码下载指南 10  2.1.1 基于repo和git的版本管理 10  2.1.2 android源码下载流程 11  2.2 原生态系统编译指南 12    2.2.1 建立编译环境 13    2.2.2 编译流程 15  2.3 定制产品的