Android-butterknife cannot annotate Ratingbar (with Butterknife part principle and view transfer mechanism)

Source: Internet
Author: User

Continue to write out some of the things that were previously outsourced by Android. Article structure: (1) Ratingbar basic use (custom style), (2) Butterknife can not annotate ratingbar and the way in which the project is resolved, (3) Butterknife principle and view mechanism principle one, Ratingbar Basic use (custom style): (1) a style style:
    name="roomRatingBar" parent="@android:style/Widget.RatingBar">        <itemname="android:progressDrawable">@drawable/room_rating_bar</item>        <itemname="android:minHeight">24dip</item>        <itemname="android:maxHeight">24dip</item>    </style>
(2) A drawable resource:
<?xml version= "1.0" encoding= "Utf-8"?><layer-list xmlns:android="Http://schemas.android.com/apk/res/android"> <!--The first picture is set unchecked, the second picture is set to half a star, and the third picture is set to the entire star. Which means we're going to have to find three of these pictures ourselves.    <item android:id="@android: Id/background" android:drawable="@ Drawable/rating_small_empty " />    <item android:id="@android: id/secondaryprogress" android:drawable= "@drawable/rating_small_half" />    <item android:id="@android: id/progress" android:drawable="@ Drawable/rating_small_full " /></layer-list>
(3) Call:
 <Ratin                 Gbar  android:id  = "@+id/ratingbar"                 style  = "@style/roomratingbar"                 android:layout_width  = "wrap_content"                 android:layout_height  = "wrap_content"  android:layout_marginleft  = "8DP"  android:layout_margintop  = "9DP"  android:isindicator  =" true "/>   
The rest is the most basic boring Findviewbyid () and Setonclicklistener () and other code. (Non-butterknife mode) second, Butterknife can not annotate ratingbar and the way in the Project Solution: (demo see below the source code)
//如果像平常这样使用butterknife去注解它,它是构造不了视图的,进而渲染不了,出异常。@BindView(R.id.retingbar)    RatingBar retingbar;
Workaround: Use the following method to initialize it: One will explain this principle
layoutinflater layoutinflater = Layoutinflater.from  (Getactivity ())  View view = Layoutinflater.inflate  (R .fragment  _ability, null)  Ratingbar = (ratingbar) view.findviewbyid  (R .id  .ratingbar )   
Third, the principle of butterknife and the principle of view mechanism to understand the mechanism and look at the source: Butterknife with Java Annotation processing technology, is the Java code compiled into Java bytecode has been processed @ Bind, @OnClick (Butterknife also supports a lot of other annotations). That is, custom annotations. The information is as follows: (actually still javase content) Java custom Annotationsjava annotations According to the data, custom annotations We need to know two basic meta-annotations @retention and @Target. Butterknife Workflow: Refer to the Butterknife framework principle, thanks to the blogger. 1. Clear one: All annotations in Butterknife are reserved for CLASS using Retention. 2. When you compile your Android project, the process () method of the Butterknifeprocessor class in the Butterknife project does the following: At first it scans all the Butterknife annotations in the Java code @Bind, @ OnClick, @OnItemClicked, etc. when it finds that a class contains any annotation, butterknifeprocessor will help you generate a Java class with a name like $ $ViewBinder, which implements the new class. Viewbinder interface This Viewbinder class contains all the corresponding code, such as the @Bind annotation corresponding to Findviewbyid (), @OnClick corresponds to View.setonclicklistener () and so on and finally when Activi When Ty starts Butterknife.bind (this) execution, Butterknife will load the corresponding Viewbinder class to invoke their bind () method.
//The initialization of each control roughly generates such code: Public  class exampleactivity$$viewbinder<T extendsio. Bxbxbai. samples. UI. exampleactivity> implements Viewbinder<T> {         @Override Public voidBindFinalFinder Finder,FinalT target, Object source) {View view; View = Finder.findrequiredview (source,21313618, "Field ' user '"); Target.username = Finder.castview (view,21313618, "Field ' user '"); View = Finder.findrequiredview (source,21313618, "Field ' Pass '"); Target.password = Finder.castview (view,21313618, "Field ' Pass '"); View = Finder.findrequiredview (source,21313618, "Field ' Submit ' and method ' submit '"); View.setonclicklistener (NewButterknife.internal.DebouncingOnClickListener () {@Override Public voidDoClick (Android.view.View p0) {target.submit ();      }        }); } @Override Public voidReset (T target) {target.username =NULL; Target.password =NULL; }}
(3) Then, when the bind method is executed, we call the Butterknife.bind (this) activity call:
@Nullable    @Override    publiconCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {    //第一个参数就是要加载的布局id,第二个参数是指给该布局的外部再嵌套一层父布局,如果不需要就直接传null。这样就成功成功创建了一个布局的实例    //一会讲解此原理        false);        ButterKnife.bind(this, view);//传一个上下文,以及取出来的父view        return view;    }
Source:
 //parameters are passed to this  @NonNull @UiThread public static Unbinder bind (@NonNull Object target, @NonNull  View source) { return createbinding (target, source); }private static unbinder createbinding (@NonNull Object target, @NonNull View source) {//Get that context first /c7>Class<?>     Targetclass = Target.getclass ();     if (Debug) log.d (TAG, "looking up binding for" + targetclass.getname ()); And get the view constructor that the context contains Constructor<? extends    Unbinder> constructor = findbindingconstructorforclass(targetclass); if (constructor = = null) {      returnUnbinder.EMPTY; }//noinspection trywithidenticalcatches resolves to API 19+ only type.    Try{//pass to the View builder to render the drawing      returnConstructor.newinstance (target, source); }Catch(Illegalaccessexception e) {Throw NewRuntimeException ("Unable to invoke"+ constructor, E); }Catch(Instantiationexception e) {Throw NewRuntimeException ("Unable to invoke"+ constructor, E); }Catch(InvocationTargetException e) {Throwable cause = E.getcause ();if(CauseinstanceofRuntimeException) {Throw(runtimeexception) cause; }if(CauseinstanceofError) {Throw(Error) cause; }Throw NewRuntimeException ("Unable to create binding instance.", cause); }  }
(4) Formally loading and injecting butterknife will load $ $ViewBinder. The Java class then invokes the Bind method of Viewbinder, dynamically injecting all the view properties in the activity class and if there are @OnClick in the activity Annotated method, Butterknife will set Onclicklistener to view in the Viewbinder class and pass the method of @OnClick annotation into it note: @Bind, @OnClick A property or method such as an annotation callout must be public or protected, because Butterknife is injected into the view by a class that gets the context to view and then precompile it. Why would you do that? Some injection frameworks such as Roboguice you can set the view to private, the answer is performance. If you set the view to private, the frame must be injected into the view by reflection, no matter how fast the CPU processor of the phone is now, and if some of the operations affect performance, it's definitely something to avoid, which is the difference between butterknife and other injection frameworks. Next, let's get to know the inflate mechanism: But before we do, we first understand the Android interface Architecture layer, which is first View mechanism: Android Control vibe two categories: ViewGroup and view controls. The ViewGroup control can contain multiple view as a parent control and manage the included view control. Through ViewGroup, we can clearly know our view inheritance tree. The upper control is responsible for measuring and drawing the underlying child controls and passing interactive events. The Findviewbyid () method, usually used in activity, is to find the corresponding element in the control tree with the tree's depth-first traversal. At the top of each control tree, there is a Viewparent object, which is the control core of the whole tree, and all the interaction management events are left to it to agree on scheduling and allocation, thus achieving overall control over the entire view.

Each activity contains a Window object, in Android, the window object is usually implemented by Phonewindow, and a decorview is set to the root view of the entire application window. Decorview as the top-level view of the window interface, encapsulates some of the common methods for manipulating windows (such as capturing screen widths and heights). Drcorview the specific content to be displayed on the Phonewindow, all of the view's listening time is received through Windowmanagerservice, And the corresponding Onclicklistener are adjusted back and forth through the activity object. On the display, it drcorview the screen screen into two parts, one titleview and the other contentview. Contentview an ID is a framelayout of content.

There is a problem in the elite, I think the resolution is not clear enough. – Why calling the Requestwindowfeature () method must be valid before calling the Setcontentview () method. Cause: 1. Clear the Setcontentview () method. After calling this method, Activitymanagerservice will callback the Onresume () method, which is the system will add the entire decorview to the Phonewindow, and its display, drawing out the interface. In other words, the service is notified immediately after this method is called to measure the view drawing view. 2.requestWindowFeature () method is to remove the title bar, that is, to remove the Titleview, That is to inform Activitymanagerservice to tell it not to measure drawing Titleview if the Requestwindowfeature method is called after the Setcontentview method, Then Requestwindowfeature will not have the chance to tell Activitymanagerservice not to measure the plotting Titleview, But it does put this requestwindowfeature event into the processing queue and can not process, so will error!! Well, we continue to understand inflate mechanism: Read the following source: There are four kinds of, but I only say the following, because it is called this method, and finally return the results to the Layoutinflater build view. But I would recommend some articles to everyone.
//Return value view: The value returned is the root node that the view points to. / * The first parameter resource.    It says that the XML layout file that comes in according to several other methods will be used to parse the second parameter root in this case: the root node, which is mainly determined by the third parameter, parser The third parameter attachtoroot: Indicates whether to add the converted view directly on the root node, if true, after the conversion out of view, the internal call Root.addview () directly to add it to the root node, and then return to the root node, Of course it's the root node we passed in. If set to false, it will only convert the XML layout to the corresponding view and will not add it to the root node that we passed in. *// * 1. If root is null,attachtoroot, setting any value is meaningless.    2. If root is not set to true for Null,attachtoroot, a parent layout, root, is assigned to the loaded layout file.    3. If root is not set to False for Null,attachtoroot, all layout properties of the outermost layer of the layouts file will be set and the layout properties will automatically take effect when the view is added to the parent view. 4. If the Attachtoroot parameter is not set, the default is true if root is not the Null,attachtoroot parameter. */ PublicViewInflate(@LayoutResintResource, @Nullable ViewGroup root,BooleanAttachtoroot) {FinalResources res = GetContext (). Getresources ();if(DEBUG) {LOG.D (TAG,"inflating from resource: \" "+ res.getresourcename (Resource) +"\" ("+ integer.tohexstring (Resource) +")"); }FinalXmlresourceparser parser = res.getlayout (Resource);Try{returnInflate (parser, Root, attachtoroot); }finally{Parser.close (); }    }
So, why above, we initialize Ratingbar to adopt that way?? The processing in Layoutinflater is: Createviewfromtag () is used to create a view object from a node name. Indeed, within the Createviewfromtag () method, the CreateView () method is called, and the instance of the view is created and returned using reflection. Finally: The same is the Createviewfromtag () method to create an instance of the view, and then recursively calls the Rinflate () method on line 24th to find the child elements under the view, and adds the view to the parent layout after each recursive completion. In this way, the entire layout file is parsed to form a complete DOM structure, which will eventually return the topmost root layout, so that the inflate () process is finished. Add: Guo Lin greatly talked about this inflate mechanism: Guo Lin greatly inflate mechanism source download: android-Multi-List of items Rxjava+rtrofit+recyclerview+glide+adapter package, Android-butterknife can not annotate Ratingbar (including the butterknife part of the principle and view delivery mechanism) is finished. This blog is the third in this series, so some detail pits. In addition, this series also has some of my projects in the process of outsourcing optimization, as well as some release signatures and so on, I will be finished as soon as possible to everyone, share experience for everyone. Welcome to point out the error below, learn together!! Your point of praise is the best support for me!! For more information, visit Jackfrost's blog

Android-butterknife cannot annotate Ratingbar (with Butterknife part principle and view transfer mechanism)

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.