对于每一个应用来说几乎都会有一个Topbar,并且基本都是类似的那么假如应用有好多个页面的话,就要写好多遍,可以在Topbar整合为一个控件来使用,针对于这个的学习,总结如下:
1 atts自定义属性的定义
res–values-atts.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Topbar">
<attr name="titleMiddle" format="string"/>
<attr name="titleTextSize" format="dimension"/>
<attr name="titleTextColor" format="color"/>
<attr name="leftTextColor" format="color"/>
<attr name="leftBackgroubd" format="reference|color"/>
<attr name="leftText" format="string"/>
<attr name="rightTextColor" format="color"/>
<attr name="rightBackgroubd" format="reference|color"/>
<attr name="rightText" format="string"/>
</declare-styleable>
</resources>
2 自定义Topbar类继承RelativeLayout
package com.example.mytobbar;
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;
public class Topbar extends RelativeLayout{
//定义自定义的属性对应的控件
private Button leftButton,rightButton;
private TextView tvTextView;
private int leftTextColor;
private Drawable leftbackground;
private String leftText;
private int rightTextColor;
private Drawable rightbackground;
private String rightText;
private float titleTextSize;
private int titleTextColor;
private String titleText;
private LayoutParams leftParams,rightParams,titleParams; //用于把控件放到布局中
//定义一个借口 用于点击事件方法的回调
public interface TopbarOnClick{
public void leftOnClick();
public void rightOnClick();
public void titleOnClick();
}
//接口的实例,作为类的成员变量
private TopbarOnClick click;
//对外暴露一个方法 把借口作为参数传入 就能回调到接口中的方法
public void setTopbarOnClick(TopbarOnClick click){
this.click=click;
}
public Topbar(Context context, AttributeSet attrs) {
super(context, attrs);
//是控件和自定义的属性相连接
/*
* 1 建立映射,获取自定义的属性集合获取一个typedArray的数据结果,可以在typedArray中取出相应的值
* 2 获取对应的值,建立映射 1 相当于map的key在atts的名字 2 默认的属性设置
* 3 使用完回收 避免浪费资源 避免错误
* */
//获取自定义的属性集合
TypedArray ad=context.obtainStyledAttributes(attrs, R.styleable.Topbar);
//获取对应的值,建立映射 相当于map的key在atts的名字 0 默认的属性设置
leftTextColor=ad.getColor(R.styleable.Topbar_leftTextColor, 0);
leftbackground=ad.getDrawable(R.styleable.Topbar_leftBackgroubd);
leftText=ad.getString(R.styleable.Topbar_leftText);
rightTextColor=ad.getColor(R.styleable.Topbar_rightTextColor, 0);
rightbackground=ad.getDrawable(R.styleable.Topbar_rightBackgroubd);
rightText=ad.getString(R.styleable.Topbar_rightText);
titleTextSize=ad.getDimension(R.styleable.Topbar_titleTextSize, 0);
titleTextColor=ad.getColor(R.styleable.Topbar_titleTextColor,0);
titleText=ad.getString(R.styleable.Topbar_titleMiddle);
// 使用完回收 避免浪费资源 避免错误
ad.recycle();
//实例化控件
leftButton=new Button(context);
rightButton=new Button(context);
tvTextView=new TextView(context);
//将自定义的属性付给控件
leftButton.setText(leftText);
leftButton.setBackground(leftbackground);
leftButton.setTextColor(leftTextColor);
rightButton.setText(rightText);
rightButton.setBackground(rightbackground);
rightButton.setTextColor(rightTextColor);
tvTextView.setText(titleText);
tvTextView.setTextColor(titleTextColor);
tvTextView.setTextSize(titleTextSize);
tvTextView.setGravity(Gravity.CENTER);
setBackgroundColor(0XFFF59563); //给view设置背景色
//把定义的控件放到布局中
leftParams=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);//控件是包裹内容的
leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); //添加限制条件 居左 相对布局才有的属性 自定义控件用那上级谁的属性多最好就继承谁来自定义
addView(leftButton, leftParams);
//设置button的大小可以设置固定的值 就不会导致背景过大 像效果图一样了
rightParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
rightParams.setMargins(30, 0, 30, 0);
addView(rightButton, rightParams);
titleParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(tvTextView,titleParams);
//添加点击事件
leftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//点击事件调用类中接口的方法,便会调用此接口的实体的方法
click.leftOnClick();
}
});
rightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
click.rightOnClick();
}
});
tvTextView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
click.titleOnClick();
}
});
}
}
3 布局文件中使用自定义的控件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
//自定义属性的命名空间com.example.mytobbar 为自定义控件类的包名
xmlns:demoa="http://schemas.android.com/apk/res/com.example.mytobbar"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.example.mytobbar.Topbar
android:id="@+id/topbar"
android:layout_width="fill_parent"
android:layout_height="50dp"
demoa:titleMiddle="中间标题"
demoa:titleTextSize="15sp"
demoa:titleTextColor="#FFFFFF"
demoa:leftTextColor="#00FF00"
demoa:rightTextColor="#FFFFFF"
demoa:rightBackgroubd="@drawable/nothing_image"
demoa:leftBackgroubd="@drawable/ic_launcher"
demoa:leftText="左边"
demoa:rightText="右边"
>
</com.example.mytobbar.Topbar>
</RelativeLayout>
4在activity中使用
package com.example.mytobbar;
import com.example.mytobbar.Topbar.TopbarOnClick;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.os.Build;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
Topbar topbar = (Topbar) findViewById(R.id.topbar);
topbar.setTopbarOnClick(new TopbarOnClick() {
@Override
public void titleOnClick() {
Toast.makeText(getApplicationContext(), "title", 0).show();
}
@Override
public void rightOnClick() {
Toast.makeText(getApplicationContext(), "right", 0).show();
}
@Override
public void leftOnClick() {
Toast.makeText(getApplicationContext(), "left", 0).show();
}
});
}
}
其中添加点击事件用到了接口的回调
添加接口回调的方法:
- 1 在自定义的类中定义接口,并在接口中定义需要回调的方法
-
//定义一个借口 用于点击事件方法的回调
public interface TopbarOnClick{
public void leftOnClick();
public void rightOnClick();
public void titleOnClick();
}
//接口的实例,作为类的成员变量
private TopbarOnClick click;
- 2 在自定义的类中写一个对外暴露的方法,把定义的接口作为方法的参数
- `
//对外暴露一个方法 把借口作为参数传入 就能回调到接口中的方法
public void setTopbarOnClick(TopbarOnClick click){
this.click=click;
}
- 3 在自定义的类中添加点击事件调用接口类的方法进行操作
` //添加点击事件
leftButton.setOnClickListener(new OnClickListener() {@Override public void onClick(View v) { //点击事件调用类中接口的方法,便会调用此接口的实体的方法 click.leftOnClick(); } });`
- 4 在需要调用自定义控件作为布局文件的activity中调用对外暴露的方法,这样当点击button时便会调用接口的方法,进而便会调用接口实体中实现的方法,就完成了回调
`topbar.setTopbarOnClick(new TopbarOnClick() {
@Override public void titleOnClick() { Toast.makeText(getApplicationContext(), "title", 0).show(); } @Override public void rightOnClick() { Toast.makeText(getApplicationContext(), "right", 0).show(); } @Override public void leftOnClick() { Toast.makeText(getApplicationContext(), "left", 0).show(); } });`
-