这节讲一下自定义控件的第二种方式:组装控件。
组装控件也可以叫做拼装控件。顾名思义,就是把若干个控件组装在一起,作为一个控件的意思。其实在上一篇就已经有一点组装控件的意思。只不过组装的部分只体现在Dialog内部的一个视图里。而拼装控件也是基于继承控件的,不过拼装控件更多地会使用到LinearLayout等较基本的视图作为父容器,更多地体现拼接的特点。这一节我将做一个导航栏的控件,控件样式固定,但用户可以自由创建任意个导航栏目,并设定栏目点击事件。
在这个例子里我继承一个LinearLayout,拼接的子控件在代码里生成,不另外在xml文件里面定义了。这样就只有一个java类:
/**
* @author Ives
*
*/
public class Navigate extends LinearLayout {
private String[] columnNames;
private OnColumnClickListener mListener;
/**
* @param context
*/
public Navigate(Context context,String[] columnNames) {
super(context);
this.setColumnNames(columnNames);
this.createView();
}
public interface OnColumnClickListener{
public void OnColumnClick(int position);
}
public void setOnColumnClickListener(OnColumnClickListener l){
this.mListener = l;
}
private void createView(){
if(getColumnNames()==null||getColumnNames().length==0)return;
TextView columnTxv;
OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
mListener.OnColumnClick((Integer)v.getTag());
}
};
int length = getColumnNames().length;
for (int i = 0; i < length; i++) {
if(i!=0){ //不是第一个,在前面加分隔线
TextView divider = new TextView(getContext());
divider.setLayoutParams(new LayoutParams(2, LayoutParams.FILL_PARENT));
divider.setBackgroundColor(Color.GRAY);
this.addView(divider);
}
columnTxv = new TextView(getContext());
columnTxv.setLayoutParams(new LayoutParams(100, LayoutParams.WRAP_CONTENT));
columnTxv.setOnClickListener(listener);
columnTxv.setText(getColumnNames()[i]);
columnTxv.setGravity(Gravity.CENTER);
columnTxv.setTag(i); //标记栏目的位置
this.addView(columnTxv); //拼接栏目TextView
}
}
private String[] getColumnNames() {
return columnNames;
}
private void setColumnNames(String[] columnNames) {
this.columnNames = columnNames;
}
}
使用示例如下:
final String[] names = new String[]{"音乐","体育","经济","时事","历史"};
Navigate nav = new Navigate(this,names);
nav.setOnColumnClickListener(new OnColumnClickListener() {
@Override
public void OnColumnClick(int position) {
Toast.makeText(getBaseContext(), names[position], Toast.LENGTH_SHORT).show();
}
});
mainLayout.addView(nav);
效果如下图:
也可以直接在xml文件里面引用。还添加一个attrs属性,使其可以直接在xml里面使用自定义的属性。
写完了这些代码后,我才发现,上一节写的例子不是像,而是已经完全是属于组装控件!上一节我应该写一个更简单点的……
有了这两节的方法,其实大部分的需求都可以实现了。如果还有更复杂的需求,可以考虑使用下一节使用的方式自定义控件。
(转载请标明本来源)