二、Android 自定義組合控制元件
阿新 • • 發佈:2020-12-15
技術標籤:Android
二、自定義組合控制元件
開發步驟
- 繼承自linearLayout或者RelativeLayout
- 定義相關屬性,獲取屬性(自定義屬性)
- 載入組合View,初始化值
- 處理相關事件(如按鈕的點選事件)
- 定義功能介面,對外暴露方法(把值傳到外面)
例子:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity ="center"
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:id="@+id/btn_minus"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background ="@drawable/selector_num_btn_bg_left"
android:gravity="center"
android:text="-"
android:textSize="30sp" />
<EditText
android:id="@+id/edt_value"
android:layout_width="80dp"
android:layout_height ="match_parent"
android:background="@drawable/shape_num_inp_bg"
android:focusable="false"
android:gravity="center"
android:text="0"
android:textSize="14sp" />
<TextView
android:id="@+id/btn_plus"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="@drawable/selector_num_btn_bg_right"
android:gravity="center"
android:text="+"
android:textSize="20sp" />
</LinearLayout>
1、繼承RelativeLayout,三個構造方法統一入口
// 1 繼承relativeLayout
public InputNumberView(Context context) {
this(context, null);
}
public InputNumberView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InputNumberView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 獲取相關屬性
initAttrs(context, attrs);
// 初始化控制元件
initView(context);
// 處理事件
initEvent();
}
2、定義相關屬性,獲取屬性
values -> attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="InputNumberView">
<attr name="max" format="integer"/>
<attr name="min" format="integer"/>
<attr name="step" format="integer"/>
<attr name="defaultValue" format="integer"/>
<attr name="disabled" format="boolean"/>
<attr name="btnColor" format="reference"/>
<!-- dp sp px -->
<attr name="valueSize" format="dimension"/>
</declare-styleable>
</resources>
獲取屬性值
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.InputNumberView);
mMax = a.getInteger(R.styleable.InputNumberView_max, 0);
mMin = a.getInteger(R.styleable.InputNumberView_min, 0);
mStep = a.getInteger(R.styleable.InputNumberView_step, 1);
mDefaultValue = a.getInteger(R.styleable.InputNumberView_defaultValue, 1);
this.currentNumber = mDefaultValue;
mDisabled = a.getBoolean(R.styleable.InputNumberView_disabled, false);
mBtnColor = a.getResourceId(R.styleable.InputNumberView_btnColor, -1);
a.recycle();
}
使用:
<com.dy.viewstudy01.InputNumberView
android:id="@+id/input_number"
app:max="10"
app:min="-10"
app:step="2"
app:disabled="true"
app:defaultValue="5"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
3、載入View
private void initView(Context context) {
// 2 載入view
LayoutInflater.from(context).inflate(R.layout.input_number_view, this);
mBtnMinus = findViewById(R.id.btn_minus);
mBtnPlus = findViewById(R.id.btn_plus);
mEdtValue = findViewById(R.id.edt_value);
// 初始化控制元件值
updateText();
}
4、處理事件
private void initEvent() {
mBtnMinus.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (currentNumber <= mMin)
return;
currentNumber -= mStep;
updateText();
}
});
mBtnPlus.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (currentNumber >= mMax)
return;
currentNumber += mStep;
updateText();
}
});
}
5、定義介面,暴露方法(這裡是為了在外面獲取到currentNumber的值)
private onNumberChangeListener onNumberChangeListener = null;
private void updateText() {
mEdtValue.setText(String.valueOf(currentNumber));
if (onNumberChangeListener != null)
// 傳值出去
onNumberChangeListener.onNumberChange(this.currentNumber);
}
// 暴露方法
public void setOnNumberChangeListener(onNumberChangeListener listener) {
this.onNumberChangeListener = listener;
}
// 介面
interface onNumberChangeListener {
void onNumberChange(int value);
}
使用:
public class MainActivity extends AppCompatActivity implements InputNumberView.onNumberChangeListener {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InputNumberView inputNumberView = findViewById(R.id.input_number);
inputNumberView.setOnNumberChangeListener(this);
}
@Override
public void onNumberChange(int value) {
// value就是傳來出的值
Log.e(TAG,"current value is -> " + value);
}
}
樣式的修改:
1、用xml檔案繪製背景圖,drawable -> shape_XXXX.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1E90FF"/>
<corners android:bottomLeftRadius="10dp"
android:topLeftRadius="10dp"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#F8F8FF"/>
<stroke android:width="2dp"
android:color="#ADD8E6"/>
</shape>
2、點選效果,drawable -> selector_XXX.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/shape_num_btn_bg_left_press"/>
<item android:drawable="@drawable/shape_num_btn_bg_left"/>
</selector>