自定义组合控件的步骤基本大致有如下五个步骤,
首先,继承一个view Group,比如说是linearLayout,relayouy;
然后定义其的相关属性,获取其相关属性,比如说是颜色,大小等;
接着就是加载组合的view,根据属性修改UI/数据,比如面的按键变色;
第四步就是添加处理事件、数据,比如按钮的点击事件;
最后就是定义功能接口,对外暴露设置接口的方法,让外界可以唤醒其功能
下面做一个数字键盘为例,帮助理解自定义组合控件:
开始,定义一个view,继承自view Group,linearLayout:
public class LonginKeyboard extends LinearLayout {
public LonginKeyboard(Context context) {
this(context,null);
}
public LonginKeyboard(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public LonginKeyboard(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//
}
}
第二步,定义相关属性,获取相关属性:比如给颜色,大小,限制等等;
第三步,加载组合的view,根据属性修改UI/数据
比如我这里做一个数字键盘,那么它的布局为
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/number_1"
style="@style/numberKeyPad"
android:text="1" />
<TextView
android:id="@+id/number_2"
style="@style/numberKeyPad"
android:text="2" />
<TextView
android:id="@+id/number_3"
style="@style/numberKeyPad"
android:text="3" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/number_4"
style="@style/numberKeyPad"
android:text="4" />
<TextView
android:id="@+id/number_5"
style="@style/numberKeyPad"
android:text="5" />
<TextView
android:id="@+id/number_6"
style="@style/numberKeyPad"
android:text="6" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/number_7"
style="@style/numberKeyPad"
android:text="7" />
<TextView
android:id="@+id/number_8"
style="@style/numberKeyPad"
android:text="8" />
<TextView
android:id="@+id/number_9"
style="@style/numberKeyPad"
android:text="9" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/number_0"
style="@style/numberKeyPad"
android:text="0" />
<TextView
android:id="@+id/back"
style="@style/numberKeyPad"
android:layout_weight="2"
android:text="删除" />
</LinearLayout>
因为相同因素过多,所以整合在styles.xml里,如下
<style name="numberKeyPad">
<item name="android:gravity">center</item>
<item name="android:background">@drawable/selector_num_key_pad</item>
<item name="android:textColor">#ffffff</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">18sp</item>
<item name="android:layout_margin">4dp</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">50dp</item>
</style>
定义点击提醒,分别在drawable包建立shape_num_key_pad_normal.xml、shape_num_key_pad_press.xml和selector_num_key_pad.xml。
shape_num_key_pad_normal.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#383838"/>
<corners android:radius="5dp"/>
</shape>
shape_num_key_pad_press.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#3838"/>
<corners android:radius="5dp"/>
</shape>
selector_num_key_pad.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_num_key_pad_press"
android:state_pressed="true"/>
<item android:drawable="@drawable/shape_num_key_pad_press"
android:state_enabled="false"/>
<item android:drawable="@drawable/shape_num_key_pad_normal"/>
</selector>
第四步,编写处理事件/数据
在java处增加点击事件:
private static final String TAG = "LonginKeyboard";
public LonginKeyboard(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public LonginKeyboard(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//
LayoutInflater.from(context).inflate(R.layout.num_key_pad,this);
initView();
}
private void initView() {
this.findViewById(R.id.number_1).setOnClickListener(this);
this.findViewById(R.id.number_2).setOnClickListener(this);
this.findViewById(R.id.number_3).setOnClickListener(this);
this.findViewById(R.id.number_4).setOnClickListener(this);
this.findViewById(R.id.number_5).setOnClickListener(this);
this.findViewById(R.id.number_6).setOnClickListener(this);
this.findViewById(R.id.number_7).setOnClickListener(this);
this.findViewById(R.id.number_8).setOnClickListener(this);
this.findViewById(R.id.number_9).setOnClickListener(this);
this.findViewById(R.id.number_0).setOnClickListener(this);
this.findViewById(R.id.back).setOnClickListener(this);
}
@Override
public void onClick(View view) {
int viewId = view.getId();
if (mKeyPressListener == null){
Log.d(TAG,"mKeyPressListener is null need not call back ..");
return;
}
if (viewId == R.id.back){
//走back
mKeyPressListener.OnBackPress();
}else {
//走数字结果通知
String text = ((TextView) view).getText().toString();
Log.d(TAG,"click text is ->"+text);
mKeyPressListener.OnNumberPress(Integer.parseInt(text));
}
}
最后一步:定义功能接口,对外暴露设置接口方法
public void serOnKeyPressListener(OnKeyPressListener listener){
this.mKeyPressListener = listener;
}
public interface OnKeyPressListener{
void OnNumberPress(int number);
void OnBackPress();
}
结果如下: