码迷,mamicode.com
首页 > 移动开发 > 详细

Android 轻松设计UI模板

时间:2015-06-07 17:29:48      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:android   控件   布局   模板   topbar   

写在前面:

我们写应用的时候,常常会发现很多界面都是有相同或是相似的部分的,比如相同的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下载区下载。

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




Android 轻松设计UI模板

标签:android   控件   布局   模板   topbar   

原文地址:http://blog.csdn.net/u012422829/article/details/46402167

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!