jdk1.5新特性
注释是给程序员看的,注解是给虚拟机看的
用框架的时候直接用
元注解:5个 注解的注解
@ Retention
@ Inherited
@Target
@ Document
@ Repeatable JDK1.8
/**
*
*@param a 文档注释
*/
public static void bindActicity(Activity activity){
<pre name="code" class="java"> findViewById(activity)
}
//通过反射拿到View
public static void findViewById(Activity activity){
Class<?> c = acticity.getClass();
Field[]fs=c.getDeclaredFields();
for(Field filed:fs){
if(field.isAnnotationPresent(InitView.class)){
int id=field.getAnnotation(InitView.class).value();//通过反射 遍历拿到注解的值
int(id>0){
field.setAccessible(true);
try{
field.set(activity,activity.findViewById(id));
}catch(Exception e){e.printStackTrace();}
}
}
}
}
@interface 来定义注解 里面只有属性,没有方法,类型可以使基本、引用、枚举
<pre name="code" class="java">//定义注解什么时期有用
编译 字节码 运行
@Retention(RetentionPolicy.RUNTIME)
//定义修饰什么属性
@Target(ElementType.FIELD)
@interface InitView { int value() default 0;}
main:
InitViewAnnotion.bindActivity(this);
private TextView tv;
@TextView(R.id.tv);
tv.setText("mayun");
//=====================================================================================
进阶:参考文章:http://xiangdonglee.iteye.com/blog/2235607
一、注解式框架
二、Butter Knife
案例一
案例二:用 ListView 展示一个列表数据,每个Item里含有一个Button,可以点击。
一、注解式框架
1. 注解式开发:
JDK 1.5后支持注解方式。想用注解式开发,就要自定义注解。
@Override就是一种自带的注解。很多框架都采用注解方式来实现。
当追求更高的开发效率,用更简洁的代码、更清晰的代码逻辑来进行高效的开发的时候,使用注解式框架开发可简化代码,提升开发效率和代码的可读性。
2. 主流注解式框架:
(1)AndroidAnnotations
配置麻烦,需要在功能清单文件中注册生成的子类。反射机制会占用资源内存,且耗时。
(2)Dagger
采用预编译技术,高效。但是对View绑定操作注解不是很方便。
(3)Butter Knife
它是View 及事件等依赖注入框架。使用方便,配置简单,有强大的View注入绑定和简单的常用方法注解。
二、Butter Knife
它是View 及事件等依赖注入框架。
1. 特点:
(1)强大的View注入绑定和Click事件的处理。简化代码,提升开发效率。
(2)可以方便地处理ListView的Adapter里的ViewHolder绑定问题。
(3)运行时不会影响App效率,使用配置方便。
(4)代码思路清晰,可读性强。
2. 用法:
导包:
compile 'com.jakewharton:butterknife:6.0.0'
在当前 Activity(this)的onCreate中注册(注入黄油刀):
- ButterKnife.inject(this);
(1)View绑定(绑定控件):
Activity声明绑定控件:
- @InjectView(R.id.tvTitle)
- TextView tvTitle;
黄油刀注入控件,相当于:先声明变量,然后通过 findViewById(R.id.tvCompany) 初始化变量。黄油刀直接帮我们绑定好了控件:
InjectView: Bind a field to the view for the specified ID. The view will automatically be cast to the field type.
- @InjectView(R.id.tvTitle) // 相当于 通过 findViewById(R.id.tvCompany) 初始化变量。
- TextView tvTitle; // 相当于 声明变量:private TextView tvCompany;
注意:不同写为:private TextView tvTitle; 会报错:@InjectView fields must not be private or static.
(2)Onclick等事件处理:
- @OnClick(R.id.btnHello)
- public void sayHi(){
- Toast.makeText(this,"你好!",Toast.LENGTH_SHORT).show();
- }
(3)ListView的Adapter里的ViewHolder绑定问题。
案例一
1. strings.xml。字符串。
- <resources>
- <string name="app_name">ButterKnifeDemo</string>
- <string name="hello_world">Hello world!</string>
- <string name="action_settings">Settings</string>
- <string name="btn_good_night">Good Night!</string>
- <string name="btn_play">播放</string>
- <string name="btn_stop">停止</string>
- <string name="btn_view_holder">ViewHolder</string>
- </resources>
2. activity_main.xml。布局
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity">
- <Button
- android:id="@+id/btnHello"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/hello_world"/>
- <Button
- android:id="@+id/btnGoodNight"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/btnHello"
- android:text="@string/btn_good_night"/>
- <Button
- android:id="@+id/btnPlay"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/btnGoodNight"
- android:text="@string/btn_play"/>
- <Button
- android:id="@+id/btnStop"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/btnPlay"
- android:text="@string/btn_stop"/>
- <Button
- android:id="@+id/btnViewHolder"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/btnStop"
- android:text="@string/btn_view_holder"/>
- </RelativeLayout>
3. MainActivity。View绑定和Onclick事件处理
- package com.android.butterknifedemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
- import butterknife.ButterKnife;
- import butterknife.InjectView;
- import butterknife.OnClick;
- import butterknife.Optional;
- public class MainActivity extends Activity {
- // 2. Actitvity里声明绑定控件
- // @Optional:加入后,若此id不存在,则程序不会崩溃,而是抛出异常
- @Optional@InjectView(R.id.btnHello)
- Button buttonHello;
- @InjectView(R.id.btnPlay)
- Button buttonPlay;
- @InjectView(R.id.btnStop)
- Button buttonStop;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 1. onCreate() 方法里注册 ButterKnife
- ButterKnife.inject(this);
- }
- // 3. 注入 View 事件,不带参数
- @OnClick(R.id.btnHello)
- public void sayHi(){
- Toast.makeText(this,"你好!",Toast.LENGTH_SHORT).show();
- }
- // 4. 注入 View 事件,带参数
- @OnClick(R.id.btnGoodNight)
- public void sayGoodNight(Button btnGoodNight){
- btnGoodNight.setText("晚上好!");
- }
- // 5. 同时注入多个 View 事件
- @OnClick({R.id.btnPlay,R.id.btnStop})
- public void playMusic(View view){
- switch (view.getId()){
- case R.id.btnPlay:
- Toast.makeText(this,"播放音乐",Toast.LENGTH_SHORT).show();
- break;
- case R.id.btnStop:
- Toast.makeText(this,"停止播放",Toast.LENGTH_SHORT).show();
- }
- }
- // ----------------------------------------------------------
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- //noinspection SimplifiableIfStatement
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
- }
4. MyAdapter。处理ListView的Adapter里的ViewHolder绑定问题。
- package com.android.butterknifedemo;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.TextView;
- import butterknife.ButterKnife;
- import butterknife.InjectView;
- /**
- * 在 ViewHolder 模式中注入
- */
- // 1. 继承自 BaseAdapter
- public class MyAdapter extends BaseAdapter{
- // 4. 定义上下文
- private Context mContext;
- /**
- * 5. 构造方法
- * @param context
- */
- public MyAdapter(Context context) {
- // 上下文通过构造方法传过来
- mContext = context;
- }
- @Override
- public int getCount() {
- return 0;
- }
- @Override
- public Object getItem(int position) {
- return position;
- }
- @Override
- public long getItemId(int position) {
- return 0;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // 3. 声明 holder 为空
- ViewHolder holder = null;
- // 6.
- if(holder==null){
- // 重新载入布局
- convertView = LayoutInflater.from(mContext).inflate(
- R.layout.activity_main,parent,false);
- // 对 holder 进行实例化
- holder = new ViewHolder(convertView);
- // 获得按钮控件
- holder.btnViewHolder = (Button) convertView.findViewById(R.id.btnViewHolder);
- // 设置标签
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- // 7.
- holder.btnViewHolder.setText("更改");
- return convertView;
- }
- // 2. 写一个 结构持有者 类
- static class ViewHolder{
- @InjectView(R.id.btnViewHolder)
- Button btnViewHolder;
- public ViewHolder(View view){
- ButterKnife.inject(this,view);
- }
- }
- }
案例二:用 ListView 展示一个列表数据,每个Item里含有一个Button,可以点击。
1. activity_main.xml。布局:一个ListView。
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity">
- <ListView
- android:id="@+id/listView"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </RelativeLayout>
2. item.xml。每一个ListView的项。包括一个文本和一个按钮
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:descendantFocusability="blocksDescendants"
- android:orientation="vertical">
- <TextView
- android:id="@+id/tvText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_name" />
- <Button
- android:id="@+id/btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/tvText" />
- </RelativeLayout>
注:ListView中出现button等可以拦截点击事件的控件的时候,要加属性:
- android:descendantFocusability="blocksDesendants"
3. MyAdapter。自定义适配器。
- package com.android.bufferknifedemo;
- import android.content.Context;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.TextView;
- import android.widget.Toast;
- import java.util.ArrayList;
- import butterknife.ButterKnife;
- import butterknife.InjectView;
- /**
- * Created by Xiangdong on 2015/7/12.
- */
- public class MyAdapter extends BaseAdapter {
- Context mContext;
- private ArrayList<String> lists;
- public MyAdapter(Context context, ArrayList<String> list) {
- mContext = context;
- lists = list;
- }
- @Override
- public int getCount() {
- return lists.size();
- }
- @Override
- public Object getItem(int position) {
- return lists.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = View.inflate(mContext, R.layout.item, null);
- holder = new ViewHolder(convertView);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- String s = lists.get(position);
- holder.tvText.setText(s);
- holder.btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Toast.makeText(mContext, "点击", Toast.LENGTH_SHORT).show();
- }
- });
- return convertView;
- }
- static class ViewHolder {
- // 绑定控件
- @InjectView(R.id.tvText)
- TextView tvText;
- @InjectView(R.id.btn)
- Button btn;
- public ViewHolder(View view) {
- ButterKnife.inject(this, view);
- }
- }
- }
4. MainActivity。
- package com.android.bufferknifedemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.widget.ListView;
- import android.widget.Toast;
- import java.util.ArrayList;
- import butterknife.ButterKnife;
- import butterknife.InjectView;
- import butterknife.OnItemClick;
- public class MainActivity extends Activity {
- @InjectView(R.id.listView)
- ListView listView;
- private MyAdapter adapter;
- private ArrayList<String> list;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- ButterKnife.inject(this);
- list = new ArrayList<>();
- list.add("测试1");
- list.add("测试2");
- list.add("测试3");
- list.add("测试4");
- list.add("测试5");
- list.add("测试6");
- list.add("测试7");
- list.add("测试8");
- list.add("测试9");
- adapter = new MyAdapter(this, list);
- listView.setAdapter(adapter);
- }
- @OnItemClick(R.id.listView)
- public void onMyItemClick(int position) {
- Toast.makeText(this, "位置:" + position, Toast.LENGTH_SHORT).show();
- }
- // ------------------------------------------------------------------
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- //noinspection SimplifiableIfStatement
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
- }