先上代码
<!-- 1。设计所需要的属性--> <resources> <declare-styleable name="Topbar"> <attr name="topTitle" format="string" /> <attr name="topTitleTextSize" format="dimension" /> <attr name="topTitleTextColor" format="color" /> <attr name="leftTextColor" format="color" /> <attr name="leftBackground" format="reference|color" /> <attr name="leftText" format="string" /> <attr name="rightTextColor" format="color" /> <attr name="rightBackground" format="reference|color" /> <attr name="rightText" format="string" /> </declare-styleable> </resources>
/** * 2.实现我们的一个view */ public class Topbar extends RelativeLayout { private Button leftButton, rightButton; private TextView tvTitle; private int leftTextColor; private Drawable leftBackground; private String leftText; private int rightTextColor; private Drawable rightBackground; private String rightText; private int topTitleTextColor; private float topTitleTextSize; private String topTitle; private LayoutParams leftParams, rightParams, titleParams; public Topbar(Context context, AttributeSet attrs) { super(context, attrs); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Topbar); leftTextColor = ta.getColor(R.styleable.Topbar_leftTextColor, 0); leftBackground = ta.getDrawable(R.styleable.Topbar_leftBackground); leftText = ta.getString(R.styleable.Topbar_leftText); rightTextColor = ta.getColor(R.styleable.Topbar_rightTextColor, 0); rightBackground = ta.getDrawable(R.styleable.Topbar_rightBackground); rightText = ta.getString(R.styleable.Topbar_rightText); topTitleTextSize = ta.getDimension(R.styleable.Topbar_topTitleTextSize, 0); topTitleTextColor = ta.getColor(R.styleable.Topbar_topTitleTextColor, 0); topTitle = ta.getString(R.styleable.Topbar_topTitle); ta.recycle(); leftButton = new Button(context); rightButton = new Button(context); tvTitle = new TextView(context); leftButton.setTextColor(leftTextColor); leftButton.setText(leftText); leftButton.setBackground(leftBackground); rightButton.setTextColor(rightTextColor); rightButton.setText(rightText); rightButton.setBackground(rightBackground); tvTitle.setTextColor(topTitleTextColor); tvTitle.setTextSize(topTitleTextSize); tvTitle.setText(topTitle); tvTitle.setGravity(Gravity.CENTER); setBackgroundColor(0xfff54545); leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); addView(leftButton, leftParams); rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE); addView(rightButton, rightParams); titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE); addView(tvTitle, 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(); } }); } public interface topbarClickListener { public void leftClick(); public void rightClick(); } private topbarClickListener listener; public void setOnTopbarClickListener(topbarClickListener listener) { this.listener = listener; } //更细节功能 public void setLeftIsVisable(boolean flag){ if(flag){ leftButton.setVisibility(View.VISIBLE); }else { leftButton.setVisibility(View.GONE); } } }3.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.sks.androiduicustom.Topbar android:id="@+id/topbar" android:layout_width="match_parent" android:layout_height="40dp" custom:leftBackground="#00ff00" custom:leftText="Back" custom:leftTextColor="#ffffff" custom:rightBackground="#00ff00" custom:rightText="More" custom:rightTextColor="#ffffff" custom:topTitle="自定义标题" custom:topTitleTextColor="#123412" custom:topTitleTextSize="18sp"></com.example.sks.androiduicustom.Topbar> </RelativeLayout>4.MainAcitivity
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.setOnTopbarClickListener(new Topbar.topbarClickListener() { @Override public void leftClick() { Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show(); } @Override public void rightClick() { Toast.makeText(MainActivity.this, "right", Toast.LENGTH_LONG).show(); } }); topbar.setLeftIsVisable(false); } }
摘了一些笔记:
在studio中引用自定义命名空间直接调用res-auto即可
xmlns:custom="http://schmas.android.com/apk/res-auto"
·custom:leftText and so on
重写控件,满足要求
1. 自定义一个Topbar类View继承自RelativeLayout
如果Topbar UI模板(View)需要自定义属性,其构造函数就要使用public Topbar(Context context, AttributeSet attrs)
2. 定义UI模板中的三个控件,声明要使用的属性
private Button leftButton, rightButton;
private TextView tvTitle;
3. 给这些控件赋值,将属性和控件关联起来。在构造函数获得在xml中自定义的属性,并把这些属性值赋给这些控件
(1)通过TypeArray这个数据结构,来存储从xml中获取的自定义属性的值
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Topbar);
其中obtainStyledAttributes(AttributeSet set, int[] attrs)第二个参数为xml定义的属性集合,所以为R.styleable.Topbar
通过这种方法,把在xml自定义的属性值映射到所定义的自定义属性中去,然后返回TypeArray变量。
TypedArray类似于Map键值对,这个变量包含了所有属性和值的映射。
(2)从TypedArray中获取属性值
leftTextColor = ta.getColor(R.styleable.Topbar_leftTextColor, 0);
这里是通过下划线的方式连接Topbar自定义属性和属性的名字,得到一个引用名。后面0是默认值。
通过这种方法就从TypedArray中取出所有的属性值,并赋值给相应的变量。
(3)实例化控件
leftButton = new Button(context);
rightButton = new Button(context);
tvTitle = new TextView(context);
(4)将前面获得属性值赋给这些控件
leftButton.setTextColor(leftTextColor);
leftButton.setBackground(leftBackground);
leftButton.setText(leftText);