1、1个功用强大的页面开发帮忙类—HtmlHelper初阶明白

HTML扩充类的有所办法都有二个参数:
以textbox为例子
public static string TextBox( this HtmlHelper htmlHelper, string name,
Object value, IDictionary<string, Object> htmlAttributes )
public static string TextBox( this HtmlHelper htmlHelper, string name,
Object value, Object htmlAttributes )
那二个参数代表那个html标签的习性集合。使用方法如下。
 
1.ActionLink
<%=Html.ActionLink(“那是3个总是”, “Index”, “Home”)%>
带有QueryString的写法
【金沙注册送58】一时辰搞领会申明处理器,HtmlHelper用法大全。<%=Html.ActionLink(“那是1个连接”, “Index”, “Home”, new { page=一},null)%>
<%=Html.ActionLink(“那是一个老是”, “Index”, new { page=一 })%>
有其余Html属性的写法
<%=Html.ActionLink(“那是一个总是”, “Index”, “Home”, new { id=”link一”
})%>
<%=Html.ActionLink(“那是贰个连连”, “Index”,null, new { id=”link一”
})%>
QueryString与Html属性同时设有
<%=Html.ActionLink(“那是1个连接”, “Index”, “Home”, new { page = 一 },
new { id = “link一” })%>
<%=Html.ActionLink(“那是八个两次三番”, “Index” , new { page = 1 }, new {
id = “link一” })%>
 
变迁结果为:
<a href=”/”>那是三个延续</a>
带有QueryString的写法
<a href=”/?page=一”>那是多少个连连</a>
<a href=”/?page=一”>那是三个老是</a>
有别的Html属性的写法
<a href=”/?Length=四” id=”link一”>那是多个总是</a>
<a href=”/” id=”link一”>那是四个接连</a>
QueryString与Html属性同时存在
<a href=”/?page=壹” id=”link壹”>那是2个再3再四</a>
<a href=”/?page=1″ id=”link一”>那是2个接二连三</a>
 
2.RouteLink
跟ActionLink在效益上亦然。
<%=Html.RouteLink(“关于”, “about”, new { })%>
带QueryString
<%=Html.RouteLink(“关于”, “about”, new { page = 1 })%>
<%=Html.RouteLink(“关于”, “about”, new { page = 1 }, new { id =
“link1” })%>
 
变迁结果:
<a href=”/about”>关于</a>
<a href=”/about?page=1″>关于</a>
<a href=”/about?page=1″ id=”link1″>关于</a>
3.Form   2种方法
<%using(Html.BeginForm(“index”,”home”,FormMethod.Post)){%>
<%} %>
 
<%Html.BeginForm(“index”, “home”,
FormMethod.Post);//注意那里没有=输出%>
<%Html.EndForm(); %>
 
变动结果:
<form action=”/home/index” method=”post”></form>
4.TextBox
, Hidden ,
<%=Html.TextBox(“input1”) %>
<%=Html.TextBox(“input2”,Model.CategoryName,new{ @style =
“width:300px;” }) %>
<%=Html.TextBox(“input3”, ViewData[“Name”],new{ @style =
“width:300px;” }) %>
<%=Html.TextBoxFor(a => a.CategoryName, new { @style =
“width:300px;” })%>
 
变更结果:
 
<input id=”input1″ name=”input1″ type=”text” value=”” />
<input id=”input2″ name=”input2″ style=”width:300px;” type=”text”
value=”Beverages” />
<input id=”input3″ name=”input3″ style=”width:300px;” type=”text”
value=”” />
<input id=”CategoryName” name=”CategoryName” style=”width:300px;”
type=”text” value=”Beverages” />
 
5.TextArea
<%=Html.TextArea(“input5”, Model.CategoryName, 3, 9,null)%>
<%=Html.TextAreaFor(a => a.CategoryName, 3, 3, null)%>
 
变迁结果:
<textarea cols=”9″ id=”input5″ name=”input5″
rows=”3″>Beverages</textarea>
<textarea cols=”3″ id=”CategoryName” name=”CategoryName”
rows=”3″>Beverages</textarea>
 
6.CheckBox
<%=Html.CheckBox(“chk1”,true) %>
<%=Html.CheckBox(“chk1″, new { @class=”checkBox”}) %>
<%=Html.CheckBoxFor(a =>a.IsVaild, new { @class = “checkBox”
})%>
 
扭转结果:
 
<input checked=”checked” id=”chk1″ name=”chk1″ type=”checkbox”
value=”true” /><input name=”chk1″ type=”hidden” value=”false”
/>
 
<input class=”checkBox” id=”chk1″ name=”chk1″ type=”checkbox”
value=”true” /><input name=”chk1″ type=”hidden” value=”false”
/>
 
<input checked=”checked” class=”checkBox” id=”IsVaild” name=”IsVaild”
type=”checkbox” value=”true” /><input name=”IsVaild” type=”hidden”
value=”false” />
 
7.ListBox
<%=Html.ListBox(“lstBox1”,(SelectList)ViewData[“Categories”])%>
<%=Html.ListBoxFor(a => a.CategoryName,
(SelectList)ViewData[“Categories”])%>
 
变化结果:
<select id=”lstBox1″ multiple=”multiple” name=”lstBox1″>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option selected=”selected” value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
<select id=”CategoryName” multiple=”multiple”
name=”CategoryName”>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
 
8.DropDownList
<%= Html.DropDownList(“ddl1”,
(SelectList)ViewData[“Categories”],  “–Select One–“)%>
<%=Html.DropDownListFor(a => a.CategoryName,
(SelectList)ViewData[“Categories”], “–Select One–“, new { @class =
“dropdownlist” })%>
 
转变结果:
<select id=”ddl1″ name=”ddl1″>
<option value=””>–Select One–</option>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
<option selected=”selected” value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
<select class=”dropdownlist” id=”CategoryName”
name=”CategoryName”>
<option value=””>–Select One–</option>
<option value=”1″>Beverages</option>
<option value=”2″>Condiments</option>
金沙注册送58 ,<option value=”3″>Confections</option>
<option value=”4″>Dairy Products</option>
<option value=”5″>Grains/Cereals</option>
<option value=”6″>Meat/Poultry</option>
<option value=”7″>Produce</option>
<option value=”8″>Seafood</option>
</select>
 
九.Partial
视图模板
webform里叫自定义控件。功用都以为着复用。但接纳上自定义控件真的很难用好。
<% Html.RenderPartial(“DinnerForm”);
%>  看领会了从未等号的。

Java中的注脚是个很神奇的东西,还不掌握的能够看下一时辰搞通晓自定义注明(Annotation)。今后众多Android的库都用利用申明达成的,比如ButterKnife,我们不防也来读书一下,学完注脚处理器,大家品尝写贰个粗略的切近ButterKnife的东西来绑定控件。

群里一小伙伴在开发应用程式时遇见了难点,便截图提问

1.壹 有失必有得

金沙注册送58 1

  在ASP.Net
MVC中微软并不曾提供类似服务器端控件那种开发格局,究竟微软的MVC就是历史观的乞求处理响应的回归。所以扬弃此前的那种事件响应的模子,放任服务器端控件也理所当然。

  但是,假设手写Html标签功用又相比较低,可重花费相比较低。那时,大家该怎么着来提升成效呢?首先,经过上篇我们了然能够因此ViewData传递数据,于是我们得以写出以下的Html代码:

<input name="UserName" type="text" value="<%: ViewData["UserName"] %>" />

  尽管上述代码能够消除难题,但是功能依然相比较低,尤其是在列表集合项较多的时候,工作量会比较大。那么,还有木有1种越来越好的诀窍吗?别急,微软一度为大家想好了策略。微软为开发职员火速支付前台页面提供了加上的HtmlHelper的赞助类,扶助大家极快支付前台页面,也提供了可扩充的接口,前台页面包车型客车竹签能够能够做到高度可选取

何以是注脚处理器?

注明处理器是(Annotation Processor)是javac的2个工具,用来在编译时扫描和编译和处理评释(Annotation)。你能够团结定义注明和注释处理器去搞一些事务。2个评释处理器它以Java代码可能(编写翻译过的字节码)作为输入,生成文书(平常是java文件)。那么些变化的java文件不可能修改,并且会同其手动编写的java代码一样会被javac编写翻译。看到那里丰盛以前知道,应该驾驭差不多的经过了,正是把标记了诠释的类,变量等作为输入内容,经过评释处理器处理,生成想要生成的java代码。

金沙注册送58 2

1.2 HtmlHelper初窥

  大家得以因而在页面中经过Html.XXX来完成急忙的Html标签编辑,并且能够方便地拓展多少绑定。

<%: Html.Raw("<p>Hello,I am HtmlHelper!</p>") %>

  那么,为何能够在页面中调用Html.XXX方法吧?通过ILSpy反编写翻译ViewPage页,大家能够观望原来在ViewPage下有贰个HtmlHelper类型的属性-Html。(那下终于知道,为何能够在页面中动用Html.xxxx()了)

金沙注册送58 3

  那么这么些HtmlHelper类又是二个怎么品种的大神啊?继续反编写翻译查看,在System.Web.Mvc命名空间下的HtmlHelper类型如下图所示,经过MSDN大神的讲授,HtmlHelper帮忙在视图中表现
HTML
控件。那我们看看在此类中有木有逸事中的TextBox、CheckBox的章程吗?经查阅,木有。

金沙注册送58 4

  那么,大家为什么能够在页面中使用Html.TextBox()方法吧?那里就涉嫌到多少个称作“扩大方法”的东东了,HtmlHelper 类的壮大方法在 System.Web.Mvc.Html
命名空间中。 这一个扩充添加了用来创制窗体、展现 HTML
控件、展现分部视图、执行输入验证等成效的援救器方法。那么,有关怎么着自定义扩大方法请参阅本文第3局地,那里先卖个典型,暂不介绍。

金沙注册送58 5

处理器AbstractProcessor

微机的写法有定点的覆辙,继承AbsstractProcessor。如下:

public class MyProcessor extends AbstractProcessor {
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv){
        super.init(processingEnv);
    }
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return null;
    }
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return true;
    }
}
  • init(ProcessingEnvironment processingEnv)
    被诠释处理工科具调用,参数ProcessingEnvironment
    提供了Element,Filer,Messager等工具
  • getSupportedAnnotationTypes()
    内定证明处理器是登记给那多少个诠释的,它是三个字符串的聚合,意味着能够支撑多个项目标诠释,并且字符串是合法全名。
  • getSupportedSourceVersion 指定Java版本
  • process(Set<? extends TypeElement> annotations,
    RoundEnvironment roundEnv)
    那些也是最重大的,在此处扫描和处理你的注释并生成Java代码,消息都在参数RoundEnvironment
    里了,前边会介绍。

在Java7 中还足以采纳

@SupportedSourceVersion(SourceVersion.latestSupported())
@SupportedAnnotationTypes({
   // 合法注解全名的集合
 })

取代 getSupportedSourceVersion() 和 getSupportedAnnotationType()
,没毛病,还足以在诠释处理离器中选用表明。

壹、傻瓜式消除办法:

1.三 为啥选择HtmlHelper?

   思虑这样一个情景:大家的项目第二个版本中的路由规则是这么的{controller}/{action}/{id},于是我们项目中拥有的<a>标签所指向的都以以刚刚的条条框框命名的href(例如:<a
></a>)。不过在其次版中,我们的路由规则也会化为了{controller}-{action}-{id},那么大家恰好为超链接所设置的href便都不可能寻常访问了。那时,大家要求展开交换,单个替换或批量交替(例如改为:<a
></a>),固然也得以消除难点,可是的确扩展了工作量,成效极低。

  那么,怎么样来遮掩那种转移所带来的不便呢?那里,通过运用HtmlHelper为我们提供的ActionLink标签,便足以缓解那个难点。因为HtmlHelper是从服务器端自动帮你生成a标签,由此所生成的href会遵从近来的路由规则,也就帮我们遮挡了转变,提升了工作作用。

注册评释处理器

卷入评释处理器的时候供给3个特有的文书
javax.annotation.processing.Processor 在 META-INF/services 路径下

--myprcessor.jar
----com
------example
--------MyProcessor.class
----META-INF
------services
--------javax.annotation.processing.Processor

打包进javax.annotation.processing.Processor的情节是总计机的官方全称,多个电脑之间换行。

com.example.myprocess.MyProcessorA
com.example.myprocess.MyProcessorB

google提供了四个登记处理器的库

compile 'com.google.auto.service:auto-service:1.0-rc2'

1个评释化解:

@AutoService(Processor.class)
public class MyProcessor extends AbstractProcessor {
      ...
}

读到那里ButterKnife用到的知识点大家都已经领会了
一.自定义注脚
二.用注脚处理器解析注脚
三.解析落成后生成Java文件
BufferKnife使用:

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.rxjava_demo)
    Button mRxJavaDemo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mRxJavaDemo.setText("Text");
    }

}

接下来大家编译一下,打开路径:/app/build/intermediates/classes/release/com/ming/rxdemo/MainActivity$$ViewBinder.class
这就是大家转移的Java文件,能够见到Button已经在bind里面伊始化了。

public class MainActivity$$ViewBinder<T extends MainActivity> implements ViewBinder<T> {
    public MainActivity$$ViewBinder() {
    }

    public void bind(Finder finder, T target, Object source) {
        View view = (View)finder.findRequiredView(source, 2131492944, "field \'mRxJavaDemo\'");
        target.mRxJavaDemo = (Button)finder.castView(view, 2131492944, "field \'mRxJavaDemo\'");
    }

    public void unbind(T target) {
        target.mRxJavaDemo = null;
    }
}

接下去我们创制3个档次,写叁个粗略的用表明绑定控件的例子

  删除:

贰、未有服务器控件也能干大事—HtmlHelper首要格局介绍

  PS:那里的实例均未有加<% %>或@符号,要运营请自行加上。

  (1)ActionLink与RouteLink

Html.ActionLink("这是一个连接", "Index", "Home")  带有QueryString的写法  Html.ActionLink("这是一个连接", "Index", "Home", new { page=1 },null)  Html.ActionLink("这是一个连接", "Index", new { page=1 })  有其它Html属性的写法  Html.ActionLink("这是一个连接", "Index", "Home", new { id="link1" })  Html.ActionLink("这是一个连接", "Index",null, new { id="link1" })  QueryString与Html属性同时存在  Html.ActionLink("这是一个连接", "Index", "Home", new { page = 1 }, new { id = "link1" })  Html.ActionLink("这是一个连接", "Index" , new { page = 1 }, new { id = "link1" })

  其变动的结果为:

<a href="/">这是一个连接</a>  带有QueryString的写法  <a href="/?page=1">这是一个连接</a>  <a href="/?page=1">这是一个连接</a>  有其它Html属性的写法  <a href="/?Length=4" id="link1">这是一个连接</a>  <a href="/" id="link1">这是一个连接</a>  QueryString与Html属性同时存在  <a href="/?page=1" id="link1">这是一个连接</a>  <a href="/?page=1" id="link1">这是一个连接</a>

  RouteLink在用法差不多与ActionLink1致,那里就不再介绍,详情请插足MSDN;

  (2)TextBox与TextArea

  ①TextBox

Html.TextBox("input1")   Html.TextBox("input2",Model.CategoryName,new{ @style = "width:300px;" })   Html.TextBox("input3", ViewData["Name"],new{ @style = "width:300px;" })   Html.TextBoxFor(a => a.CategoryName, new { @style = "width:300px;" })

  其生成的结果为:

<input id="input1" name="input1" type="text" value="" />  <input id="input2" name="input2" style="width:300px;" type="text" value="Beverages" />  <input id="input3" name="input3" style="width:300px;" type="text" value="" />  <input id="CategoryName" name="CategoryName" style="width:300px;" type="text" value="Electronic" />

  ②TextArea

Html.TextArea("input5", Model.CategoryName, 3, 9,null)  Html.TextAreaFor(a => a.CategoryName, 3, 3, null)

  其变化的结果为:

<textarea cols="9" id="input5" name="input5" rows="3">Electronic</textarea>  <textarea cols="3" id="CategoryName" name="CategoryName" rows="3">Electronic</textarea>

  这里能够看来,大家得以行使强类型来生成Html标签,例如:Html.TextBoxFor(a
=> a.CategoryName, new { @style = “width:300px;”
}),这里的CategoryName正是某些项指标性质。

  (3)CheckBox

Html.CheckBox("chk1",true)   Html.CheckBox("chk1", new { @class="checkBox"})   Html.CheckBoxFor(a =>a.IsVaild, new { @class = "checkBox" })

   其转移的结果为:

<input checked="checked" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />  <input class="checkBox" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />  <input checked="checked" class="checkBox" id="IsVaild" name="IsVaild" type="checkbox" value="true" /><input name="IsVaild" type="hidden" value="false" />

  (4)DropDownList

Html.DropDownList("ddl1", (SelectList)ViewData["Categories"],  "--Select One--")  Html.DropDownListFor(a => a.CategoryName, (SelectList)ViewData["Categories"], "--Select One--", new { @class = "dropdownlist" })

  其变化的结果为:

<select id="ddl1" name="ddl1">  <option value="">--Select One--</option>  <option value="1">Beverages</option>  <option value="2">Condiments</option>  <option selected="selected" value="3">Confections</option>  <option value="4">Dairy Products</option>  <option value="5">Grains/Cereals</option>  <option value="6">Meat/Poultry</option>  <option value="7">Produce</option>  <option value="8">Seafood</option>  </select>  <select class="dropdownlist" id="CategoryName" name="CategoryName">  <option value="">--Select One--</option>  <option value="1">Beverages</option>  <option value="2">Condiments</option>  <option value="3">Confections</option>  <option value="4">Dairy Products</option>  <option value="5">Grains/Cereals</option>  <option value="6">Meat/Poultry</option>  <option value="7">Produce</option>  <option value="8">Seafood</option>  </select>

  (5)RadioButton

男<%: Html.RadioButton("Gender","1",true) %>  女<%: Html.RadioButton("Gender","2",false) %>

  其转移的代码为:

男<input checked="checked" id="Gender" name="Gender" type="radio" value="1" />  女<input id="Gender" name="Gender" type="radio" value="2" />

  (6)Encode与Raw

  Encode会将内容开始展览编码话,由此,假如您的剧情中含有Html标签的话那么会被分析成特殊字符,例如:

<%: Html.Encode("<p>哈哈</p>") %>

  其变动的代码为:

&amp;lt;p&amp;gt;哈哈&amp;lt;/p&amp;gt;

  那里根本是为着防止XSS攻击和恶心脚本,由此在MVC中,私下认可的<%:
%>就落实了<%: Html.Encode()
%>。不过,有个别时候要是大家须要输出Html或JavaScript内容的字符串,那时我们能够动用HtmlHelper为我们提供的别样艺术。例如大家要出口刚刚那句话,大家可以如下使用:

<%: Html.Raw("<p>哈哈</p>") %>

  其生成的代码为:

<p>哈哈</p>

  在HtmlHelper中还提供了不少的扩展方法供大家有益创制Html,比如:BeginForm、EndForm等。关于其余的方式介绍,请自行检索,那里不再1一赘述。

品种组织

--apt-demo
----bindview-annotation(Java Library)
----bindview-api(Android Library)
----bindview-compiler(Java Library)
----app(Android App)
  • bindview-annotation 申明评释
  • bindview-api 调用Android SDK API
  • bindview-compiler 注脚处理器相关
  • app 测试App

①.在 bindview-annotation
下成立2个@BindView申明,该评释重回1个值,整型,名为value,用来代表控件ID。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
    /**
     * 用来装id
     *
     * @return
     */
    int value();
}

贰.在 bindview-compiler 中开创注明处理器 BindViewProcessor
并登记,做为主的起初化学工业作。

@AutoService(Processor.class)
public class BindViewProcessor extends AbstractProcessor {
    /**
     * 文件相关的辅助类
     */
    private Filer mFiler;
    /**
     * 元素相关的辅助类
     */
    private Elements mElementUtils;
    /**
     * 日志相关的辅助类
     */
    private Messager mMessager;
    /**
     * 解析的目标注解集合
     */
    private Map<String, AnnotatedClass> mAnnotatedClassMap = new HashMap<>();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mElementUtils = processingEnv.getElementUtils();
        mMessager = processingEnv.getMessager();
        mFiler = processingEnv.getFiler();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> types = new LinkedHashSet<>();
        types.add(BindView.class.getCanonicalName());//返回该注解处理器支持的注解集合
        return types;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return true;
    }
}

是还是不是注意到了中间有个Map容器,而且类型是AnnotatedClass,那是干啥的吧?那么些很好驾驭,大家在解析XML,解析Json的时候数据解析完事后是还是不是要以对象的情势表示出来,那里也一律,@BindView用来标记类成员,一个类下能够有八个成员,好比七个Activity中能够有四个控件,二个容器下有多少个控件等。如下:

package com.mingwei.myprocess.model;

import com.mingwei.myprocess.TypeUtil;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import java.util.ArrayList;
import java.util.List;

import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/**
 * Created by mingwei on 12/10/16.
 * CSDN:    http://blog.csdn.net/u013045971
 * Github:  https://github.com/gumingwei
 */
public class AnnotatedClass {
    /**
     * 类名
     */
    public TypeElement mClassElement;
    /**
     * 成员变量集合
     */
    public List<BindViewField> mFiled;
    /**
     * 元素辅助类
     */
    public Elements mElementUtils;

    public AnnotatedClass(TypeElement classElement, Elements elementUtils) {
        this.mClassElement = classElement;
        this.mElementUtils = elementUtils;
        this.mFiled = new ArrayList<>();
    }
    /**
     * 获取当前这个类的全名
     */
    public String getFullClassName() {
        return mClassElement.getQualifiedName().toString();
    }
    /**
     * 添加一个成员
     */
    public void addField(BindViewField field) {
        mFiled.add(field);
    }
    /**
     * 输出Java
     */
    public JavaFile generateFinder() {
        return null;
    }
    /**
     * 包名
     */
    public String getPackageName(TypeElement type) {
        return mElementUtils.getPackageOf(type).getQualifiedName().toString();
    }
    /**
     * 类名
     */
    private static String getClassName(TypeElement type, String packageName) {
        int packageLen = packageName.length() + 1;
        return type.getQualifiedName().toString().substring(packageLen).replace('.', '$');
    }
}

分子用BindViewField表示,没什么复杂的逻辑,在构造函数判断项目和发轫化,不难的get函数

package com.mingwei.myprocess.model;

import com.mingwe.myanno.BindView;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;

/**
 * Created by mingwei on 12/10/16.
 * CSDN:    http://blog.csdn.net/u013045971
 * Github:  https://github.com/gumingwei
 * 被BindView注解标记的字段的模型类
 */
public class BindViewField {

    private VariableElement mFieldElement;

    private int mResId;

    public BindViewField(Element element) throws IllegalArgumentException {
        if (element.getKind() != ElementKind.FIELD) {//判断是否是类成员
            throw new IllegalArgumentException(String.format("Only field can be annotated with @%s",
                    BindView.class.getSimpleName()));
        }
        mFieldElement = (VariableElement) element;
        //获取注解和值
        BindView bindView = mFieldElement.getAnnotation(BindView.class);
        mResId = bindView.value();
        if (mResId < 0) {
            throw new IllegalArgumentException(String.format("value() in %s for field % is not valid",
                    BindView.class.getSimpleName(), mFieldElement.getSimpleName()));
        }
    }

    public Name getFieldName() {
        return mFieldElement.getSimpleName();
    }

    public int getResId() {
        return mResId;
    }

    public TypeMirror getFieldType() {
        return mFieldElement.asType();
    }
}

此地看看了很多的Element,在Xml解析时候就有Element这几个定义。在Java源文件中千篇一律有Element概念:

package com.example;        // PackageElement

public class MyClass {      // TypeElement

    private int a;          // VariableElement

    private Foo other;      // VariableElement

    public Foo () {}        // ExecuteableElement

    public void setA (      // ExecuteableElement
                int newA    // TypeElement
                ) {

    }
}

接下去正是在处理器的process中分析注明了
每趟解析前都要清空,因为process方法大概持续走2遍。
得到申明模型之后遍历调用生成Java代码

@Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        mAnnotatedClassMap.clear();
        try {
            processBindView(roundEnv);
        } catch (IllegalArgumentException e) {
            error(e.getMessage());
            return true;
        }

        try {
            for (AnnotatedClass annotatedClass : mAnnotatedClassMap.values()) {
                info("generating file for %s", annotatedClass.getFullClassName());
                annotatedClass.generateFinder().writeTo(mFiler);
            }
        } catch (Exception e) {
            e.printStackTrace();
            error("Generate file failed,reason:%s", e.getMessage());
        }
        return true;
    }

processBindView 和 getAnnotatedClass

    /**
     * 遍历目标RoundEnviroment
     * @param roundEnv
     */
    private void processBindView(RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(BindView.class)) {
            AnnotatedClass annotatedClass = getAnnotatedClass(element);
            BindViewField field = new BindViewField(element);
            annotatedClass.addField(field);
        }
    }
    /**
     * 如果在map中存在就直接用,不存在就new出来放在map里
     * @param element
     */
    private AnnotatedClass getAnnotatedClass(Element element) {
        TypeElement encloseElement = (TypeElement) element.getEnclosingElement();
        String fullClassName = encloseElement.getQualifiedName().toString();
        AnnotatedClass annotatedClass = mAnnotatedClassMap.get(fullClassName);
        if (annotatedClass == null) {
            annotatedClass = new AnnotatedClass(encloseElement, mElementUtils);
            mAnnotatedClassMap.put(fullClassName, annotatedClass);
        }
        return annotatedClass;
    }

3.在生成Java以前 大家要在bindview-api 中开创壹些类,同盟bindview-compiler 一起利用。
您在选用Butterknife的时候不是要在onCreate里掉用一下BindView.bind(this)吗,那这个人是怎么呢。试想一下,前边做的一大堆工作是为着扭转自动绑定控件的Java代码,假设生成的Java代码不能够和你要使用的地点关系起来,那也是尚未用的,可以把BindView.bind(this)通晓为调用了你转移的Java代码,而生成了代码中成就了部分控件的初叶化学工业作,自然你的控件就变得可用了。
接口:Finder 定义findView方法
实现类:ActivityFinder Activity中使用,ViewFinder View中使用
接口:Injector
inject方法现在是要成立在扭转的Java文件中,用该办法中传送过来的参数举行控件的伊始化。
扶助类:ViewInjector 调用和传递参数
本条代码我就不贴了,就一丝丝剧情,1看就精晓了。
4.在AnnotatedClass中生成Java代码
转移代码应用了二个很好用的库 Javapoet
。类,方法,都足以使用营造器营造出来,很好上手,再也不用拼接字符串了。哈哈哈哈~

public JavaFile generateFinder() {
        //构建方法
        MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder("inject")
                .addModifiers(Modifier.PUBLIC)//添加描述
                .addAnnotation(Override.class)//添加注解
                .addParameter(TypeName.get(mClassElement.asType()), "host", Modifier.FINAL)//添加参数
                .addParameter(TypeName.OBJECT, "source")//添加参数
                .addParameter(TypeUtil.FINDER, "finder");//添加参数

        for (BindViewField field : mFiled) {
            //添加一行
            injectMethodBuilder.addStatement("host.$N=($T)finder.findView(source,$L)", field.getFieldName()
                    , ClassName.get(field.getFieldType()), field.getResId());
        }

        String packageName = getPackageName(mClassElement);
        String className = getClassName(mClassElement, packageName);
        ClassName bindClassName = ClassName.get(packageName, className);
        //构建类
        TypeSpec finderClass = TypeSpec.classBuilder(bindClassName.simpleName() + "$$Injector")//类名
                .addModifiers(Modifier.PUBLIC)//添加描述
                .addSuperinterface(ParameterizedTypeName.get(TypeUtil.INJECTOR, TypeName.get(mClassElement.asType())))//添加接口(类/接口,范型)
                .addMethod(injectMethodBuilder.build())//添加方法
                .build();

        return JavaFile.builder(packageName, finderClass).build();
    }

    public String getPackageName(TypeElement type) {
        return mElementUtils.getPackageOf(type).getQualifiedName().toString();
    }

    private static String getClassName(TypeElement type, String packageName) {
        int packageLen = packageName.length() + 1;
        return type.getQualifiedName().toString().substring(packageLen).replace('.', '$');
    }

能够在代码里System.out调节和测试评释处理器的代码。
还要小心的有个别,项目里面包车型客车互相引用。
bindview-complier 引用 bindview-annotation
app 引用了剩余的四个module,在引用 bindview-complier 的时候用的apt的法子

apt project(':bindview-compiler')

就写到那里吧,Demo
放在 Github上了

  ((System.ComponentModel.ISupportInitialize)(this.performanceCounter1)).EndInit();

三、随时随处小编也能增加—HtmlHelper增加方法简介

  这些法子就算简短,可是会出错。

三.1 扩充方法简介

  借助MSDN的介绍:“增添方法使你能够向现有项目“添加”方法,而无需创制新的派生类型、重新编写翻译或以其余艺术修改原始类型。”扩大方法是1种新鲜的静态方法,但足以像增添项目上的实例方法同样实行调用。大家能够再次来到第2部分对HtmlHelper的恢宏类-InputExtension类上,它是对此HtmlHelper的扩大,那么怎么分辨它是HtmlHelper的扩大呢?

  原因是,当您添加performanceCounte之类的控件时,它会要求生成CategoryName,但VS突然犯傻,未有自动生成CategoryName,所以报了错。(CategoryName指的正是控件要用的名字)

三.二 扩张方法的叁要素

金沙注册送58 6

  (1)静态类

  能够从上海教室看出,InputExtension首先是一个静态类;

  (二)静态方法

  既然是静态类,那么其颇具的艺术肯定都是静态方法,例如:public
static MvcHtmlString CheckBox();

  (3)this关键字

  能够从事艺术工作术名定义中看出,第三个参数都以this
HtmlHelper htmlHelper,代表对HtmlHelper类的壮大;

 

三.三 自定义扩充方法

  (一)在Models文件夹下新建三个类,取名称叫:MyHtmlHelperExt

  (二)将MyHtmlHelperExt设置为static,并写入以下的2个静态方法:

public static HtmlString MyExtHtmlLabel(this HtmlHelper helper, string value)  {        return new HtmlString(string.Format("Hello-{0}-End", value));  }

  (叁)分明满足了扩大方法的叁要素之后,将命名空间改为:System.Web.Mvc。

namespace System.Web.Mvc

data-source=”Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.”>PS:为何要改命名空间为System.Web.Mvc?

data-source=”Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.”>那是因为若是不改命名空间,大家要利用自定义的壮大方法要求在各种页面中引进Models(MyHtmlHelper所在的十二分命名空间)那几个命名空间,为了以免再一次的命名空间引进操作(想想大家采取Html.Text博克斯()不也从不引进命名空间么?),于是我们将命名空间与HtmlHelper类所在的命名空间保持1致。

  (四)在页面中大家就足以使用我们温馨写的恢弘方法了

<%: Html.MyExtHtmlLabel("EdisonChou") %>

  (5)查看页面效果

金沙注册送58 7

二、妥当的消除办法

参照小说

(1)马伦,《ASP.Net
MVC视频教程》,

(2)oer,《HtmlHelper使用全称》,

(三)MSDN,《增加方法(C#编制程序指南)》,

(4)MSDN,《HtmlHelper类(System.Web.Mvc)》,

 

作者:周旭龙

出处:

本文版权归小编和和讯共有,欢迎转载,但未经小编同意必须保留此段证明,且在作品页面分明地方给出原来的书文链接。


  在Form1.Designer中添加
    this.performanceCounter1.CategoryName = “Processor”;
    this.performanceCounter1.CounterName = “% Processor Time”;
    this.performanceCounter1.InstanceName = “_Total”;

  

 

————————————假装那是贰个分割线————————————

金沙注册送58 8

相关文章

网站地图xml地图