Android View the basic writing method of the custom combined control _android

Source: Internet
Author: User
Tags getcolor

There are a lot of situations where we just use Android to provide me with good controls, a neat combination of layouts, a new control that I call "Custom combo controls."

So, under what circumstances is this custom composite control used? Or when you're doing a project, you'll find that some of the layouts will be reused, the same layout of the XML block will be duplicated repeatedly paste many times, which will cause confusion in the code structure does not say that the amount of code will be increased, the various controls need to be in the Java code to be declared and processing the corresponding logic, the workload is really not small, so, It is necessary to find a reasonable "lazy" way to start the brain to simplify the above mentioned unnecessary trouble. Let's look at a diagram, a simple layout, and we'll implement a simple, custom combination control on this map.

From the above diagram, we can see that there are no "brand new" controls in this layout, and that they are all native controls of the Android system. Familiar with the Android interface layout, people must feel that this layout is really small case, too simple, minutes can be completed. So here's the layout code for an entry:

<!--? XML version=1.0 encoding=utf-8?--> <relativelayout android:background= "@drawable/selector_blue" Android:id= "@+id/rl_show_address" android:layout_height= "60dip" android:layout_width= "Match_parent" xmlns:android = "Http://schemas.android.com/apk/res/android" > <textview android:id= "@+id/tv_title" android:layout_height= " Wrap_content "android:layout_marginleft=" 5dip "android:layout_margintop=" 1dip "android:layout_width=" wrap_content "Android:text=" This is the title "android:textcolor=" #000000 "android:textsize=" 20sp "> <textview android:id=" @+id/tv_desc "Android:layout_below=" @id/tv_title "android:layout_height=" wrap_content "android:layout_marginleft=" 6dip " android:layout_margintop= "1dip" android:layout_width= "wrap_content" android:text= "This is the description content" Android:textcolor= "# 99ff0000 "android:textsize=" 14sp "> <checkbox android:clickable=" false "android:focusable=" false "android:id=" @+id/cb_status "android:layout_alignparentright=" true "android:layout_centervertical=" true"Android:layout_height=" wrap_content "android:layout_width=" Wrap_content "> <!--plus a split line--> <view Andr oid:background= "#000000/" android:layout_alignbottom= "@id/cb_status" android:layout_alignparentbottom= "true" android:layout_height= "0.2dip" android:layout_margintop= "7dip" android:layout_width= "match_parent" > </view
 ></checkbox></textview></textview></relativelayout>

As you can see, this layout is quite simple indeed. However, when the product manager tells you that the demand has changed, we need to add another such item to the interface, so you think, ctrl+c,ctrl+v, easy to handle, and then change the ID of the control, in the Java Code Findviewbyid (ID), add a section of logical code , finish the work. Did not expect this time the product again, the demand changed, here need to add 10 such layout, so you ... Admittedly, this time again ctrl+c,ctrl+v is not suitable, the workload appears very big, even if you are not too troublesome, so do, you do not expect the product will come again, that I deleted a few, that plus a few, is not going crazy.

Maybe we can come up with a lazy way to do it. By analyzing the layout above, it can be found that every item on the layout is unchanged, the layout is exactly the same, the only change is that the text on the red TextView changes with the state of the checkbox, and this change, we can find a way to extract into a method, the answer is yes. We can encapsulate the layout of this seed item once in a Java class, and each time we call the control, we set up a variety of attribute data beforehand, which involves a custom attribute. Analysis of this attribute set how to define, from the above picture can be seen, the control needs to set the content is, above the TextView title, and the following TextView description information, and description information is based on the state of the checkbox changed, So both of these states (true or false) need to be defined in the attribute set, so the attribute set is available.

Under Engineering, under the Res/values directory, create a new Attrs.xml file that defines the following property set:

<!--? XML version=1.0 encoding=utf-8?-->
<resources>
 
  <declare-styleable name= " Combinationview ">
    </attr>
    </attr>
    </attr>
  </declare-styleable>
 
</resources>

The

Defines the set of properties, and then we need to define a Java class to render the layout, parse the property set, and the object to provide a way to modify the state of the control, which has achieved the effect of reuse. The question is, which class do we want to inherit from this Java class? Here, we don't have to think about view because it's not a completely new custom control, and you don't need onmessure and ondraw to measure to draw a view. So what about ViewGroup? We don't have to use this class, because the layout here is given, and you don't need to use OnLayout to set the display position for the child control. So, what should we inherit? Can we imagine the ViewGroup subclasses? In addition to inheriting view and ViewGroup of the custom controls, you can also directly inherit the controls that are already in place on Android, which should be easy to imagine with object-oriented thinking. Since the layout file is relativelayout with the relative layout, we would certainly be able to customize the Java class to inherit this relativelayout,relativelayout to provide some parameters and methods to facilitate our implementation of the child control layout. However, we have already written here directly in the child control layout and do not need to use the parameters and methods provided by Relativelayout to lay out the layout. So, cause, even if do not inherit relativelayout, but change into linearlayout,framelayout ... is also possible, as long as the layout class is a subclass of the ViewGroup on the line. The following is the implementation code for this 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, you need to use the private String namespace = Http://schemas.android.com/apk/res/com.example.combinationview
  ;
  Title Private String title;
  The selected description is private String desc_on;
 
  A description that is not selected private String Desc_off;
    Public Combinationview (context, AttributeSet attrs) {Super (context, attrs);
    Renders the layout of a custom grouped control into view View view = View.inflate (context, R.layout.layout_combinationview, this);
    Tv_title = (TextView) View.findviewbyid (r.id.tv_title);
    Tv_desc = (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);
    Initializes to the child control if (title!= null) {Tv_title.settext (title);
    } if (Desc_off!= null) {Tv_desc.settext (Desc_off);
  }/** * Determines whether it is selected * * @return/public boolean ischecked () {return cb_status.ischecked (); /** * Set selected State * * @param ischecked/public void setchecked (Boolean ischecked) {Cb_status.setch
    Ecked (ischecked);
    if (ischecked) {tv_desc.settext (desc_on);
    else {tv_desc.settext (desc_off);
 }
  }
 
}

The code is simple, first inheriting the relativelayout, copying its constructor, rendering the layout view first in the constructor, and then reading the properties of the property set, and displaying the properties displayed to the child controls on the layout. In addition, a method of judging the state ischecked () is provided to determine whether the control is selected, providing a method of setting the state setchecked (Boolean) to change the state. PS: In order to verify the passage above, the reader can inherit relativelayout, inherit LinearLayout or inherit Framelayout, run to try, also can realize.

Here's how to refer to this custom composite control, which needs to be defined first in the activity's layout file:

<linearlayout android:layout_height= "match_parent" android:layout_width= "Match_parent" Vertical "xmlns:android=" http://schemas.android.com/apk/res/android "xmlns:example=" http://schemas.android.com/ Apk/res/com.example.combinationview "> <com.example.combinationview.combinationview android:id=" @+id/cv_ The "android:layout_height=" Wrap_content "android:layout_width=" match_parent "example:desc_off=" I was not selected description 1 " Example:desc_on= "I was chosen to describe 1" example:title= "I am Heading 1" > </com.example.combinationview.combinationview> < Com.example.combinationview.combinationview android:id= "@+id/cv_second" android:layout_height= "Wrap_content" Android:layout_width= "Match_parent" example:desc_off= "I was not selected description 2" example:desc_on= "I was selected description 2" example:title= " I am Heading 2 "> </com.example.combinationview.combinationview> <com.example.combinationview.combinationview Android:id= "@+id/cv_third" android:layout_height= "wrap_content" android:layout_width= "Match_parent" EXample:desc_off= "I was not selected description 3" example:desc_on= "I was selected description 3" example:title= "I am Heading 3" > </ com.example.combinationview.combinationview> <com.example.combinationview.combinationview android:id= "@+id /cv_fourth "android:layout_height=" wrap_content "android:layout_width=" match_parent "example:desc_off=" I was not selected description 4 "Example:desc_on=" I was selected to describe 4 "example:title=" I was heading 4 "> </com.example.combinationview.combinationview> </
 Linearlayout>

First of all, the definition of four custom combination control, you can see that the code is much more streamlined not?! Where to note: A custom property set is referenced here, so you must add namespaces on the layout node

Xmlns:example=http://schemas.android.com/apk/res/com.example.combinationview

Where the example is the name of the namespace, is arbitrary, but must refer to the name of the property in the control consistent, or it will be an error. The next string is a path that indicates the set of attributes, the first half is fixed, and the last "/" After must be the project's package name, otherwise the error is not correct.

Here is the business logic code within the activity, nothing to say

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;
    @Override protected 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);
  @Override public 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;
 }
  }
 
}

All right, about the custom combo control, it's very simple, but it's more common. Later, when the project is used, think about the implementation of the steps, a custom combination of controls, it is more convenient to use, than simply copy sticky not only tall, but also improve the reuse of code, simplifying the structure of the code and reduce the amount of code.

Here is a complete example of this, relatively simple, directly on the code:

Package com.xiong.demo1; 
 
Import android.app.Activity; 
Import Android.os.Bundle; 
Import Android.view.View; 

public class Mainactivity extends activity { 
 
  @Override 
  protected void onCreate (Bundle savedinstancestate) { 
    super.oncreate (savedinstancestate); 
    Setcontentview (r.layout.main_activity); 
    Titlebarview Titlebarview = (titlebarview) Findviewbyid (r.id.tbar_test); 
    Titlebarview.gettextviewrigth (). setvisibility (View.gone); 
    Titlebarview.settitlebarchangerliseter (New Ititleonchangelister () { 
      @Override public 
      Void Setleftonclicklister () { 
        finish (); 
      } 
 
      @Override public 
      void Setrigthonclicklister () { 
 
      } 
    }); 
  } 
 
 

 <?xml version= "1.0" encoding= "Utf-8"?> <linearlayout "xmlns:android=" Schemas.android.com/apk/res/android "xmlns:xionglh=" Http://schemas.android.com/apk/res-auto "android:layou T_width= "Match_parent" android:layout_height= "Match_parent" > <com.xiong.demo1.titlebarview Android : id= "@+id/tbar_test" android:layout_width= "match_parent" android:layout_height= "45DP" xionglh:titlebar_cent 
    er_text= "Home" xionglh:titlebar_center_textcolor= "@android: Color/black" xionglh:titlebar_center_text_size= "18SP" xionglh:titlebar_left_bg= "@mipmap/left_back" xionglh:titlebar_right_text= "Security Center" Xionglh:titlebar_right_text_ Size= "12SP"/> </LinearLayout> 
 <?xml version= "1.0" encoding= "Utf-8"?> <resources> <declare-styleable Name= "titlebar" > <attr name= "titlebar_center_text_size" format= "Dimension"/> "<attr name=" TitleBar_ Center_text "format=" string "/> <attr name=" titlebar_center_textcolor "format=" color "/> <attr name= "TITLEBAR_LEFT_BG" format= "reference"/> <attr name= "titlebar_right_text_size" format= "Dimension"/> &l 
 
  T;attr name= "Titlebar_right_text" format= "string"/> <attr "name=" titlebar_right_textcolor "Color" format= </declare-styleable> </resources> 
Package com.xiong.demo1; 
Import Android.content.Context; 
Import Android.content.res.TypedArray; 
Import Android.graphics.Color; 
Import Android.util.AttributeSet; 
Import Android.util.TypedValue; 
Import Android.view.View; 
Import Android.view.ViewGroup; 
Import Android.widget.ImageView; 
Import Android.widget.RelativeLayout; 
 
Import Android.widget.TextView; 
 
  public class Titlebarview extends Relativelayout {private Ititleonchangelister mititleonchangelister; 
  Private ImageView Mimgleft; 
 
  Private TextView mtxtcenter, mtxtrigth; Private float mtitlecentertextsize;//title font size Private String mtitlecentertext;//caption text private int Mtitlecentertextcolor ;//title Color private int mleftbg;//left return button private float mtitlerigthtextsize;//title font size private String Mtitlerigthtex t;//title text private int mtitlerigthcolor;//title color public Titlebarview (context context, AttributeSet Attrs) {Super 
    (context, attrs); 
 int defualtsize = (int) typedvalue.applydimension (       TYPEDVALUE.COMPLEX_UNIT_SP, Getresources (). Getdisplaymetrics ()); 
    TypedArray TypedArray = GetContext (). Obtainstyledattributes (Attrs, R.styleable.titlebar); 
    Mtitlecentertextsize = Typedarray.getdimension (r.styleable.titlebar_titlebar_center_text_size, defualtSize); 
    Mtitlecentertext = typedarray.getstring (R.styleable.titlebar_titlebar_center_text); 
    Mtitlecentertextcolor = Typedarray.getcolor (R.styleable.titlebar_titlebar_center_textcolor, Color.RED); 
    MLEFTBG = Typedarray.getresourceid (R.STYLEABLE.TITLEBAR_TITLEBAR_LEFT_BG, r.mipmap.left_back); 
    Mtitlerigthtextsize = Typedarray.getdimension (r.styleable.titlebar_titlebar_right_text_size, defualtSize); 
    Mtitlerigthtext = typedarray.getstring (R.styleable.titlebar_titlebar_right_text); 
    Mtitlerigthcolor = Typedarray.getcolor (R.styleable.titlebar_titlebar_right_textcolor, Color.RED); 
    Typedarray.recycle (); 
  Initview (); private void Initview () {mtxtcenter = new TextView (getcOntext ()); 
    Mtxtcenter.settext (Mtitlecentertext); 
    Mtxtcenter.settextsize (typedvalue.complex_unit_px, mtitlecentertextsize); 
    Mtxtcenter.settextcolor (Mtitlecentertextcolor); Layoutparams centerparams = new Layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_ 
    CONTENT); 
    Centerparams.addrule (Relativelayout.center_in_parent, TRUE); 
    AddView (Mtxtcenter, centerparams); 
    Mtxtrigth = new TextView (GetContext ()); 
    Mtxtrigth.settext (Mtitlerigthtext); 
    Mtxtrigth.settextsize (typedvalue.complex_unit_px, mtitlerigthtextsize); 
    Mtxtrigth.settextcolor (Mtitlerigthcolor); Layoutparams rigthparams = new Layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_ 
    CONTENT); 
    Rigthparams.addrule (Relativelayout.align_parent_right, TRUE); 
 
    Rigthparams.addrule (relativelayout.center_vertical, TRUE); 
    AddView (Mtxtrigth, rigthparams); 
    Mimgleft = new ImageView (GetContext ()); Mimgleft.setimageresource (MLEFTBG); Layoutparams leftparams = new Layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT 
    ); 
    Leftparams.setmargins (6, 0, 0, 0); 
    Leftparams.addrule (relativelayout.center_vertical, TRUE); 
    AddView (Mimgleft, leftparams); 
    View view = new View (GetContext ()); 
    View.setminimumwidth (1); 
    View.setbackgroundcolor (Getresources (). GetColor (r.color.gray_767676)); 
    Layoutparams viewparams = new Layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT, 1); 
    Viewparams.addrule (Relativelayout.align_parent_bottom); 
    AddView (view, viewparams); Mimgleft.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {Mititle 
      Onchangelister.setleftonclicklister (); 
 
    } 
    }); Mtxtrigth.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {MITITL 
      Eonchangelister.setrigthonclicklister (); 
 
  } 
    }); } public void SettiTlebarchangerliseter (Ititleonchangelister ititleonchangelister) {this.mititleonchangelister = ItitleOnChangeLister 
  ; 
  Public ImageView Getleftimage () {return mimgleft; 
  Public TextView Gettextviewcenter () {return mtxtcenter; 
  Public TextView Gettextviewrigth () {return mtxtrigth; 

}} package Com.xiong.demo1; 
  public interface Ititleonchangelister {void Setleftonclicklister (); 
 
void Setrigthonclicklister (); 

 }
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.