編輯:關於Android編程
1.Java反射的知識
2.Java注解的知識
<relativelayout android:layout_height="match_parent" android:layout_width="match_parent" tools:context="${relativePackage}.${activityClass}" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"><button android:id="@+id/bt" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="點我"></button></relativelayout>
Activity中的代碼
public class MainActivity extends Activity implements OnClickListener { /** * 按鈕 */ private Button bt = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 找到按鈕 bt = (Button) findViewById(R.id.bt); // 設置點擊事件 bt.setOnClickListener(this); } @Override public void onClick(View v) { Toast.makeText(this, "點我了", Toast.LENGTH_LONG).show(); } }也是很簡單的,然後是效果圖 上面就是我們平常的寫法,那麼我們來看看用了注解框架的寫法,先體驗,再動手寫注解框架
public class MainActivity extends Activity { /** * 按鈕 */ @Injection(value = R.id.bt,click = "clickView") private Button bt = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //讓注解起作用 ViewInjectionUtil.injectView(this); } public void clickView() { Toast.makeText(this, "點我了,用了注解框架", Toast.LENGTH_LONG).show(); } }
@Injection(value = R.id.bt,click = "clickView")此處的R.id.bt就是value的值,所以可以知道就是這裡告訴框架的,而我們的點擊事件起作用了,這裡告訴了框架需要調用的方法的名稱所以我們的一個和普通的方法可以被調用
//讓注解起作用 ViewInjectionUtil.injectView(this);這句代碼就是框架讀取了注解中的信息並且幫你找到了控件,並且注冊相應的事件
/** * 運行時期有效,和針對的是字段 * * @author xiaojinzi * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Injection { /** * 字段對應布局文件的id * * @return */ int value(); /** * 點擊事件 * @return */ String click() default ""; /** * 長按的點擊事件 * @return */ String longClick() default ""; }這裡對代碼做一下解釋@Target(ElementType.FIELD)表示我們聲明的注解是作用到字段上的,你肯定見過作用在方法上的注解,比如:@Override 這個不陌生吧? @Retention(RetentionPolicy.RUNTIME)這個表示我們聲明的注解是運行的時候有效的,還有其他的情況,這裡不做深入 好了,我們的注解就寫好了,注解中有三個屬性可以用,分別是: 1.value int類型 表示控件的id 2.click String類型 點擊事件的方法名稱 3.longClick String類型 長按事件的方法名稱 好了,我們的注解就寫完了,你可以在任何一個字段上面使用這個注解了,都是不會報錯的,但是還沒有實際的作用
/** * 對activity中的字段進行注入 * * @param act */ public static void injectView(Activity act) { // 獲取這個activity中的所有字段 Field[] fields = act.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { // 循環拿到每一個字段 Field field = fields[i]; if (field.isAnnotationPresent(Injection.class)) { // 如果這個字段有注入的注解 // 獲取注解對象 Injection injection = field.getAnnotation(Injection.class); int value = injection.value(); field.setAccessible(true); // 即使私有的也可以設置數據 Object view = null; try { view = act.findViewById(value); // 設置字段的屬性 field.set(act, view); } catch (Exception e) { e.printStackTrace(); L.s(TAG, "注入屬性失敗:" + field.getClass().getName() + ":" + field.getName()); } try { if (view instanceof View) { View v = (View) view; // 獲取點擊事件的觸發的方法名稱 String methodName = injection.click(); EventListener eventListener = null; // 如果不是空字符串 if (!"".equals(methodName)) { eventListener = new EventListener(act); // 設置點擊事件 v.setOnClickListener(eventListener); eventListener.setClickMethodName(methodName); } methodName = injection.longClick(); if (!"".equals(methodName)) { if (eventListener == null) { eventListener = new EventListener(act); } // 設置點擊事件 v.setOnLongClickListener(eventListener); eventListener.setLongClickMethodName(methodName); } } } catch (Exception e) { e.printStackTrace(); } } } }
/** * Created by cxj on 2016/1/21. * * @author 小金子 */ public class EventListener implements View.OnClickListener, View.OnLongClickListener { /** * 類的標識 */ private String tag = "EventListener"; /** * 設置是否有日志的輸出 */ private boolean isLog = false; /** * 反射中要被調用方法的對象,通過構造方法進來 */ private Object receiver = null; /** * 點擊事件的方法名字 */ private String clickMethodName = ""; /** * 長按事件的方法的名字 */ private String longClickMethodName = ""; /** * 設置點擊事件的方法名字 * * @param clickMethodName */ public void setClickMethodName(String clickMethodName) { this.clickMethodName = clickMethodName; } /** * 設置長按的點擊事件的方法的名字 * * @param longClickMethodName */ public void setLongClickMethodName(String longClickMethodName) { this.longClickMethodName = longClickMethodName; } /** * 構造函數 * * @param receiver * 控件所在的activity或者Fragment */ public EventListener(Object receiver) { this.receiver = receiver; } @Override public void onClick(View v) { Method method = null; try { method = receiver.getClass().getMethod(clickMethodName); if (method != null) { // 調用該方法 method.invoke(receiver); } } catch (Exception e) { if (isLog) L.s(tag, "尋找無參數列表的方法:" + clickMethodName + "失敗"); } try { if (method == null) { method = receiver.getClass().getMethod(clickMethodName, View.class); if (method != null) { method.invoke(receiver, v); } } } catch (Exception e) { if (isLog) L.s(tag, "尋找帶有View類型參數的方法:" + clickMethodName + "失敗"); } } @Override public boolean onLongClick(View v) { Method method = null; try { method = receiver.getClass().getMethod(longClickMethodName); if (method != null) { // 調用該方法 method.invoke(receiver); } } catch (Exception e) { if (isLog) L.s(tag, "尋找無參數列表的方法:" + longClickMethodName + "失敗"); } try { if (method == null) { method = receiver.getClass().getMethod(longClickMethodName, View.class); if (method != null) { method.invoke(receiver, v); } } } catch (Exception e) { if (isLog) L.s(tag, "尋找帶有View類型參數的方法:" + longClickMethodName + "失敗"); } return true; } }類EventListener:這個類主要是處理View的事件的,比如點擊事件,長按事件,類實現了這些接口 創建該類的時候需要傳入Activity對象或者Fragment對象,比如點擊事件觸發的時候該類中實現的方法onClick(View)方法被調用,但是並不是用戶指定的方法名的那個方法,所以這裡需要有注解中的click字符串信息,也就是Activity需要調用的方法的方法名,有了方法名和Activity,就可以利用反射從activity中調用指定方法名的方法,從而達到我們開始的時候演示的時候那樣子,點擊按鈕的時候,會調用activity中的bt字段上的注解中的click寫的那個方法名對應的方法
在Android開發中,我們經常會用到ListView、GridView,每次編碼的時候都需要為他們寫對應的Adapter,寫多了就感覺很煩躁了,因為基本的編程思想都是一
榮耀8和榮耀v8有什麼不同?榮耀8發布後,和之前的發布的榮耀v8有什麼不一樣?相信很多人都有這樣的疑問,其實總的一句話就可以概括了:榮耀8主打小屏旗艦,榮耀
這裡主要講解垃圾收集理論上的算法,下一篇會介紹一些實現了這些算法的垃圾收集器。一般我們談垃圾收集從三個問題來幫你理解jvm的垃圾收集策略:1.怎麼判斷哪些內存是垃圾?2.
UI(User Interface)的基本設計 本文地址: http://blog.csdn.net/caroline_wendy UI(User Interfa