步骤一: 先在values 里 新建一个attrs.xml 来设置我们的属性值:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="TopBar" > <attr name="title" format="string"/> <attr name="titleTextSize" format="dimension"/> <attr name="titleTextColor" format="color"/> <attr name="leftText" format="string"/> <attr name="leftBackground" format="reference|color"/> <attr name="leftTextColor" format="color"/> <attr name="rightText" format="string"/> <attr name="rightBackground" format="reference|color"/> <attr name="rightTextColor" format="color"/> </declare-styleable> </resources>
步骤二: 新建Topbar类继承自RelaiveLayout :
/** * Created by Ace on 2016/2/3. */ public class Topbar extends RelativeLayout { //声明我们需要的控件 private Button leftButton,rightButton; private TextView tv_title; private int leftTextColor; private String leftText; private Drawable leftBackground; private int rightTextColor; private String rightText; private Drawable rightBackground; private String title; private int titleTextColor; private float titleTextSize; //4 定义布局属性 private LayoutParams leftParams , rightParams,titleParams; public Topbar(Context context, AttributeSet attrs) { super(context, attrs); //1 通过 context.obtainStyledAttributes 得到 TypedArray对象 并拿到属性值 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar); leftText = ta.getString(R.styleable.TopBar_leftText); leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0); leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground); rightText = ta.getString(R.styleable.TopBar_rightText); rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0); rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground); title = ta.getString(R.styleable.TopBar_title); titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0); titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 0); //记得回收下 防止出现一些内存问题 ta.recycle(); // 2 new出控件 leftButton = new Button(context); rightButton = new Button(context); tv_title = new TextView(context); //3 把自定义的属性赋给控件 leftButton.setTextColor(leftTextColor); leftButton.setBackground(leftBackground); leftButton.setText(leftText); rightButton.setTextColor(rightTextColor); rightButton.setBackground(rightBackground); rightButton.setText(rightText); tv_title.setTextColor(titleTextColor); tv_title.setTextSize(titleTextSize); tv_title.setText(title); tv_title.setGravity(Gravity.CENTER); setBackgroundColor(0xFFF59563); // 5 new出LayoutParams 设置宽高 leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); // 6 设置规则 可以看出LayoutParams布局参数就是把你的控件以什么样的方式显示在组合控件 leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); //7 添加到布局中(控件,布局参数) addView(leftButton ,leftParams); rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); addView(rightButton, rightParams); titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.MATCH_PARENT); titleParams.addRule(RelativeLayout.CENTER_IN_PARENT); addView(tv_title,titleParams); //8 TopBar的静态部分已经完毕了 到这一步就很明白了 我们采用的组合方式,用系统以及有的控件组合在一起,组成一个新的控件,这个思路是否可以延伸到其他地方呢?思考下 } }
步骤三: 再Activity_main.xml中设置我们的自定义Topbar 重点我用红色和黄色标出,系统 xmlns(xml name space)的是:android 那么我们自己定义当然要有个个性的名字 我就写ace了, 再看后面res-auto ,这部分是控件属性资源地址.用AS的小伙伴
用res-auto就可以了 eslipse的小伙伴要写完整的地址 xmlns:XXXXXX="http://schemas.android.com/apk/res/包路径"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ace="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="zb.com.topbardemo.MainActivity"> <zb.com.topbardemo.Topbar android:id="@+id/topbar" android:layout_width="wrap_content" android:layout_height="40dp" ace:leftTextColor = "#FFFFFF" ace:leftText ="后退" ace:leftBackground = "#4e32b4" ace:rightTextColor = "#FFFFFF" ace:rightText ="设置" ace:rightBackground = "#4e32b4" ace:title = "我是ACE" ace:titleTextColor = "#e20f0f" ace:titleTextSize = "15sp" > </zb.com.topbardemo.Topbar> </RelativeLayout>
静态部分完成现在写Topbar的点击事件 在Topbar类里写 :
leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context,"Ace Left",Toast.LENGTH_LONG).show(); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context,"Ace Right",Toast.LENGTH_LONG).show(); } });
这样是可以 但是却把按钮的点击事件写死了,我们要根据不同情况调用不同的点击事件就无法实现
.要解决这个问题那么要用到接口回调,系统也是如此来做得. OnclickListener是一个接口 那么我们也新建一个接口topbarClickListener,添加两个方法(左Button的点击和右Button的点击)
package zb.com.topbardemo; 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.view.ViewGroup; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; /** * Created by Ace on 2016/2/3. */
//定义一个topbarClickListener private topbarClickListener mListner; //定义一个接口 两个方法
public interface topbarClickListener{ public void leftClick(); public void rightClick(); } //暴露一个方法用来设置点击事件 并映射用户传进来的listner
public void setTopbarClickListner(topbarClickListener listner){ mListner = listner; } . . . . . .中间的代码省略跟前面一样不用变动 . . . . . leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mListner.leftClick(); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mListner.rightClick(); } }); } }
这样 按钮的点击按钮要做什么完全取决于用户来设置
我们用我们自己的方法来设置点击事件
MainActivity:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Topbar topbar =(Topbar)findViewById(R.id.topbar); topbar.setTopbarClickListner(new Topbar.topbarClickListener() { @Override public void leftClick() { Toast.makeText(MainActivity.this,"Ace left",Toast.LENGTH_LONG).show(); } @Override public void rightClick() { Toast.makeText(MainActivity.this,"Ace right",Toast.LENGTH_LONG).show(); } }); } }
我的AS出了点问题 暂时没有截图 抱歉~~~