Android中的接口回调机制(自定义View——TopBar讲解)

Demo下载:http://download.csdn.net/detail/zq13561411965/9071503

自定义View

TopBar——每个应用顶部,随着页面的切换上面的bar显示的内容不同。抽取出一个ViewUI模板,就要用到自定义View。
TopBar——左边,一个按钮(一般用户返回);右边,一个按钮;中间,Title(一般用来显示当前页面Title)。
在xml中布局的时候,LinearLayout就可以看作是一个自定义的View,在每一个属性前面都要加上android:(例如在定义宽度的时候前面加上android:layout_width),为什么要加上这个android? 就是因为在创建xml时候默认创建的包名称就是android,在java文件中使用import来到导入一个包,在xml中使用 xmlns: android = "http://schemas.android.com/apk/res/android"   导入一个外部的资源文件,就用android来替代这个引入的资源文件,android:layout_width....现在知道android 是什么意思了吧,那么为什么layout_width就是表示宽度呢,这就是接下来要说的View的属性文件:先看代码:
<?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,使用这样的文件来定义一个控件的属性。
在java文件中创建一个类,继承Relativelayout,选择相应的构造方法,创建映射集合等等,具体代码看下面:
/**
 * @Title: TopBar.java
 * @Package com.sloop.topbar
 * @Copyright: Copyright (c) 2015
 * 
 * @author sloop
 * @date 2015年5月28日 下午7:04:23
 * @version V1.0
 */
package com.sloop.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
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;

import com.sloop.topbar.R;


/**
 * @ClassName: TopBar
 */
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 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);
		}
	}

	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();
			}
		});
	}

}

值得注意的是创建出来的自定义属性和值的映射集合在不用的时候要手动释放一下。

接口回掉的使用

andriod中的Button的监听就是利用接口回掉机制来实现的,在源码中实现接口毁掉的实现是很清晰的,我们创建这个TopBar中也是使用了接口回掉的机制来实现的按钮监听,下面我们来简单说一下:
1.定义接口
public interface OnClickListener {
   
    public void OnClick(Button b);
 
}
2. 定义Button
public class Button {
  OnClickListener listener;
 
  public void click() {
    listener.OnClick(this);
  }
  public void setOnClickListener(OnClickListener listener) {
    this.listener = listener;
  }
}
3. 将接口对象OnClickListener 赋给 Button的接口成员
public class Activity {
  public Activity() {
  }
  public static void main(String[] args) {
    Button button = new Button();
    button.setOnClickListener(new OnClickListener(){
       @Override
       public void OnClick(Button b) {
                 System.out.println("clicked");
       }   
    });
    button.click(); //user click,System call button.click();
  }
}

Android事件侦听器是视图View类的接口,包含一个单独的回调方法。这些方法将在视图中注册的侦听器被用户界面操作触发时由Android框架调用。回调方法被包含在Android事件侦听器接口中:

例如,Android 的view 对象都含有一个命名为 OnClickListener 接口成员变量,用户的点击操作都会交给 OnClickListener的 OnClick() 方法进行处理。

开发者若需要对点击事件做处理,可以定义一个 OnClickListener 接口对象,赋给需要被点击的 view的接口成员变量OnClickListener,一般是用 view 的setOnClickListener() 函数来完成这一操作。

当有用户点击事件时,系统就会回调被点击view的OnClickListener接口成员的OnClick()方法。




你可能感兴趣的:(android)