
æçš¿è ïŒAnton Valyukhãã·ãã¢ã¢ãã€ã«ããããããŒã
ãã®èšäºã§ã¯ãAndroidã¢ããªã±ãŒã·ã§ã³ã®éçºæã«éåžžã«äŸ¿å©ãªMVVMïŒModel-View-ViewModelïŒèšèšãã¿ãŒã³ã䜿çšããçè«ãšå®è·µã«ã€ããŠèª¬æããŸãã
MVP-ã¢ãã«ãã¥ãŒãã¬ãŒã³ã¿ãŒ
æå§ãã«ãã¡ãã£ãšããçè«ã ããã¯ãã¹ãŠãå€ãã®äººã ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãåããã¢ããªã±ãŒã·ã§ã³ãäœæããããã«MVCïŒModel-View-ControllerïŒãã³ãã¬ãŒããã©ã®ããã«é©åãããããèãããšããäºå®ããå§ãŸããŸããã ãããŠ2006幎ãã GUIã¢ãŒããã¯ã㣠ãã®ä»äºã§ã Martin Fowlerã¯åŸã«ãMVPãïŒãModel-View-PresenterãïŒãšããŠç¥ãããããã«ãªã£ããã³ãã¬ãŒãã詳现ã«èª¿æ»ããŸããã
ãã®ãããMVPã¯MVCãã掟çãããã¶ã€ã³ãã¿ãŒã³ã§ãããäž»ã«ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãæ§ç¯ããããã«èšèšãããŠããŸãã MVPã¯ãèªåãŠããããã¹ãã容æã«ããããžãã¯ãšè¡šç€ºã®åé¢ãæ¹åããããã«äœ¿çšãããŸãã
ãã®ãã³ãã¬ãŒãã«ã¯3ã€ã®èŠçŽ ããããŸãã
- 衚瀺ãã
- ãã¬ãŒã³ã¿ãŒã
- ã¢ãã«
ãã¹ãŠã®ä»çµã¿ã¯æ¬¡ã®ãšããã§ãã

- ViewèŠçŽ ã¯ããŠãŒã¶ãŒããŒã¿ã®è¡šç€ºãšãŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã®ãã£ããã£ãè¡ããŸãã ãã®ãã¹ãŠã圌ããã¬ãŒã³ã¿ãŒã«éä¿¡ããŸãã
- Presenterã¯UIã§ãŠãŒã¶ãŒã¢ã¯ã·ã§ã³ãåŠçããã¢ãã«ã§ã®ããŒã¿å€æŽãèæ ®ããŠããã®æ å ±ããã¥ãŒã«éä¿¡ããŸãã ãã¬ãŒã³ã¿ãŒã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãæäœãããã¹ãŠã®ããžãã¹ããžãã¯ãå«ãèŠçŽ ã§ãã
- ã¢ãã«ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ç¥èãšããŒã¿ãã¡ã€ã³ã衚瀺ãããã¡ã€ã³ã¢ãã«ãå«ãŸããŠããŸãã ã¢ãã«ã¯ãPresenterããŒã¿å€æŽæ å ±ãéä¿¡ããPresenterããã¡ãã»ãŒãžãåä¿¡ããŸãã
MVP-Androidã®å®è£
MVPã§ã¯ããã¥ãŒã®æœè±¡åãäœæã§ããŸãã ãããè¡ãã«ã¯ãç¹å®ã®ããããã£ãšã¡ãœããã®ã»ããã§ãã¬ãŒã³ããŒã·ã§ã³ã€ã³ã¿ãŒãã§ã€ã¹ã匷調衚瀺ããå¿ èŠããããŸãã
èŠãŠã¿ãŸããããããã¯Androidã«å®è£ ã§ããŸãããã®ããã«ãå°ããªããã€ã¯ããäœæããŸãã
Presenterã¯ããã®Viewã®æœè±¡åãèšè¿°ããç¹å¥ãªã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãViewãšå¯Ÿè©±ããŸãã
ãã®ãããªãã¥ãŒã¢ãã«ããããšããŸãã
public interface SomeScreenView { void startLoading(); void stopLoading(); void mapDataItems(final Collection<DataItem> items); }
泚ïŒãã®ãã¥ãŒã¢ãã«ãšç»é¢ã«è¡šç€ºããããã¥ãŒãæ··åããªãã§ãã ããã MVPã§äœ¿çšããããã¥ãŒã¯ããã¥ãŒã®æœè±¡åã§ãã ã€ãŸããããã¯ãã¥ãŒã®åäœã®äžè¬åã§ãã MVPãã¥ãŒã§ã¯ããã¹ãŠããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã«ã©ã®ããã«è¡šç€ºããããã«ã€ããŠæ£ç¢ºã«ã¯è²¬ä»»ãè² ããŸããã 圌女ã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®åäœãæ åœããŸãã
ãã¬ãŒã³ã¿ãŒã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£ ãžã®ãªã³ã¯ãåãåãããã¥ãŒã®ã¢ãã«ãšå¯Ÿè©±ããåæåãããã¹ãŠã®ã¡ãã»ãŒãžãåŒã³åºããã¡ãã»ãŒãžãéä¿¡ããŸãããã¹ãŠã®å¯Ÿè©±ã¯çŽæ¥è¡ãããŸããViewã®å®è£ ãããããã®ã¡ãœãããåŒã³åºããŠçµæã
ã€ãŸããPresenterã¯Viewã€ãã³ãã«ãµãã¹ã¯ã©ã€ãããå¿ èŠã«å¿ããŠModelã®ããŒã¿ãå€æŽããŸãã
public class SomeScreenPresenter extends Presenter { private SomeScreenView mView; public void setView(SomeScreenView view) { mView = view; } @Override public void initialize() { mView.startLoading(); mView.mapDataItems(...); mView.stopLoading(); } }
ãã®å Žåã®ãã¥ãŒã®äŸã¯ãSomeScreenViewã®åäœã®å®è£ ãæ åœããã¢ã¯ãã£ããã£ã§ãã ãã¥ãŒã®åœ¹å²ã¯ãã¢ã¯ãã£ããã£ã ãã§ãªãããã©ã°ã¡ã³ãããã€ã¢ãã°ããŸãã¯Androidãã¥ãŒã ãã§ãå®è¡ã§ããŸãã ãããè¡ãã«ã¯ãSomeScreenViewã®åäœãå®è£ ããå¿ èŠããããŸãã æå®ãããã¢ã¯ãã£ããã£ã¯ãSomeScreenPresenterã¿ã€ãã®ãªããžã§ã¯ãã䜿çšããŸãããã®ãªããžã§ã¯ãã¯ããã®äŸã§ã¯PresenteãšããŠæ©èœããŸãã Viewãå®è£ ããããã«ãã®ãªããžã§ã¯ããžã®ãªã³ã¯ãæäŸããŸããViewã¯ãå¿ èŠãªã¡ãœãããçŽæ¥åŒã³åºãããšã§Presenterãšå¯Ÿè©±ããŸãã 次ã«ãPresenterã¯ãã¢ã¯ãã£ããã£ã®å éšã§å®è£ ãããã¡ãœãããåŒã³åºããŸããããã¯ããã¥ãŒã®å®è£ ã§ããããã§ãã
@EActivity(R.layout.activity_some_screen) public class SomeScreenActivity extends Activity implements SomeScreenView { private SomeScreenPresenter mPresenter; @ViewById(R.id.drawer_layout) protected ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPresenter = new SomeScreenPresenter(this); mPresenter.initialize(); } }
ãã®åçŽãªäŸã¯ãMVPã䜿çšããŠã以åã¯å®å šã«ã¢ã¯ãã£ããã£ã§ãããããŒã¿ããã³ãŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã®åŠçã«é¢é£ä»ããããŠããããžãã¯ãå解ããæ¹æ³ã瀺ããŠããŸãã ãã®ããžãã¯ãå¥ã®ã¢ãžã¥ãŒã«ã«ç§»ããŸãããããšãã°ãéåžžã®åäœãã¹ãã§ãã®ã¢ãžã¥ãŒã«ã確èªã§ããŸãã ç§ã®èŠ³ç¹ãããããšãããã¯Robotiumã§UIæ©èœããã¹ããããããšãã¥ã¬ãŒã¿ãŒãå®è¡ããããããããã¯ããã«ç°¡åã§ããã³ã³ãããŒã©ãšãã¥ãŒãäœæããã«ãã®èŠçŽ ãå®å šã«ãã¹ãã§ããŸãã ããã«ããã®ã³ãŒãã¯ããã«æ¹åããããšãã§ããŸã-ããšãã°ãäŸåæ§æ³šå ¥ã䜿çšããŸãïŒããšãã°ãRoboGuiceãŸãã¯Daggerã䜿çšããŸãïŒã
MVVM
MVPãã³ãã¬ãŒãã¯æªããããŸããããMicrosoftã¯MVVMïŒModel-View-ViewModelïŒãšããããã«åªãããã³ãã¬ãŒããèæ¡ããŸããã ãã®ãã³ãã¬ãŒãã¯.NETéçºè ã«éåžžã«äººæ°ããããSilverlightã§äœ¿çšããããã®å®è£ ã¯AngularJSã§è¡ãããŸãã MVVMã¯éåžžã«äŸ¿å©ãªãã³ãã¬ãŒãã§ãã
MVVMãšMVPã®éãã¯äœã§ããïŒ
MVVMã䜿çšãããšãViewèŠçŽ ãViewModelããããã£ãšã€ãã³ãã«ãã€ã³ãã§ããŸãã ããã«ãViewModelã¯ãã¥ãŒã®æœè±¡åã§ãã MVVMã«ã¯æ¬¡ã®ãã®ããããŸãã
- 衚瀺-ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã«å¯Ÿå¿ãããã£ãŒã«ããå«ãŸããŸãã
- ViewModel-åããã£ãŒã«ããå«ã¿ãŸããããµããžã§ã¯ãé åã«ãããŸãã
- å®éãã¢ãã«ã
ãã¥ãŒã®ããããã£ã¯ãViewModel / Modelããããã£ãšåãã§ãã ãã ããViewModelã«ã¯ãã¥ãŒã€ã³ã¿ãŒãã§ã€ã¹ãžã®ãªã³ã¯ããããŸããã ViewModelã®ç¶æ ãå€æŽãããšãViewãèªåçã«å€æŽããããã®éãåæ§ã§ãã ãã®ããã«ãããŒã¿ãã€ã³ãã£ã³ã°ã¡ã«ããºã ã䜿çšãããŸãã ãŸããMVVMã®ç¹åŸŽã¯ãViewãšã®åæ¹åéä¿¡ã§ãã

次ã«ãä»äºã§åºäŒã£ãAndroidã®MVVMå®è£ ã«ã€ããŠç°¡åã«èª¬æããããããã®é·æãšçæãæ€èšããŸãã ãã€ãŠãRoboBindingãngAndroidãBindroidã® 3ã€ã®å®è£ ã«æ°ä»ããŸãã ã ãã®ã¬ãã¥ãŒã®æåŸã§ã Android Data Bindingã«ç°¡åã«çŠç¹ãåœãŠãŸããAndroidData Binding㯠ãèªåã§çºèŠãå§ããã°ããã§ãéåžžã«ææã«èŠããŸãã ã¡ãªã¿ã«ã ããã§ããããã¯ã«é¢ããè¯ãè³æã§ãã
ãããã€ã³ãã£ã³ã°
RoboBindingã¯ãAndroidãã©ãããã©ãŒã çšã®MVVMãã¬ãŒã ã¯ãŒã¯ã§ãã ããã«ãããã«ã¹ã¿ã ã³ã³ããŒãã³ãããµãŒãããŒãã£ã³ã³ããŒãã³ãããŸãã¯Androidã®ãŠã£ãžã§ããã®å±æ§ãç°¡åã«ãã€ã³ãã§ããŸãã ãã®çµæãBeanã䜿çšããŠå€ãã®äžèŠãªã³ãŒããã¹ããŒã§ããŸãã
RoboBinding-ã€ã³ã¹ããŒã«
ç§ã®æèŠã§ã¯ãRoboBindingã®ã€ã³ã¹ããŒã«ã¯ç°¡åã§ã¯ãããŸãããåäœãããã«ã¯Android Annotation Processing Toolkitãå¿ èŠã ããã§ãã ããã¯ãRoboBindingãããªã³ã³ãã€ã«æ®µéã§ã®ã³ãŒãçæã«åºã¥ããŠããããã§ãã ãã®å Žåãã³ãŒãã¯ãã¬ãŒã ã¯ãŒã¯ã«å«ãŸããŠããè¿œå ã®æ³šéã«åºã¥ããŠçæãããäœãã§åŠçããå¿ èŠããããŸãã ãããAndroid Annotation Processing Toolkitã®æ©èœã§ãã
æ£çŽãªãšããã2çªç®ããAPTãšRoboBindingã®æéãæ¥ç¶ããŠæ§æã§ããŸããã 倧å€æ°ãããæ©ãæåããããšãé¡ã£ãŠããŸãã
RoboBinding â apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' apt("org.robobinding:codegen:$robobindingVersion") { exclude group: 'com.google.android', module: 'android' } compile("org.robobinding:robobinding:$robobindingVersion") { exclude group: 'com.google.android', module: 'android' } buildscript { dependencies { classpath 'com.android.tools.build:gradle:xxx' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' } }
RoboBinding-ViewModel
ãããããã¥ãŒã¢ãã«ã®å€èŠ³ã§ãã
RoboBinding â ViewModel @PresentationModel public class SomeScreenViewModel implements HasPresentationModelmChangeSupport { private PresentationModelChangeSupport mChangeSupport; private String mUserFirstName; private String mUserLastName; public SomeScreenViewModel() { mChangeSupport = new PresentationModelChangeSupport(this); } public String getUserFirstName() { return mUserFirstName; } public String getUserLastName() { return mUserLastName; } public String getUserFullName() { return mUserFirstName + " " + mUserLastName; } public void setUserFirstName(String userFirstName){ mUserFirstName = userFirstName; } public void setUserLastName(String userLastName){ mUserLastName = userLastName; } public void updateUser() { mChangeSupport.firePropertyChange("userFullName"); } @Override public PresentationModelChangeSupport getPresentationModelmChangeSupport() { return mChangeSupport; } }
ãã®ã¢ãã«ã«ã¯ããã¬ãŒã³ããŒã·ã§ã³ã¢ãã«ããšãã泚éãä»ããŠããŸãããããã¯MVVMãã³ãã¬ãŒãã®æŠå¿µã«ãããViewModelã§ãã ããã¯éåžžã®POJOã¢ãã«ã§ããããã«ã¯ãåŸã§ãã¥ãŒã«è¡šç€ºããããã£ãŒã«ããå«ãŸããŸãïŒä»ã®äŸã§ãããè¡ãæ¹æ³ã瀺ããŸãïŒã ããŒã¿ãåæ¹åã§è¡šç€ºããã«ã¯ãHasPresentationModelmChangeSupportã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããå¿ èŠããããŸããgetPresentationModelmChangeSupportã¡ãœããã§ã¯ãããŒã¿ãå€æŽããChangeSupportå®è£ ãè¿ãå¿ èŠããããŸãã
SomeScreenViewModelã«ã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã§è¡šç€ºããã³åä¿¡ãããå€ãå«ã2ã€ã®ãã£ãŒã«ããšããããã®ãã£ãŒã«ããžã®ã¢ã¯ã»ã¹ãæäŸããã¡ãœãããå«ãŸããŸãã ãŠãŒã¶ãŒãšã®å¯Ÿè©±ãæ åœããã¡ãœããããããŸãã ãããã©ãã ãæ£ç¢ºã«æ©èœããããéäžã§ææ¡ããŸãã
RoboBinding-ã¬ã€ã¢ãŠã
ãã¥ãŒèªäœã§ã¯ãã«ã¹ã¿ã å±æ§ã䜿çšããŠãã¢ãã«ã®ãã£ãŒã«ããç¹å®ã®ã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã«é¢é£ä»ããããšãã§ããŸãã ãããæ©èœãããããã«ãè¿œå ã®ããŒã ã¹ããŒã¹ãæ¥ç¶ãããã®åŸãã«ã¹ã¿ã è¿œå ãã£ãŒã«ããã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã«æå®ããŸãã
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:bind="http://robobinding.org/android" android:orientation="vertical"> <TextView âŠâŠ bind:text="{userFullName}"/> <EditText âŠâŠ bind:text="${userFirstName}"/> <EditText âŠâŠ bind:text="${userLastName}"/> <Button âŠâŠ bind:onClick="updateUser"/> </LinearLayout>
ããŒã¯ã¢ããã«ã¯ã
bind:text="${userLastName}"
ã䜿çš
bind:text="${userLastName}"
EditTextããã
bind:text="${userLastName}"
bind:text="${userLastName}"
SomeScreenViewModelã®ãã©ã€ããŒãString mUserFirstNameãã£ãŒã«ãã«ããã€ã³ããããŸãã ããã§ãmUserFirstNameãã£ãŒã«ããžã®å€æŽã¯æå®ãããEditTextã«è¡šç€ºããããã®EditTextã®ããŒã¿å€æŽã¯mUserFirstNameãã£ãŒã«ãã«è¡šç€ºãããŸãã ãã®ååã«ããã°ãViewãšViewModeléã®åæ¹åããŒã¿ãã€ã³ãã£ã³ã°ã®ã¡ã«ããºã ã¯æ©èœããŸãã
ããã«ããŠãŒã¶ãŒããŒã¿ãåŠçã§ããŸãã
bind:onClick
ããããŸã
bind:onClick
bind:onClick
ã¡ãœããã®ååãå«ã¿ãSomeScreenViewModelã«ã¯ããã¿ã³ãã¯ãªãã¯ããåŸã«åŒã³åºãããåãååã®ã¡ãœããããããŸãã
RoboBinding-ã¢ã¯ãã£ããã£
ããããã¢ãã«ã¯ã©ã®ããã«ããŠãã¥ãŒã®ååšãèªèãããã¥ãŒã¯ã©ã®ããã«ããŠã¢ãã«ã®ååšãèªèããŸããïŒ ããŒã¿ãã€ã³ãã£ã³ã°ããã»ã¹ã¯æ£ç¢ºã«äœãããŸããïŒ RoboBindingã®å Žåãããã¯ãã€ã³ããŒã¯ã©ã¹ã§ãã 圌ã«ã¯ãã¬ã€ã¢ãŠããžã®ãªã³ã¯ãæäŸãããŸãããã®ãªã³ã¯ã§ã¯ãã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã«ã«ã¹ã¿ã ãã£ãŒã«ããå«ãŸããã¢ãã«ã®å®è£ ãžã®ãªã³ã¯ãäžããããŸãã ãã®åŸã ãã€ã³ããŒã¯ã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ãã¢ãã«å ã®ãã£ãŒã«ãã«ãã€ã³ãããŸãã ããã§ãã»ãã¿ãŒ/ã²ãã¿ãŒã䜿çšããããã¢ãã«ã®ããŒã¿ããã£ãŒã«ãã«æžã蟌ãã ãã§ããã¥ãŒã«è¡šç€ºãããŸãã
RoboBinding â Activity public class SomeScreenActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SomeScreenViewModel presentationModel = new SomeScreenViewModel(); View rootView = Binders.inflateAndBindWithoutPreInitializingViews(this, R.layout.activity_some_screen, presentationModel); setContentView(rootView); } }
ãã¹ãŠãéåžžã«ç°¡åã§ãã ãã®å ŽåããŸããfindViewByIdããããŸããã 第äºã«ãããªãã¯ããªããç¹ã«ããåãããããšã«å¯ŸããŠè²¬ä»»ãè² ããŸãã-ããªããå€ãèšå®ããŠããããå€ãååŸã§ããæœè±¡çãªã¢ãã«ãããããŸããã
次ã«ããããã©ã®ããã«æ©èœãããã説æããŸãããã ããšãã°ããŠãŒã¶ãŒããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¿ã³ãã¯ãªãã¯ãããšããŸãã ããã«ããã
bind:onClick="updateUser"
ã䜿çšããŠãã®ãã¿ã³ã«é¢é£ä»ããããã€ãã³ãupdateUserãããªã¬ãŒãããŸãã
bind:onClick="updateUser"
bind:onClick="updateUser"
ïŒRoboBinding-ã¬ã€ã¢ãŠããåç §ïŒã ããã«ããããã®ã¢ã¯ã·ã§ã³ã«é¢é£ä»ããããupdateUserïŒïŒã¡ãœãããSomeScreenViewModelã§åŒã³åºãããŸãïŒRoboBinding-ViewModelãåç §ïŒã ããã¯ããã¥ãŒã«ã¢ãã«ã®ç¶æ ã衚瀺ããããã«å¿ èŠã§ãã
ããã¯ãå€éšãã次ã®ããã«è¡šçŸã§ããŸãã
-ãããã¿ã€ãPresentationModelChangeSupportã®ãªããžã§ã¯ãã¯ããuserFullNameããšãããã£ãŒã«ããååŸããŠæŽæ°ããŸãã -updateUserïŒïŒã¡ãœããã§ã話ããã
-è¯ãã-ãtypeãPresentationModelChangeSupportãªããžã§ã¯ãã¯ãèããã-ãuserFullNameãããã€ã³ãã«
bind:text="{userFullName}"
bind:text="{userFullName}"
ã ãgetUserFullNameãšåŒã°ããã²ãã¿ãŒãæã£ãŠããŸããïŒã ãããŸãã ç§ã¯ãããåŒã³åºããå€ïŒmUserFirstName + "" + mUserLastNameã«çããïŒãååŸãããã®å€ã<TextView ........
bind:text="{userFullName}"/>
bind:text="{userFullName}"/>
ã
ããããRoboBindingã§ã®åæ¹åããŒã¿ãã€ã³ãã£ã³ã°ã®å®è£ ã®ä»çµã¿ã§ãã
RoboBinding-é·æãšçæ
RoboBindingã®å©ç¹ïŒ
- åæ¹åïŒåæ¹åïŒãã€ã³ãã£ã³ã°ã
- ã³ãŒãçæ;
- ãªã¹ãã®ãµããŒãã
çæïŒ
- AppCompatã©ã€ãã©ãªã®åé¡ã
- RecyclerViewã®ãµããŒãã¯ãããŸããã
åæ¹åãã€ã³ãã£ã³ã°ïŒã³ãŒãã®ã$ãèšå·ã¯ãã¢ãã«ã®ããŒã¿ãå€æŽããããšãã¥ãŒã«è¡šç€ºããããã¥ãŒã®ããŒã¿ãå€æŽããããšã¢ãã«ã«æ圱ãããããšãæå³ããŸãã ã$ãèšå·ãååšããªãå Žåãããã¯ã¢ãã«ã®ããŒã¿ããã¥ãŒã«è¡šç€ºãããããšãæå³ããŸããããã®éã¯ãããŸããã
RoboBindingã¯ã³ãŒãçæã«åºã¥ããŠããŸãã ã€ãŸããäºåã³ã³ãã€ã«ã®æ®µéã§-ã¯ã©ã¹ã«ãã€ã³ããã泚éã«åºã¥ããŠãå¿ èŠãªã³ãŒããçæããããã®åŸã³ããŒãããŸãã ã€ãŸããå®è¡æ®µéã§ã¯ãè¿œå ã®ã³ã¹ãã¯å¿ èŠãããŸããã
åçŽãªããŒã¿ããªã³ã¯ããã ãã§ãªãããªã¹ãïŒã³ã¬ã¯ã·ã§ã³ïŒããªã³ã¯ããããšãã§ããŸãã ããã«ãListViewã®æäœããµããŒããããŠããŸããäžéšã®ã³ã¬ã¯ã·ã§ã³ãListViewã«é¢é£ä»ããããšãã§ãããã¹ãŠãæ£åžžã«æ©èœããŸãïŒå°ãªããšãç§ã«ãšã£ãŠã¯æ©èœããŸããïŒã
æ¬ ç¹ã«ã€ããŠã¯ãRoboBindingããªã¹ãã§åäœããRecyclerViewã§åäœããå Žå-ããããå°ãªããšããŸã ã§ãã
ãã€ã³ãã£ã³ã°ã¯ã«ã¹ã¿ã å±æ§ã«åºã¥ããŠãããããäºææ§ã©ã€ãã©ãªã«ãåé¡ããããŸãã ããã¯ãäºææ§ã©ã€ãã©ãªããã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ããããã«ã¹ã¿ã å±æ§ãè¿œå ããããšããŠããå Žåãããã¯åžžã«æ©èœãããšã¯éããŸããããæ©èœããå Žåã¯éåžžã«æªãããšã§ãã RoboBindingãµã€ãã§ã¯ããããã®ãã¹ãŠã®ãã°ãæ¢ã«ææãããŠããŸãã確ãã«ãRoboBindingã¯éçºäžã§ãããéåžžã«è¿ éã«éçºãããŠããããããã°ã®ä¿®æ£äœæ¥ã¯ãã§ã«é²è¡äžã§ãã
ngAndroid
ç§ãæ°ã«å ¥ã£ã次ã®ã©ã€ãã©ãªã¯ãAngularJS JavaScriptãã¬ãŒã ã¯ãŒã¯ã®ã¢ã€ãã¢ã«åºã¥ããngAndroidã§ãïŒãã ããã¢ã€ãã¢ã®ã¿ã§ã-ããã«ã¯JavaScriptã¯ãããŸããïŒã RoboBindingãšéåžžã«ãã䌌ãŠããŸãã
ngAndroid-ã€ã³ã¹ããŒã«
RoboBindingãšã¯ç°ãªããngAndroidã¯éåžžã«ç°¡åã«ã€ã³ã¹ããŒã«ã§ãããã¹ãŠãåããŠåäœã
compile 'com.github.davityle:ngandroid:0.0.4'.
ïŒ
compile 'com.github.davityle:ngandroid:0.0.4'.
compile 'com.github.davityle:ngandroid:0.0.4'.
ngAndroid-ã¢ãã«
ngAndroid - Model public class Model { private String mUserFirstName; private String mUserLastName; private String mUserFullName; public String getUserFirstName() { return mUserFirstName; } public String getUserLastName() { return mUserLastName; } public String getUserFullName() { return mUserFullName; } public void setUserFirstName(String userFirstName){ mUserFirstName = userFirstName; } public void setUserLastName(String userLastname){ mUserLastName = userLastname; } public void setUserFullName(String userFullName) { mUserFullName = userFullName; } }
ã¢ãã«ã¯å®éã«éãã¯ãããŸãã-ãããã¯éåžžã®ããŒã¿ã§ãããããŒã¿ã«ã¢ã¯ã»ã¹ããæ¹æ³ã§ãã ã¢ã¯ã·ã§ã³ã¯ãããŸãã-ãµããŒããããŠããŸããããã®åœ¢åŒã§ã¯ãµããŒããããŠããŸããã
ngAndroid-ã¬ã€ã¢ãŠã
ã¬ã€ã¢ãŠãã¯åãã§ã-éãã¯æå°éã§ãã åæ§ã«ãäœæ¥ã¯ã«ã¹ã¿ã å±æ§ã«åºã¥ããŠããŸããå¿ èŠãªããŒã ã¹ããŒã¹ãæ¥ç¶ãããã®ã¢ãã«å ã®å±æ§åã䜿çšããŠã¢ãã«ã衚瀺ããŸããã
ngAndroid â Layout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:ng="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <TextView âŠâŠ ng:ngModel="model.userFullName" <EditText âŠâŠ ng:ngModel="model.userFirstName"/> <EditText âŠâŠ ng:ngModel="model.userLastName"/> <Button âŠâŠ ng:ngClick="updateUser()"/> </LinearLayout>
ngAndroid-ã¢ã¯ãã£ããã£
éãã¯ã¢ã¯ãã£ããã£ããå§ãŸããŸãã ç¹å®ã®ã¢ã¯ãã£ããã£ïŒãã©ã°ã¡ã³ãããã¥ãŒãªã©ãããå ŽåããããŸãïŒãããäŸãèããŠã¿ãŸãããã ãŸãããã®ã¢ã¯ãã£ããã£ã§ã¯ã@ NgScopeã¢ãããŒã·ã§ã³ã䜿çšããŠãngAndroidããã®ãã¥ãŒã«ãã€ã³ããŒãå«ããå¿ èŠãããããšãèªèããŠããŸãã @ NgModelã¢ãããŒã·ã§ã³ã䜿çšããŠãã¢ã¯ãã£ããã£ã®äŸïŒSomeScreenViewModelïŒã®ViewModelãåã蟌ã¿ãŸãã å®éãããã¯ãã¹ãŠã§ããViewã瀺ããViewModelã瀺ããŸãã RoboBindingãšã¯ç°ãªããäœæ¥ã®ãã®æ®µéã§ã¯ãngAndroidå ã§ã€ã³ãžã§ã¯ã¿ãŒããªã³ã«ãªããæå®ãããäŸåé¢ä¿ã®å¿ èŠãªå®è£ ãå®è¡ããŠæ§æããŸãã
ãã®ããã«ããŠãåæ¹åãã€ã³ãã£ã³ã°ãå®çŸãããŸãã åæã«ãã¢ã¯ãã£ããã£èªäœãã€ãã³ãã®åŠçãæ åœããã¯ã©ã¹ãšããŠæ©èœããŸãã Activityã§ã¯ãupdateUserïŒïŒã¡ãœãããå®è£ ãããŸãããã®ã¡ãœããã¯ã以åã¯ãã¿ã³ã«ããŒã¯ã¢ããããããã¡ã€ã«ã«ãã€ã³ããããŠããŸããã ãã®äŸã¯ãRoboBindingãšã¯ç°ãªããngAndroidã®updateUserïŒïŒãViewModelã§ã¯ãªãActivityã«ããããšã瀺ããŠããŸãã
@NgScope public class SomeScreenActivity extends Activity { @NgModel SomeScreenViewModel mScreenViewModel; private final NgAndroid mNg = NgAndroid.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNg.setContentView(this, R.layout.activity_some_screen); } protected void updateUser(){ String firstName = mScreenViewModel.getUserFirstName(); String lastName = mScreenViewModel.getUserLastName(); mScreenViewModel.setUserFullName(firstName + " " + lastName); } }
ngAndroid-é·æãšçæ
å©ç¹ïŒ
- åæ¹åãã€ã³ãã£ã³ã°;
- ãããžã§ã¯ãã¯æŽ»çºã«éçºäžã§ãã
çæïŒ
- ãªã¹ã/ RecyclerViewã®ãµããŒããªã;
- ãªãã¬ã¯ã·ã§ã³ã䜿çšãããŸãïŒã³ãŒãçæã«åãæ¿ããããšãçŽæããŸãïŒã
- ãããžã§ã¯ãã¯æŽ»çºã«éçºäžã§ãããããéåžžã«ç²éã§ãã
NgAndroidã¯çŸåšæ¥éã«éçºãããŠããŸããã¢ãã«ãšã¯ãªãã¯ã«å ããŠãã©ã€ãã©ãªã¯ãã³ã°ã¯ãªãã¯ãå€æŽãç¡å¹åãªã©ããµããŒãããŠããŸãããµããŒããããŠãããã£ã¬ã¯ãã£ãã¯ãŸããŸãå¢ããŠããŸãã åæã«ããã®ãããªæ¥éãªéçºã¯æ¬ ç¹ãšã¿ãªãããšãã§ããŸã-ç§ã¯è·å Žã§ngAndroidã䜿çšããŠããéã¯æ³šæããŸãã
çŸåšã次ã®è§åºŠãã£ã¬ã¯ãã£ãããµããŒããããŠããŸãã
- ngmode
- NGClick
- NgLongClick
- Ngchange
- Ngdisabled
- NgInvisible
- ããŽã³
- Ngblur
- Ngfocus
å šäœçã«ãç§ã¯ã©ã€ãã©ãªããšãŠã奜ãã§ãã-éææ§ãã·ã³ãã«ããäŸåæ§æ³šå ¥ããããšããäºå®ïŒã³ãŒããå°ãªããŠè¯ãïŒãåæ¹åïŒåæ¹åïŒãã€ã³ãã£ã³ã°ãããããã§ãã
ãã€ã³ããã€ã
Bindroidã¯ãAndroidã¢ããªã±ãŒã·ã§ã³çšã®MVVMãã¿ãŒã³ã®å¥ã®å®è£ ã§ãã Bindroidã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãšããŒã¿ã®ãã€ã³ããç°¡çŽ åããããšãäž»ãªç®çãšãããªãŒãã³ãœãŒã¹ã©ã€ãã©ãªã§ãã ã¢ãã«ãæäœããããã®Observerãã³ãã¬ãŒããšããããã®ãªããžã§ã¯ããšãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããã°ãããªã³ã¯ããããã®äžé£ã®ã¡ãœããã«åºã¥ããŠããŸãã
ãã€ã³ããã€ã-ã¢ãã«
Bindroidã¯ãUIå±æ§ã®ã«ã¹ã¿ã ãã£ãŒã«ãããªããšããç¹ã§ããã§ã«æ€èšãããŠããå®è£ ãšæ ¹æ¬çã«ç°ãªããŸããã€ãŸãããã¥ãŒãã¢ãã«ã®ãã£ãŒã«ãã«é¢é£ä»ããèŠçŽ ããããŸããã 代ããã«ãã¢ãã«å ã«TrackableFieldãã£ãŒã«ãããããŸã-ãã¹ãŠã®ããŒã¿ãã£ãŒã«ãã¯TrackableFieldã§ãªããã°ãªããŸããã ããã¯ããã£ãŒã«ããå€æŽãããšããã¥ãŒã§å€æŽãããããã«è¡ãããŸãã ãããã£ãŠãObserverãã³ãã¬ãŒãã¯ããã«å®è£ ãããããŒã¿ã®å€æŽãUIã«è¡šç€ºãããããã«ããŸãã
Bindroid â Model public class SomeScreenViewModel { private TrackableField<String> mUserFirstName = new TrackableField<String>(); private TrackableField<String> mUserLastName = new TrackableField<String>(); private TrackableField<String> mUserFullName = new TrackableField<String>("Here could be your advertising."); public String getUserFirstName() { return mUserFirstName.get(); } public void setUserFirstName(String firstName) { mUserFirstName.set(firstName);} public String getUserLastName() { return mUserLastName.get(); } public void setUserLastName(String lastName) { mUserLastName.set(lastName); } public String getUserFullName() { return mUserFullName.get(); } public void setUserFullName(String fullName) { mUserFullName.set(fullName); } }
Bindroid-ã¬ã€ã¢ãŠã
Bindroid - Layout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical"> <TextView âŠâŠ android:id="@+id/text_user_fullname" <EditText âŠâŠ android:id="@+id/edit_user_firstname"/> <EditText âŠâŠ android:id="@+id/edit_user_lastname"/> <Button âŠâŠ android:onClick="updateUser"/> </LinearLayout>
æ®å¿µãªããããã€ã³ãããã«ã¯ãfindViewByIdã䜿çšããŠãã¢ãã«å ã®åãã£ãŒã«ãããã¥ãŒå ã®ç¹å®ã®å®è£ ã«æåã§ãã€ã³ãããå¿ èŠããããŸãã findViewByIdã¯ãButterKnifeãŸãã¯Android Annotationsã䜿çšããŠåé€ã§ããŸããã
Bindroid-ã¢ã¯ãã£ããã£
Bindroid â Activity public class SomeScreenActivity extends Activity { SomeScreenViewModel mScreenViewModel = new SomeScreenViewModel(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_some_screen); UiBinder.bind(new EditTextTextProperty(this.findViewById( R.id.edit_user_firstname)), mScreenViewModel, "userFirstName", BindingMode.TWO_WAY); UiBinder.bind(new EditTextTextProperty(this.findViewById( R.id.edit_user_lastname)), mScreenViewModel, "userLastName", BindingMode.TWO_WAY); UiBinder.bind(new TextViewTextProperty(this.findViewById(R.id.text_user_fullname)), mScreenViewModel, "userFullName", BindingMode.TWO_WAY); } public void updateUser(View v){ String firstName = mScreenViewModel.getUserFirstName(); String lastName = mScreenViewModel.getUserLastName(); mScreenViewModel.setUserFullName(firstName + " " + lastName); } }
Bindroid-é·æãšçæ
å©ç¹ïŒ
- åæ¹åãã€ã³ãã£ã³ã°;
- AppCompatã©ã€ãã©ãªã§ã®äœæ¥ããµããŒãããŸãã
çæïŒ
- ã³ãŒãçæã®ãµããŒããªã;
- ã³ã³ãã€ã«æã«ãã§ãã¯ã€ã³ããŸããã
- ãªã³ã¯ããã«ã¯ã³ãŒããå€ãããŸãã
Bindroidã¯ãã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã®ã«ã¹ã¿ã ãã£ãŒã«ããäŸåé¢ä¿ã®æ¿å ¥ãæ°ã«å ¥ããªãå Žåããè¿œå ã®ãªãœãŒã¹ãæ¶è²»ããAndroid Annotation Processing Toolkitãªã©ã®äžèŠãªããŒã«ãåãæ¿ããã®ãå«ãªå Žåã«ãèå³æ·±ãæãããããããŸããã ãŸãã¯ãã³ã³ãã€ã«ããŠãã°ããåäœãããããã«ãã¹ãŠãå¿ èŠãªå ŽåããããŸãã ãã®åŸãBindroidãé©ããŠããŸãããã³ãŒããããå°ãé·ãæžãå¿ èŠããããŸãã
ç§ã®æèŠã§ã¯ãæ倧ã®æ¬ ç¹ã¯ã³ã³ãã€ã«æ®µéã§ã®æ€èšŒã®æ¬ åŠã§ãã ããšãã°ãã¢ãã«ã§ãã£ãŒã«ãã®ååãuserLastNameã§ãã¢ã¯ãã£ããã£ã§ãã¹ãããå Žåããã¹ãŠãã³ã³ãã€ã«ãããŸãããå®è¡äžã«äŸå€ãçºçããŸãã ãŸãããã€ã³ãã£ã³ã°ãè¡ããšãã«ã¹ã¿ãã¯ãã¬ãŒã¹ãéåžžã«æ¥œããã®ã§ãäœãééã£ãŠããã®ããéåžžã«é·ãéæ¢ããŸãã ããã¯é倧ãªæ¬ é¥ã§ãã
AndroidããŒã¿ãã€ã³ãã£ã³ã°
2015幎ã®æ¥ãGoogleã¯Google I / Oã«Android Data Bindingã©ã€ãã©ãªãå°å ¥ããŸãããããã¯ãããŸã§ã®ãšããããŒã¿çã§å©çšå¯èœã§ãã 圌女ã«ã¯å€ãã®å¯èœæ§ããããŸãããèšäºã§ã¯MVVMã«é¢é£ãã圌女ã®æ©äŒã«ã€ããŠã話ããŸãã
AndroidããŒã¿ãã€ã³ãã£ã³ã°-ã€ã³ã¹ããŒã«
ã€ã³ã¹ããŒã«ã¯éåžžã«ç°¡åã§ãã Android Data Bindingã¯ããŒã¿ãã¹ãäžã®ãããAndroid Studioã¯ïŒ2015幎7æãAndroid Studio v 1.3.0ïŒã§éåžžã®æäœããŸã ãµããŒãããŠããŸããã
Android Data Binding â apply plugin: 'com.android.databinding' dependencies { classpath 'com.android.tools.build:gradle:1.3.0-beta2' classpath 'com.android.databinding:dataBinder:1.0-rc0' }
AndroidããŒã¿ãã€ã³ãã£ã³ã°-ã¢ãã«
ã¢ãã«ã«ã¯ç°åžžãªãã®ã¯ãããŸãããåããã£ãŒã«ããããããããã®ãã£ãŒã«ãã«ã¢ã¯ã»ã¹ããæ¹æ³ããããŸãã
Android Data Binding â Model public class User { private String mFirstName; private String mLastName; private String mFullName; public User(String firstName, String lastName) { mFirstName = firstName; mLastName = lastName; } public String getFirstName() { return mUserFirstName; } public String getLastName() { return mLastName; } public String getFullName() { return mFullName; } public void setFirstName(String userFirstName) { mUserFirstName = userFirstName; } public void setLastName(String userLastname){ mUserLastName = userLastname; } public void setFullName(String userFullName) { mUserFullName = userFullName; } public void updateUser(View v){ mFullName = mFirstName + " " + mLastName; } }
AndroidããŒã¿ãã€ã³ãã£ã³ã°-ã¬ã€ã¢ãŠã
ãã¥ãŒã®ããŒã¯ã¢ãããã¡ã€ã«ã«ã€ããŠã¯ã以åã«æ€èšãããå®è£ ãšã¯ãã§ã«é倧ãªéãããããŸãããŸããã«ãŒãããŒããããããã¬ã€ã¢ãŠãããããŸããããŒã¿ã»ã¯ã·ã§ã³ã¯ãã¢ãã«ãšãã®åŒã³åºãæ¹æ³ïŒåå空éïŒã瀺ããŸãããããŠãUIããã®ããŒã¿ã¯ãæå®ãããã¢ãã«ã®ãã£ãŒã«ãã«ããããããŸãïŒãã®å Žåããããã¯ããããã¢ãã«å ã®åããã£ãŒã«ãã§ãïŒãã€ãŸãã以åãšåæ§ã«ãã£ãŒã«ãããããã¢ãã«ããããã€ã³ã¿ãŒãã§ã€ã¹ã®UIèŠçŽ ãžã®åå²ã®ãã£ãŒã«ãã衚瀺ã§ãããªã³ã¯ã¡ã«ããºã ããããŸããéãã¯ãã«ãŒãããŒããã¬ã€ã¢ãŠãã§ãããã¬ã€ã¢ãŠãèªäœã®ä»ã«ã䜿çšããŠããã¢ãã«ã瀺ãå¿ èŠãããããŒã¿ãå«ãã»ã¯ã·ã§ã³ãããããšã§ãã次ã®äŸã§ã¯ããã詳现ãªäœ¿çšãæ€èšã§ããŸãã
user.fullName, user.firstName user.lastName
Android Data Binding â Layout <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout âŠâŠ> <TextView âŠâŠ android:text="{user.fullName}"/> <EditText âŠâŠ android:text="@{user.firstName}"/> <EditText âŠâŠ android:text="@{user.lastName}"/> <Button âŠâŠ android:onClick="updateUser"/> </LinearLayout> </layout>
AndroidããŒã¿ãã€ã³ãã£ã³ã°-ã¢ã¯ãã£ããã£
ã¢ã¯ãã£ããã£ã«ã¯æå°éã®å€æŽããããŸããããŒã¿ã¢ãã«ããªã³ã¯ããããã¥ãŒãããŒã¿ã¢ãã«ãäœæããŸãããã®åŸãã¢ãã«å ã®äžéšã®å€ãå€æŽããããã»ã¹ã§ããã®ããŒã¿ã¯ãã¥ãŒå ã§å€æŽãããŸããããŒã¿ã衚瀺ã«å€æŽãããå Žåãå€æŽã¯ã¢ãã«ã§å©çšå¯èœã«ãªããŸããããŒã¿ãšUIã§ã®è¡šç€ºå Žæã®éã®åæ¹åãã€ã³ãã£ã³ã°ã«ã¯ãã@ãèšå·ã䜿çšãããŸãïŒããšãã°ã
android:text="@{user.lastName}"
ïŒãã以å€ã®å Žåããã€ã³ãã£ã³ã°ã®å®è£ ã¯äžæ¹åã§ãã
ãããã£ãŠãç§ã®èŠ³ç¹ããèŠããšãããŒã¿ãã€ã³ãã£ã³ã°ã®äœ¿çšã¯éåžžã«ã·ã³ãã«ãã€ééçã«èŠããMVVMãã³ãã¬ãŒãã®å®è£ ã§ãã
Android Data Binding â Activity public class SomeScreenActivity extends Activity { private User mUser = new User("Anton", "Valiuh"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); binding.setUser(mUser); } }
AndroidããŒã¿ãã€ã³ãã£ã³ã°-æ©èœ
ããŒã¿ãã€ã³ãã£ã³ã°ã«ã¯MVVMãã¿ãŒã³ãå®è£ ããæ©èœããããšããäºå®ã«å ããŠããã®ãã¯ãããžã«ã¯ããã«å€ãã®åªããæ©èœããããŸãïŒå®éãAndroidããŒã¿ãã€ã³ãã£ã³ã°ã¯å¥ã®ã¬ããŒããŸãã¯èšäºã®ãããã¯ã§ãïŒã
è¡šçŸã®èšèªããã¥ãŒå ã«ããªããã£ãããžãã¯ãèšè¿°ã§ããŸããäž»ãªããšã¯ãããžãã¯ããã¥ãŒã«å ¥ããªãããã«ç¡çãããªãããšã§ããããã§ããåŒã®èšèªã䜿çšãããšåçŽåã§ããŸããç¶æ ã«å¿ããŠãããŸããŸãªãã³ãã©ãŒãéžæãããã©ãŒããããå®è¡ã§ããŸãããšãŠã䟿å©ã§ãã
android:text="@{String.format("Hello %s",viewModel.field )}" android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}â
èŒžå ¥ãããã«ãä»»æã®ã¯ã©ã¹ãã€ã³ããŒãã§ããŸããããšãã°ãViewãã€ã³ããŒãããåŸãäžéšã®åŒã§ãã®ã¯ã©ã¹ã®ããããã£ã䜿çšã§ããŸãã
ãªãœãŒã¹ãµããŒãã圌ãã¯è¡šçŸãæžããã©ã®ãªãœãŒã¹ãåãã¹ããã瀺ãããã¹ãŠãããŸãæ©èœããŸãã
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}â
ã³ã¬ã¯ã·ã§ã³ã®ãµããŒãã
android:text="@{list[index]}" android:text="@{map[`firstName`}â
ã«ã¹ã¿ã Beanãäœæã§ããŸãã
ããªãã¯é·ãéãªã¹ãããããšãã§ããŸã-ãã£ãšãããŸãã
確ãã«ãé ããæ©ãããAndroid Data Bindingã¯AndroidããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ãäœæããããã®æ°ããæšæºã«ãªããŸã-ããã¯ã»ãŒ100ã®ããšã§ãããã
AndroidããŒã¿ãã€ã³ãã£ã³ã°-é·æãšçæ
å©ç¹ïŒ
- Googleã®å ¬åŒã©ã€ãã©ãªã
- ã³ãŒãçæ;
- ã³ã³ãã€ã«æã«ç¢ºèªããŸãã
- 䜿ãããããšæ¡åŒµæ§ã
- æ°ããAndroidæšæºã
çæïŒ
- åæ¹åãã€ã³ãã£ã³ã°ã¯ãµããŒããããŠããŸããïŒãŸã ïŒã
- IDEã®ãµããŒããªãïŒãŸã ïŒã
- Android Studioã®å€ãã®èª€ã£ããšã©ãŒïŒãã ãããã¹ãŠãã³ã³ãã€ã«ãããŠèµ·åããŸãïŒã
éèŠãªæ¬ ç¹-å®å šãªåæ¹åãã€ã³ãã£ã³ã°ã®æ¬ åŠ-ããã¯ãããŸãããä»ã®ãšããããŸãæ©èœããŠããŸãããããŠãããŒã¿çããäœãåŸãã¹ãã...確ãã«ãããã¯è¿ãå°æ¥å®å šã«æ©èœããæåã®ãã®ã§ãã
IDEã®ãµããŒãã¯ãããŸãã-çµæãšããŠãAndroid Studioã«ã¯å€ãã®ãšã©ãŒããããŸãããããããã¹ãŠãã³ã³ãã€ã«ããããã¹ãŠãå§ãŸãããã¹ãŠãæ©èœããŸãã誰ããèå³ãæã£ãŠæ¥ç¶ãããå Žåã¯ãåŸæããªããšæããŸãã