Android custom control-custom Composite Control

Source: Internet
Author: User

Android custom control-custom Composite Control

 

The previous blog posts introduced how to customize controls for Android. In fact, they are about how to "customize from nothing" a brand new control to inherit the View or inherit the ViewGroup, rewrite related methods. This method of custom controls is relatively difficult, and not all new controls are required. In many cases, we only need to make good use of the controls provided by Android and combine them with clever layout. This is a new control, which I call a "custom control combination ".

So, under what circumstances is this custom Composite Control used? When you are working on a project, you may find that some la s will be reused, and the XML code block of the same layout will be repeatedly copied and pasted multiple times. This will cause confusion in the code structure, the amount of code will also increase, and various controls need to be affirmed and processed in Java code. The workload is not small, so you must find a reasonable "lazy" method, how to simplify the unnecessary troubles mentioned above. The following figure shows a simple layout. We use this figure to implement a simple custom Composite Control.

From the analysis above, we can see that there are no "brand new" controls in this layout, and they all use native controls of the Android system. People familiar with the layout of the Android interface must think that this layout is really a small Case. It is too simple and can be written in minutes. The following is the layout code of a Project:

 

 
     
      
       
            
         
     
    
   
  
 
We can see that this layout is indeed quite simple. However, at this time, the product manager tells you that we need to add such an entry on this interface when the requirement is changed. So you think it's easy to do this by pressing Ctrl + C, Ctrl + V, then, modify the Control id and add a piece of logic code in the Java code findviewbyid (id. I didn't expect the product to come again at this time, and the demand was changed. here we need to add 10 such la s, so you... it is true that Ctrl + C and Ctrl + V are not suitable at this time, and the workload will be very heavy. Even if you are not in too much trouble, you will do the same and you will not expect the product to come back, delete a few for me, and add a few for that. Is it crazy.

 

Maybe we can come up with a method of laziness. By analyzing the preceding layout, we can find that each sub-entry in the layout remains unchanged and the layout is identical. The only difference is that, the text in the red TextView changes with the status of the CheckBox. Can we find a way to extract the text to a method? The answer is yes. We can encapsulate the layout of this seed entry into a Java class at a time. Each time we call this control, we can set various attribute data in advance. This involves custom attributes, for more information about custom attributes, see the Android custom control-Custom Attributes in my previous blog. Analyze how to define this property set. From the image above, we can see that the content to be set on the control is the title of the TextView above and the description of the TextView below, the description information is changed according to the CheckBox status. Therefore, both States (true or false) need to be defined in the attribute set, so the attribute set will be available.

In the res/values directory of the project, create the attrs. xml file and define the following property set:

 

 
     
                              
  
 

After defining the property set, we need to define a Java class to render this layout, parse this property set, and provide the method for modifying the control status of the object, which has achieved the effect of reuse. The question is, which class should we define to inherit from this Java class? Here, we do not need to consider the View, because it is not a brand new custom control, and we do not need onMessure and onDraw to measure to draw a View. What about ViewGroup? We do not need to use this class, because the layout here is given, and we do not need to use onLayout to set the display position for the Child control. So what should we inherit? Can we imagine if the subclass of ViewGroup is okay? In addition to inheriting views and viewgroups, custom controls can also be directly inherited from existing Android controls for modification. This idea is not hard to imagine. Because the relative layout RelativeLayout is used in the layout file, we can customize the Java class to inherit this RelativeLayout. Some parameters and methods are provided in RelativeLayout to facilitate the layout of child controls. However, we have already written the child control layout directly here, and do not need to use the parameters and methods provided by RelativeLayout for layout. Therefore, even if you do not inherit RelativeLayout, you can change it to LinearLayout, FrameLayout... as long as the layout class is a subclass of ViewGroup. The following is the implementation code of the custom Composite Control:

 

Package com. example. combinationview; import android. content. context; import android. util. attributeSet; import android. view. view; import android. widget. checkBox; import android. widget. relativeLayout; import android. widget. textView; public class CombinationView extends RelativeLayout {private TextView TV _title; private TextView TV _desc; private CheckBox cb_status; // namespace. When referencing this custom component, private String names is required. Pace = http://schemas.android.com/apk/res/com.example.combinationview;// title private String title; // selected Description private String desc_on; // unselected description private String desc_off; public CombinationView (Context context, AttributeSet attrs) {super (context, attrs); // render the layout of the custom composite control into ViewView view = View. inflate (context, R. layout. layout_combinationview, this); TV _title = (TextView) view. findViewById (R. id. TV _title); TV _des C = (TextView) view. findViewById (R. id. TV _desc); cb_status = (CheckBox) view. findViewById (R. id. cb_status); title = attrs. getAttributeValue (namespace, title); desc_on = attrs. getAttributeValue (namespace, desc_on); desc_off = attrs. getAttributeValue (namespace, desc_off); System. out. println (title +: + desc_on +: + desc_off); // initialize the sub-control if (title! = Null) {TV _title.setText (title);} if (desc_off! = Null) {TV _desc.setText (desc_off) ;}/ *** determines if it is selected ** @ return */public boolean isChecked () {return cb_status.isChecked ();} /*** set the selected status ** @ param isChecked */public void setChecked (boolean isChecked) {cb_status.setChecked (isChecked); if (isChecked) {TV _desc.setText (desc_on );} else {TV _desc.setText (desc_off );}}}
The code is very simple. First, inherit RelativeLayout, rewrite its constructor method, render the Layout View in the constructor, and then read the attributes of the attribute set, display the default properties to the Child control on the layout. In addition, an isChecked () method is also provided to determine whether the control is selected. A setChecked (boolean) method is provided to change the status. PS: to verify the above paragraph, the reader can inherit RelativeLayout and inherit LinearLayout or FrameLayout. It can also be implemented by running it.

 

The following describes how to reference this custom composite control. You must first define it in the Activity layout file:

 

     
      
      
      
      
      
      
      
  
 
First, we have defined four custom composite controls. You can see that the code is much simpler, right ?! Note: The custom property set is referenced here, so the namespace must be added to the layout node.
 xmlns:example=http://schemas.android.com/apk/res/com.example.combinationview
Here, example is the namespace name, which is arbitrary, but must be referenced in the control with the same attribute name. Otherwise, an error is reported. The following string indicates the path of the property set. The first half is fixed. The content after the last "/" must be the package name of the project; otherwise, an error is reported.

 

The following is the business logic code in the Activity.

 

package com.example.combinationview;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.app.Activity;public class MainActivity extends Activity implements OnClickListener {private CombinationView cv_first;private CombinationView cv_second;private CombinationView cv_third;private CombinationView cv_fourth;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);cv_first = (CombinationView) findViewById(R.id.cv_first);cv_second = (CombinationView) findViewById(R.id.cv_second);cv_third = (CombinationView) findViewById(R.id.cv_third);cv_fourth = (CombinationView) findViewById(R.id.cv_fourth);cv_first.setOnClickListener(this);cv_second.setOnClickListener(this);cv_third.setOnClickListener(this);cv_fourth.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.cv_first:if (cv_first.isChecked()) {cv_first.setChecked(false);} else {cv_first.setChecked(true);}break;case R.id.cv_second:if (cv_second.isChecked()) {cv_second.setChecked(false);} else {cv_second.setChecked(true);}break;case R.id.cv_third:if (cv_third.isChecked()) {cv_third.setChecked(false);} else {cv_third.setChecked(true);}break;case R.id.cv_fourth:if (cv_fourth.isChecked()) {cv_fourth.setChecked(false);} else {cv_fourth.setChecked(true);}break;default:break;}}}
Well, the custom composite controls are simple but common. When the project is used in the future, think about the implementation steps and customize a combination of controls, which is indeed more convenient to use than simply copying and pasting, it also improves code reusability, simplifies the code structure, and reduces the amount of code.

 

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.