Custom View classification
- Inherit View to override onDraw method. Achieve some irregular effects. You need to support wrap_content, and you need to handle the padding.
- Inherit from ViewGroup to derive a special Layout. Implement custom layouts. You need to properly handle the measurement and layout of the ViewGroup, as well as the measurement and layout of the child elements.
- Inherits a particular View (such as a TextView). For extension. You don’t need to support wrap_content,padding, etc.
- Inherit a specific ViewGroup (such as a LinearLayout). For extension. You don’t have to deal with the measurement and layout of the ViewGroup.
Inheriting existing controls
This is a relatively simple implementation. Because most of the core work, such as the measurement of control size, control placement and other related calculations, has been implemented and packaged in the system, developers only need to make some extensions on its basis, and according to their own intention to display the corresponding UI elements. For example:
public class CustomToolBar extends RelativeLayout {
private ImageView leftImg, rightImg;
private TextView titleTextView;
//1. Declare an interface
public interface ImgClickListener{
public void leftImgClick(a);
public void rightImgClick(a);
}
// create an interface variable
private ImgClickListener imgClickListener;
//3. Declare a set method for the interface variable,
public void setImgClickListener(ImgClickListener imgClickListener) {
this.imgClickListener = imgClickListener;
}
public CustomToolBar(Context context) {
this(context, null);
}
public CustomToolBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomToolBar(final Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
titleTextView = new TextView(context);
leftImg = new ImageView(context);
leftImg.setPadding(12.12.12.12);
rightImg = new ImageView(context);
rightImg.setPadding(12.12.12.12);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomToolBar);
String titleText = ta.getString(R.styleable.CustomToolBar_titleText);
// The second argument represents the default color
int titleTextColor = ta.getColor(R.styleable.CustomToolBar_myTitleTextColor, Color.BLACK);
// Has been changed from sp to px
float titleTextSize = ta.getDimension(R.styleable.CustomToolBar_titleTextSize, 12);
// Read the image
Drawable leftDrawable = ta.getDrawable(R.styleable.CustomToolBar_leftImageSrc);
Drawable rightDrawable = ta.getDrawable(R.styleable.CustomToolBar_rightImageSrc);
/ / recycling TypedArray
ta.recycle();
leftImg.setImageDrawable(leftDrawable);
rightImg.setImageDrawable(rightDrawable);
titleTextView.setText(titleText);
titleTextView.setTextSize(titleTextSize);
titleTextView.setTextColor(titleTextColor);
// When you set LayoutParams for a control, select the parent container of that control
LayoutParams leftParams = new LayoutParams((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, getResources().getDisplayMetrics()),
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, getResources().getDisplayMetrics()));
// indicates the left alignment of the control with the parent container
leftParams.addRule(ALIGN_PARENT_LEFT, TRUE);
this.addView(leftImg, leftParams);
LayoutParams titleParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
titleParams.addRule(CENTER_IN_PARENT, TRUE);
addView(titleTextView, titleParams);
LayoutParams rightParams = new LayoutParams((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, getResources().getDisplayMetrics()),
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, getResources().getDisplayMetrics()));
rightParams.addRule(ALIGN_PARENT_RIGHT, TRUE);
addView(rightImg, rightParams);
//4. Call the method in the interface when clicking ImageView
leftImg.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(imgClickListener! =null) { imgClickListener.leftImgClick(); }}}); rightImg.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(imgClickListener! =null) { imgClickListener.rightImgClick(); }}}); }}Copy the code
Custom attributes
Sometimes when we want to use CustomToolBar in an XML layout file, we want to specify the display content of title, font color, leftImage and rightImage images, and so on directly in the XML file. This requires the use of custom attributes. The steps for customizing attributes are as follows:
Declare custom attributes in attrs.xml
In the attrs.xml file in the VALUES directory of res (without creating a new one yourself), use the tag to customize the attributes as follows:
<resources>
<declare-styleable name="CustomToolBar">
<attr name="titleText" format="string|reference"/>
<attr name="myTitleTextColor" format="color|reference"/>
<attr name="titleTextSize" format="dimension|reference"/>
<attr name="leftImageSrc" format="reference"/>
<attr name="rightImageSrc" format="reference"/>
</declare-styleable>
</resources>
Copy the code
Explanation:
- The tag represents defining a collection of custom properties, which are commonly used in conjunction with custom controls.
- A label is a specific attribute. Name is the name of the attribute, and format is the format of the attribute.
Use custom attributes in XML layout files
You need to add the namespace XMLNS :app, and then reference the custom properties through the namespace app, passing in the appropriate image resource and string content.
xmlns:app="http://schemas.android.com/apk/res-auto"
Copy the code
Gets the reference value of the custom property in the CustomToolBar
public CustomToolBar(Context context, AttributeSet attrs) {
super(context, attrs);
/ / mainly through the Context. ObtainStyleAttributes method access to custom properties of the set, and then from the collection to retrieve the corresponding custom properties.
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.CustomToolBar);
String titleText = ta.getString(R.styleable.CustomToolBar_titleText);
int titleTextColor = ta.getColor(R.styleable.CustomToolBar_myTitleTextColor, Color.BLACK);
// Has been changed from sp to px
float titleTextSize = ta.getDimension(R.styleable.CustomToolBar_titleTextSize,12);
// Read the image
Drawable leftDrawable = ta.getDrawable(R.styleable.CustomToolBar_leftImageSrc);
Drawable rightDrawable = ta.getDrawable(R.styleable.CustomToolBar_rightImageSrc);
}
Copy the code
Directly inherits from a View or ViewGroup
This approach is more cumbersome than the first, but it is more flexible and allows for more complex UI interfaces. In general, the following issues need to be addressed with this implementation:
- Customize the size of the control, that is, how much width and height are set respectively;
- If it is a ViewGroup, how to reasonably arrange the placement of its internal sub-views;
- How to draw UI elements to the interface based on the corresponding properties.
The above three problems can be solved in the following three methods:
- onMeasure
- onLayout
- onDraw
Therefore, the focus of custom View is actually copy and reasonable implementation of these three methods. Note: Not every custom View needs to implement these three methods, and most of the time implementing only two or even one of these methods will suffice.
note
Welcome to follow wechat official account:No reason also