使用Android Studio對代碼進行重構
來自: http://blog.csdn.net/guijiaoba/article/details/50608606
使用Android Studio對代碼進行重構
簡介
2013年Google I/O大會上,谷歌推出新的Android開發環境——Android Studio,從此Android程序員有了新的選擇,使用Android Studio進行App開發。AndroidStudio是一項全新的基于IntelliJ IDEA的Android開發環境。類似于Eclipse ADT插件,現在已經成為了官方推薦的ide,同時Eclipse不再進行更新。
軟件開發中,經過幾個版本迭代,不少程序員會覺的以前的代碼架構可能不滿足日益增長的需求,這時候都會想到了重構,關于重構網上也有不少用于的資料。
資料里面列舉了如下幾種方法,對代碼進行重構。
31天重構學習筆記01. 封裝集合 31天重構學習筆記02. 移動方法 31天重構學習筆記03. 提升方法 31天重構學習筆記04. 降低方法 31天重構學習筆記05. 提升字段 31天重構學習筆記06. 降低字段 31天重構學習筆記07. 重命名(方法,類,參數) 31天重構學習筆記08. 使用委派代替繼承 31天重構學習筆記09. 提取接口 31天重構學習筆記10. 提取方法 31天重構學習筆記11. 使用策略類 31天重構學習筆記12. 分解依賴 31天重構學習筆記13. 提取方法對象 31天重構學習筆記14. 分離職責 31天重構學習筆記15. 移除重復內容 31天重構學習筆記16. 封裝條件 31天重構學習筆記17. 提取父類 31天重構學習筆記18. 使用條件判斷代替異常 31天重構學習筆記19. 提取工廠類 31天重構學習筆記20. 提取子類 31天重構學習筆記21. 合并繼承 31天重構學習筆記22. 分解方法 31天重構學習筆記23. 引入參數對象 31天重構學習筆記24. 分解復雜判斷 31天重構學習筆記25. 引入契約式設計 31天重構學習筆記26. 避免雙重否定 31天重構學習筆記27. 去除上帝類 31天重構學習筆記28. 為布爾方法命名 31天重構學習筆記29. 去除中間人對象 31天重構學習筆記30. 盡快返回 31天重構學習筆記31. 使用多態代替條件判斷
Android Studio是基于優秀的ide的,ide提供了豐富的功能,很方便的對代碼進行重構,下圖是我的Android Studio Refactor菜單,部分快捷鍵與默認快捷鍵不同是因為方便而修改的。
古人云『工欲善其事必先利其器』,所以在對代碼進行重構前,需要詳細了解Android Studio提供的功能,下面對AS(Android Studio,后面簡稱AS)菜單進行簡單示例。
如何使用
鼠標光標選中或者放在代碼上,按下快捷鍵就可以彈出當前代碼可以使用的功能。
如下所示:
代碼與操作示例
- ChangeSignature,改變函數簽名,可以修改函數的名字,參數的順序,參數的名字。
Before:
// 改變簽名 void testChangeSignature(int second, int first) { System.out.println(first + "->" + second); }
Gif:
After:
// 改變簽名 void testChangeSignature(int one, int two) { System.out.println(one + "->" + two); }
修改前參數依次是second、first,修改是one、two。
- ChangeClassSignatuere,改變類的簽名,可以修改類的泛型簽名
Before:
// 改變類的簽名 void testChangeClassSignatuere() { String second = "second"; int first = 100; new ChangeClassSignatuere(second, first); }// **分割線***
public class ChangeClassSignatuere {
private int first; private String second; public ChangeClassSignatuere(String second, int first) { this.first = first; this.second = second; } @Override public String toString() { return "ChangeClassSignatuere{" + "second='" + second + '\'' + ",first=" + first + '}'; }
} </pre>
Gif:
After:
// 改變類的簽名 void testChangeClassSignatuere() { String second = "second"; int first = 100; new ChangeClassSignatuere<Activity>(second, first); } // **分割線***public class ChangeClassSignatuere<A> {
private int first; private String second; public ChangeClassSignatuere(String second, int first) { this.first = first; this.second = second; } @Override public String toString() { return "ChangeClassSignatuere{" + "second='" + second + '\'' + ",first=" + first + '}'; }
}</pre>
- 修改匿名類為內部類
</ul>
Before:
// 匿名類改成內部類 void testConvertAnonymousToInner() { View.OnClickListener clickListener = new View.OnClickListener() {@Override public void onClick(View v) { System.out.println("onClick"); } }; }</pre>
Gif:
After:
// 匿名類改成內部類 void testConvertAnonymousToInner() {View.OnClickListener clickListener = new Abc123(); } private static class Abc123 implements View.OnClickListener { @Override public void onClick(View v) { System.out.println("onClick"); } }</pre>
這個是我最喜歡的一個功能,有時候匿名類剛剛開始邏輯很簡單,過不了多久邏輯太多,就可以使用快捷鍵變成一個內部類。
- ConvertToInstanceMethod,修改一個方法變成成員方法
Befor:
// 變成成員方法 void testConvertToInstanceMethod() { TestClass.convertToInstanceMethod(this, "test"); }public class TestClass {
static void convertToInstanceMethod(RefactorDemo demo, String string) { System.out.println("convertToInstanceMethod = " + demo); System.out.println("convertToInstanceMethod = " + string); }
} </pre>
After:
// 變成成員方法 void testConvertToInstanceMethod() { this.convertToInstanceMethod("test"); }void convertToInstanceMethod(String string) { System.out.println("convertToInstanceMethod = " + this); System.out.println("convertToInstanceMethod = " + string); }</pre>
在修改前,調用convertToInstanceMethod方法,第一個參數相是RefactorDemo,傳遞是this, 修改后就那個方法直接移動到本類中。
- Copy,復制一個類
Before:
// 復制一個類 void testCopy() { new FirstClass(); }public class FirstClass implements Serializable {
public String first; @Override public String toString() { return "FirstClass{" + "first='" + first + '\'' + '}'; }
}</pre>
Gif:
After:
public class SecondClass implements Serializable {public String first; @Override public String toString() { return "SecondClass{" + "first='" + first + '\'' + '}'; }
}</pre>
- EncapsulateFields,壓縮一個字段,間接訪問
</ul>
Before:
String filed = "filed";// 壓縮一個字段,間接訪問 void testEncapsulateFields() { System.out.println(filed); }</pre>
After:
private String filed = "filed";// 壓縮一個字段,間接訪問 void testEncapsulateFields() { System.out.println(getFiled()); } public String getFiled() { return filed; } public void setFiled(String filed) { this.filed = filed; }</pre>
相當于簡介訪問一個field,自動生成setter和getter。
- GenerifyRefactoring,泛型重構
Before:
// 泛型重構 void testGenerifyRefactoring() { List list = new ArrayList(); list.add("one"); list.add("two"); list.add("three"); }
After:
// 泛型重構 void testGenerifyRefactoring() { List<String> list = new ArrayList<String>(); list.add("one"); list.add("two"); list.add("three"); }
自動添加泛型的參數。
- Inline,內聯函數
Before:
// 內聯 void testInline() { int a = 100; int b = 200; System.out.println(add(a, b)); }int add(int a, int b) { return a + b; }</pre>
Gif:
After:
// 內聯 void testInline() { int a = 100; int b = 200; System.out.println(a + b); }原先需要調用一個函數的地方,直接把那個函數里面的代碼復制過來。
- InvertBoolean,重構Boolean
Before:
// 重構Boolean void testInvertBoolean() { System.out.println(checkPaswd(null)); System.out.println(checkPaswd("")); System.out.println(checkPaswd("admin")); }boolean checkPaswd(String passwd) { if (passwd != null && passwd.length() != 0) { return true; } return false; }</pre>
Gif:
After:
// 重構Boolean void testInvertBoolean() { System.out.println(checkPaswd(null)); System.out.println(checkPaswd("")); System.out.println(checkPaswd("admin")); }boolean checkPaswd(String passwd) { return passwd != null && passwd.length() != 0; }</pre>
- MakeClassStatic,使類變成靜態的
Before:
// 使類變成靜態的 void testMakeClassStatic() { new MyClass().fun(); }String myClassField = "abc"; class MyClass { void fun() { System.out.println("myClassField = " + myClassField); } }</pre>
Gif:
After:
// 使類變成靜態的 void testMakeClassStatic() { new MyClass(myClassField).fun(); }String myClassField = "abc"; static class MyClass { private String myClassField; public MyClass(String myClassField) { this.myClassField = myClassField; } void fun() { System.out.println("myClassField = " + myClassField); } }</pre>
修改前需要調用外部內的成員變量myClassField,實際編譯過后MyClass的class是持有外部類的對象,這樣才能訪問myClassField,通過重構,使得myClassField通過構造方法傳入進去,然后再在fun方法中使用,這樣重構會減少類的依賴。
- MakeMethodStatic,使方法變成靜態的
Before:
// 使方法變成靜態的 void testMakeMethodStatic() { myFun(); }void myFun() { System.out.println("myFun"); }</pre>
After:
// 使方法變成靜態的 void testMakeMethodStatic() { myFun(); }static void myFun() { System.out.println("myFun"); }</pre>
- Move,移動一個類
Before:
// 移動一個類 void testMove() { new MoveClass().fun(); }static class MoveClass { String movde; @Override public String toString() { return "MoveClass{" + "movde='" + movde + '\'' + '}'; } void fun() { System.out.println(this); } }</pre>
Gif:
After:
// 移動一個類 void testMove() { new MoveClassxxxxxx().fun(); }class MoveClassxxxxxx {
String movde; @Override public String toString() { return "MoveClass{" + "movde='" + movde + '\'' + '}'; } void fun() { System.out.println(this); }
} </pre>
- PullMenmberUp,上移
</ul>
Before:
public class Base {public String baseString; public Base(String baseString) { this.baseString = baseString; } public void funBase() { System.out.println(baseString); }
} public class Sub extends Base {
public Sub(String baseString) { super(baseString); } public void funSub() { System.out.println(baseString); }
}
// 上移 void testPullMenmberUp() { new Sub("base").funSub(); }</pre>
Gif:
After:
public class Base {public String baseString; public Base(String baseString) { this.baseString = baseString; } public void funBase() { System.out.println(baseString); } public void funSub() { System.out.println(baseString); }
}
public class Sub extends Base {
public Sub(String baseString) { super(baseString); }
}</pre>
實際上就是把子類中的方法移動到父類中。
- PullMenmberDown,下移
Before:
public class Base {public String baseString; public Base(String baseString) { this.baseString = baseString; } public void funBase() { System.out.println(baseString); }
} public class Sub extends Base {
public Sub(String baseString) { super(baseString); } public void funSub() { System.out.println(baseString); }
} // 下移 void testPullMenmberDown() { new Sub("base").funBase(); }</pre>
After:
public class Base {public String baseString; public Base(String baseString) { this.baseString = baseString; }
}
public class Sub extends Base {
public Sub(String baseString) { super(baseString); } public void funSub() { System.out.println(baseString); } public void funBase() { System.out.println(baseString); }
}</pre>
實際上就是把父類中的方法移動到子類中。
- Rename,重命名
這個功能也是我最喜歡的,只要選擇重命名一個對象或者資源,所有使用到這個對象或者資源的地方,都會進行重新命名。
Before:
// 重命名 void testRename() { String first = "second"; System.out.println(first); }
Gif:
After:
// 重命名 void testRename() { String second = "second"; System.out.println(second); }
- ReplaceConstructorWithBuilder,構造方法變成builder
</ul>
還在羨慕Picasso,Fresco人性化調用方式嗎?很簡單,通過這個功能就可以快速生成代碼
Before:
public class MyAlertDialog {private String title; private String message; private String okButton; private String cancelButton; public MyAlertDialog(String title, String message, String okButton, String cancelButton) { this.title = title; this.message = message; this.okButton = okButton; this.cancelButton = cancelButton; }
}
// 構造方法變成builder void testReplaceConstructorWithBuilder() { new MyAlertDialog("title", "message", "ok", "cancel").show(); }</pre>Gif:
After:
// 構造方法變成builder void testReplaceConstructorWithBuilder() { new MyAlertDialog.Builder() .setTitle("title") .setMessage("message") .setOkButton("ok") .setCancelButton("cancel") .createMyAlertDialog() .show(); }public static class Builder { private String title; private String message; private String okButton; private String cancelButton;
public Builder setTitle(String title) { this.title = title; return this; } public Builder setMessage(String message) { this.message = message; return this; } public Builder setOkButton(String okButton) { this.okButton = okButton; return this; } public Builder setCancelButton(String cancelButton) { this.cancelButton = cancelButton; return this; } public MyAlertDialog createMyAlertDialog() { return new MyAlertDialog(title, message, okButton, cancelButton); }
}</pre>
- ReplaceConstructorWithFactory,構造方法變成工程方法
</ul>
Before:
// 構造方法變成工程方法 void testReplaceConstructorWithFactory() { new MyAlertDialog("title", "message", "ok", "cancel").show(); }
Gif:
After:
// 構造方法變成工程方法 void testReplaceConstructorWithFactory() { MyAlertDialog.newInstance("title", "message", "ok", "cancel") .show(); } public class MyAlertDialog {
private MyAlertDialog(String title, String message, String okButton, String cancelButton) { this.title = title; this.message = message; this.okButton = okButton; this.cancelButton = cancelButton; }public static MyAlertDialog newInstance(String title, String message, String okButton, String cancelButton) { return new MyAlertDialog(title, message, okButton, cancelButton); }
} </pre>
通過上面代碼發現,如果構造方法變成了工廠方式,那么它的構造參數是private的,這樣調用者只能通過工廠方式來生成對象。
- ReplaceInheritanceWithDelegation,代理代替繼承
Before:
public abstract class AbsClass {public abstract void sayHello();
}
public class ExtClass extends AbsClass {
@Override public void sayHello() { System.out.println("hello"); }
} // 代理代替繼承 void testReplaceInheritanceWithDelegation() { new ExtClass().sayHello(); }</pre>
Gif:
After:
public class ExtClass {private final AbsClassImpl abs = new AbsClassImpl(); public void sayHello() { abs.sayHello(); } private class AbsClassImpl extends AbsClass { @Override public void sayHello() { System.out.println("hello"); } }
}
// 代理代替繼承 void testReplaceInheritanceWithDelegation() { new ExtClass().sayHello(); }</pre>
書上說過,組合由于繼承大概說的就是這個意思。
- SafeDelete,安全刪除
Before:
// 安全刪除 void testSafeDelete() { String unUsedString = "abc";unUsedString = getUnUsedString(); System.out.println(new Date()); } public String getUnUsedString() { return unUsedString; }</pre>
After:
// 安全刪除 void testSafeDelete() { System.out.println(new Date()); }這個比較簡單,如果某個變量沒有使用,那么直接直接刪除所有引用這個變量的地方。
- WrapReturnValue,封裝返回值
Before:
// 封裝返回值 void testWrapReturnValue() { System.out.println(getUserName()); }private String getUserName() { return "userName"; }</pre>
Gif:
After:
// 包裝下返回值 void testWrapReturnValue() { System.out.println(getUserName().getValue()); }private UserInfo getUserName() { return new UserInfo("userName"); } public class UserInfo { private final String value; public UserInfo(String value) { this.value = value; } public String getValue() { return value; } }</pre>
- RemoveMiddleMan,去除中間人
Before:
// 去除中間人 void testRemoveMiddleMan() { OrderManager manager = new OrderManager(); manager.newOrder("new"); manager.confirm("confir"); manager.invalidOrder("invalid"); }public static class OrderManager { private List<String> unProcessOrderList; private List<String> processedOrderList; public OrderManager() { unProcessOrderList = new ArrayList<>(); processedOrderList = new ArrayList<>(); } public void newOrder(String order) { unProcessOrderList.add(order); } public void confirm(String order) { unProcessOrderList.remove(order); processedOrderList.add(order); } public void invalidOrder(String order) { processedOrderList.remove(order); } public void display() { System.out.println(unProcessOrderList); System.out.println(processedOrderList); } }</pre>
Gif:
After:
// 去除中間人 void testRemoveMiddleMan() { OrderManager manager = new OrderManager(); manager.getUnProcessOrderList().add("new"); manager.confirm("confir"); manager.getProcessedOrderList().remove("invalid"); }public static class OrderManager { private List<String> unProcessOrderList; private List<String> processedOrderList; public OrderManager() { unProcessOrderList = new ArrayList<>(); processedOrderList = new ArrayList<>(); } public void confirm(String order) { unProcessOrderList.remove(order); processedOrderList.add(order); } public void display() { System.out.println(unProcessOrderList); System.out.println(processedOrderList); } public List<String> getUnProcessOrderList() { return unProcessOrderList; } public List<String> getProcessedOrderList() { return processedOrderList; } }</pre>
用途就是,原先OrderManager持有一個List來保存Order,調用方直接使用OrderManager來處理訂單,去除中間人的意思就是說,調用法直接獲取保存Order的容器,調用方直接自己控制容器。
代碼抽取
代碼抽取在實際使用當中非常有用。
- ExtraMethod,抽取一個方法
Before:
// 抽取一個方法 void testExtraMethod() { Map<String, Integer> map = new HashMap<>(); map.put("one", 1); map.put("two", 2); map.put("three", 2);System.out.println(map); }</pre>
Gif:
After:
// 抽取一個方法 void testExtraMethod() { Map<String, Integer> map = initMap();System.out.println(map); } @NonNull private Map<String, Integer> initMap() { Map<String, Integer> map = new HashMap<>(); map.put("one", 1); map.put("two", 2); map.put("three", 2); return map; }</pre>
- ExtraMethodObject,抽取一個方法到一個對象中
和上面那個差不多,只不過把方法移動到另外一個類中。
Before:
// 抽取一個方法到一個對象中 void testExtraMethodObject() { Map<String, Integer> map = new HashMap<>(); map.put("one", 1); map.put("two", 22); map.put("three", 33);System.out.println(map); }</pre>
After:
// 抽取一個方法到一個對象中 void testExtraMethodObject() { Map<String, Integer> map = MapUtil.invoke(); System.out.println(map); }private static class MapUtil { private static Map<String, Integer> invoke() { Map<String, Integer> map = new HashMap<>(); map.put("one", 1); map.put("two", 22); map.put("three", 33); return map; } } </pre>
- ExtractParameterObject,抽取若干參數成一個類
這個比較使用,有時候一個方法參數太多,可以把這些參數合并成一個類。
Before:
// 抽取若干參數成一個類 void testExtractParameterObject() { print(100, 200); }// widht,height --> Size Class void print(int width, int height) { System.out.println("width = " + width + ", height = " + height); }</pre>
Gif:
After:
// 抽取若干參數成一個類 void testExtractParameterObject() { print(new Size(100, 200)); }// widht,height --> Size Class void print(Size size) { System.out.println("width = " + size.getWidth() + ", height = " + size.getHeight()); }
public class Size { private final int width; private final int height;
public Size(int width, int height) { this.width = width; this.height = height; } public int getWidth() { return width; } public int getHeight() { return height; }
} </pre>
- ExtractSuperclass,抽取到父類
</ul>
Before:
// 抽取到父類 void testExtractSuperclass() { sendEvent("login_success"); }public void sendEvent(Object event) { // EventBus.getDefault().send(event); }</pre>
Gif:
After:
public class BaseExtractDemo { public void sendEvent(Object event) { // EventBus.getDefault().send(event); } }public class ExtractDemo extends BaseExtractDemo { // 抽取到父類 void testExtractSuperclass() { sendEvent("login_success"); } }</pre>
- ExtractConstant,抽取常量
</ul>
Before:
// 抽取常量 void testExtractConstant() { String email = "admin@123.com"; String passwd = "1qaz2wsx";Bundle bundle = new Bundle(); bundle.putString("email", email); bundle.putString("passwd", passwd); }</pre>
Gif:
After:
public static final String KEY_EMAIL = "email"; public static final String KEY_PASSWD = "passwd";// 抽取常量 void testExtractConstant() { String email = "admin@123.com"; String passwd = "1qaz2wsx"; Bundle bundle = new Bundle(); bundle.putString(KEY_EMAIL, email); bundle.putString(KEY_PASSWD, passwd); }</pre>
- ExtractField,抽取成成員變量
Before:
// 抽取成成員變量 void testExtractField() { String testExtractField = "testExtractField"; System.out.println(testExtractField); }
After:
private String testExtractField;// 抽取成成員變量 void testExtractField() { testExtractField = "testExtractField"; System.out.println(testExtractField); }</pre>
- ExtractVariable,抽取成變量
Before:
// 抽取成變量 void testExtractVariable() { System.out.println("long name = " + getLoooooooooooooooooooooooooooooooooooooooooooooooooooooongName()); }String getLoooooooooooooooooooooooooooooooooooooooooooooooooooooongName() { return "getLoooooooooooooooooooooooooooooooooooooooooooooooooooooongName"; }</pre>
Gif:
After:
// 抽取成變量 void testExtractVariable() { String name = getLoooooooooooooooooooooooooooooooooooooooooooooooooooooongName(); System.out.println("long name = " + name); }String getLoooooooooooooooooooooooooooooooooooooooooooooooooooooongName() { return "getLoooooooooooooooooooooooooooooooooooooooooooooooooooooongName"; }</pre>
有時候,一行代碼寫的很長,可以使用這個方法,對代碼進行重構。
- ExtractParameter,抽取成方法的參數
Before:
// 抽取成方法的參數 void testExtractParameter() { printHelloString(); }private void printHelloString() { String str = "printHello"; System.out.println(str); }</pre>
Gif:
After:
// 抽取成方法的參數 void testExtractParameter() { String str = "printHello"; printStringAndLength(str); }private void printStringAndLength(String paramStr) { System.out.println(paramStr + " -> " + paramStr.length()); }</pre>
Android資源重構
- ExtractLayout,布局文件抽取
Before:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="<android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout></pre>
Gif:
After:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="<include layout="@layout/view_top" /> <include layout="@layout/content_main" /> <include layout="@layout/view_button" />
</android.support.design.widget.CoordinatorLayout></pre>
- ExtractStyle,樣式抽取
</ul>
Before:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:textAlignment="center" android:textColor="#f00ff0" android:textSize="18sp" android:textStyle="bold" android:typeface="normal" />Gif:
After:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" style="@style/my_textview_style" /><style name="my_textview_style"> <item name="android:textAlignment">center</item> <item name="android:textColor">#f00ff0</item> <item name="android:textSize">18sp</item> <item name="android:textStyle">bold</item> <item name="android:typeface">normal</item> </style> </pre>
綜合示例
通過一個示例演示怎么樣重構代碼,示例是一個Activity里面有個RecyclerView,然后重構代碼,演示怎么樣分離Adapter,ViewHolder等。
Before:
public class StartActivity extends AppCompatActivity {@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); final List<String> data = new ArrayList<>(); for (int i = 0; i < 100; i++) { data.add("Text " + (i + 1)); } recyclerView.setAdapter(new RecyclerView.Adapter<MyViewHolder>() { @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); return new MyViewHolder(layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false)); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.bind(data.get(position)); } @Override public int getItemCount() { return data.size(); } }); } class MyViewHolder extends RecyclerView.ViewHolder { TextView textView; public MyViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(android.R.id.text1); } void bind(String text) { textView.setText(text); } }
}</pre>
Gif:
After:
public class StartActivity extends AppCompatActivity {private RecyclerView recyclerView; private List<String> data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); initData(); initView(); } private void initData() { data = new ArrayList<>(); for (int i = 0; i < 100; i++) { data.add("Text " + (i + 1)); } } private void initView() { recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(new MyViewHolderAdapter(data)); }
}
class MyViewHolderAdapter extends RecyclerView.Adapter<MyViewHolder> {
private List<String> data; public MyViewHolderAdapter(List<String> data) { this.data = data; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return MyViewHolder.newInstance(parent); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.bind(data.get(position)); } @Override public int getItemCount() { return data.size(); }
}
class MyViewHolder extends RecyclerView.ViewHolder {
public static final int LAYOUT_ID = android.R.layout.simple_list_item_1; @NonNull static MyViewHolder newInstance(ViewGroup parent) { Context context = parent.getContext(); LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return new MyViewHolder(layoutInflater.inflate(LAYOUT_ID, parent, false)); } TextView textView; public MyViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(android.R.id.text1); } void bind(String text) { textView.setText(text); }
}</pre>
總結
至此,Android Studio的重構功能講解完成,由于Android Studio更新很快,很多功能還需要自己去發掘。
『君子生非異也,善假于物也』,好好使用工具,可以偷個懶。
</div>