Android・iOS アプリ作成入門 Android 編

9b6ca173883528d3bd047ca8f20b0bce?s=47 nonylene
March 13, 2016

Android・iOS アプリ作成入門 Android 編

KMC 春合宿 2016 没スライド // iOS -> https://speakerdeck.com/nonylene/ios-apurizuo-cheng-ru-men

9b6ca173883528d3bd047ca8f20b0bce?s=128

nonylene

March 13, 2016
Tweet

Transcript

  1. "OESPJEɾJ04 ΞϓϦ࡞੒ೖ໳ ,.$OPOZMFOF

  2. ͜ͷεϥΠυʹ͍ͭͯ w य़߹॓ͷ຅εϥΠυ w य़߹॓Ͱ͸J04ฤͷΈΛൃදʢͪ͜Βʣ w ͜͜ʹ͸"OESPJEฤΛऩ࿥ w J04ฤͱҰ෦ॏෳ͍ͯ͠·͢

  3. ࣗݾ঺հ w OPOZMFOF ͷʹΕΜ  w ,.$ೋճੜSPPU w (JU)VCIBUFOBFUDʜ w

    QZUIPO KBWB "OESPJE 
 ,PUMJOFUDʜ
  4. ࿩͢͜ͱ

  5. "OESPJEͱJ04ͷجຊ

  6. "OESPJEͱJ04
 Ͱ ಉػೳͷΞϓϦΛ࡞੒

  7. ࡞੒͢ΔΞϓϦ w 4UBDL0WFSqPX"1* w ΈΜͳେ޷͖ɺϓϩάϥϛϯάͷ2"αΠτ w QVCMJD"1*Ͱݕࡧ΍ৄࡉ͕औΕΔ

  8. 4UBDL0WFSqPX"1* w υΩϡϝϯτ w IUUQTBQJTUBDLFYDIBOHFDPNEPDT w TFBSDI"1* ྫλΠτϧʹBOESPJE  w

    IUUQTBQJTUBDLFYDIBOHFDPNTFBSDI PSEFSEFTDTPSUBDUJWJUZJOUJUMFBOESPJET JUFTUBDLPWFSqPXpMUFS GQO[U%1
  9. None
  10. 4UBDLFS

  11. "OESPJE

  12. ໨࣍ w "OESPJEͱ͸ʁ w ηοτΞοϓ w )FMMP8PSMEΛோΊΔ w ΞϓϦ࡞੒

  13. "OESPJEͱ͸ w (PPHMFͷ04 w -JOVYΧʔωϧΛ࢖༻ w ༷ʑͳϝʔΧʔ w ೔ຊʹ͓͚ΔγΣΞ͸ w

    ࠷৽͸ NBSTINBMMPX
  14. ։ൃ؀ڥ w +BWB w ਖ਼֬ʹ͸"OESPJE+BWB
 ͱݴΘΕɺڍಈ͕ҧͬͨΓ͢Δ w ਖ਼نදݱFUD w "OESPJE/͔Β͸0QFO+%,KBWB

  15. ։ൃ؀ڥ w "OESPJE4UVEJP w *OUFMMJ+ϕʔε w 8JOEPXTNBD-JOVY w ແྉ

  16. ηοτΞοϓ

  17. ໊শઃఆ w ࠓճ͸4UBDLFS w OFUOPOZMFOFTUBDLFS w ͜Ε͕ΞϓϦͷ*%ʹ

  18. 04όʔδϣϯ w ݹ͍όʔδϣϯ͕ଟ͘ଘࡏ w ࠷৽ͷ"1*͕࢖͑ͳ͍౳ w Ҏ্ఔ౓͕Φεεϝ

  19. "DUJWJUZ࡞੒ w &NQUZ"DUJWJUZΛબ୒
 ʢ#BTJD͸ͪΐͬͱ"EWBODFE͗͢Δʣ

  20. )FMMP8PSME w ୺຤Λ઀ଓɺ্ʹ͋Δl⾣z Λԡͯ͠ΞϓϦΛىಈ w ΤϛϡϨʔλͰ΋Մ

  21. )FMMP8PSMEΛோΊΔ

  22. .BJO"DUJWJUZKBWB public class MainActivity extends AppCompatActivity { @Override protected void

    onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } ˣޙͰઆ໌ ˢϨΠΞ΢τΛදࣔ w ը໘੍ޚ
  23. BDUJWJUZ@NBJOYNMʢൈਮʣ <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!"/> </RelativeLayout>

    w ϨΠΞ΢τ
  24. CVJMEHSBEF ൈਮ android { defaultConfig { applicationId "net.nonylene.stacker" minSdkVersion 19

    targetSdkVersion 23 versionCode 1 versionName "1.0" } } dependencies { compile 'com.android.support:appcompat-v7:23.2.0' } ˡόʔδϣϯ৘ใͳͲ ˢ֎෦ϥΠϒϥϦ 4VQQPSU-JCSBSZ w Ϗϧυઃఆ౳ HSPPWZ
  25. "OESPJE.BOJGFTUYNMʢൈਮʣ w ΞϓϦͷ৘ใ͕ॻ͔ΕͨϑΝΠϧ <manifest package=“net.nonylene.stacker"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme=“@style/AppTheme">

    <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name
 ="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest> ˡΞϓϦ໊ɺΞΠίϯ౳ ˢ"DUJWJUZͷ৘ใ
  26. ΞϓϦ࡞੒

  27. ϑϩʔΛߟ͑Δ ᶃݕࡧϫʔυΛೖྗͤ͞Δ ᶅ"1*Λୟ͍ͯ݁ՌΛऔಘ ᶅ+40/Λॲཧ ᶆॲཧͨ݁͠ՌΛදࣔ͢Δ

  28. ᶃݕࡧϫʔυΛೖྗ

  29. ϨΠΞ΢τ࡞੒

  30. ը໘Λ૊ΈཱͯΔ w ը໘ύʔπͷ͜ͱΛViewͱ͍͏ w "OESPJEͰ͸ը໘ύʔπ͸YNMͰද͞ΕΔ w ೖྗཝͱϦετදࣔͷύʔπΛ্Լʹฒ΂Δ

  31. BDUJWJUZNBJOYNMʢൈਮʣ <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Please

    input search” android:lines=“1”/> <Button ~~~ android:text=“Search!”/> <android.support.v7.widget.RecyclerView ~~~ android:scrollbars=“vertical"/> </LinearLayout> ɾ-JOFBS-BZPVU &EJU5FYU #VUUPO 3FDZDMFS7JFX
  32. -JOFBS-BZPVU w ෳ਺ͷViewΛ্ԼPSࠨӈʹฒ΂Δ໾ׂΛ࣋ͭ • layout_width=“match_parent”
 layout_height=“match_parent”
 
 ɹɹॎԣ͍ͬͺ͍ʹ޿͛Δ • orientation="vertical"


    
 ɹɹॎ޲͖ʹฒ΂Δ
  33. &EJU5FYU w จࣈೖྗ༻ͷView • id="@+id/edit_text"
 
 ɹɹϓϩάϥϜ͔Βࢀর͢ΔͨΊͷ*% • hint=“Please input

    search"
 
 ɹɹ༧Ίදࣔ͢Δώϯτ • lines="1"
 
 ɹɹҰߦදࣔ
  34. &EJU5FYU • layout_width=“match_parent”
 layout_height=“wrap_content”
 
 ɹɹԣ෯͸͍ͬͺ͍ʹ޿͛Δ
 ɹɹॎ෯͸σϑΥϧτͷߴ͞ʹ͢Δ • ࣗ෼Ͱߴ͞Λઃఆ͢Δ৔߹͸ dp

    Λ࢖͏ • 1dp ͸୺຤ʹΑͬͯ 2px ͩͬͨΓ 3px ͩͬͨΓ
  35. #VUUPO w Ϙλϯͷ7JFX • text=“Search!"
 
 ɹɹϘλϯʹදࣔ͢ΔςΩετ

  36. w 4VQQPSU-JCSBSZʹೖ͍ͬͯΔ w 4VQQPSU-JCSBSZͱ͸ɾɾɾʁ 3FDZDMFS7JFX

  37. w ৽͍͠04ͷػೳͷҰ෦Λݹ͍04Ͱ΋࢖͑ΔΑ͏ʹ ͢ΔɺHPPHMFͷެࣜϥΠϒϥϦ w ྫ.BUFSJBM%FTJHO 'SBHNFOU FUD w ઌ΄ͲͷAppCompatActivity΋ͦͷҰͭ w

    ࠷৽ͷσβΠϯͷҰ෦΍ػೳ͕ఏڙ͞ΕΔ 4VQQPSU-JCSBSZ
  38. w ଞʹ΋04ʹ͸ೖͬͯͳ͍ศརػೳΛఏڙ w ྫ3FDZDMFS7JFX 1BMFUUF 4VQQPSU-JCSBSZ

  39. w ಉ͡ViewΛ܁Γฦ͠Ϧετදࣔ͢ΔView w ৄ͘͠͸ޙͰઆ໌ 3FDZDMFS7JFX

  40. w ϥΠϒϥϦͱͯ͠഑෍͞Ε͍ͯΔͷͰಋೖ w CVJMEHSBEMF 3FDZDMFS7JFX dependencies { compile ‘com.android.support:appcompat-v7:23.2.0’ compile

    ‘com.android.support:recyclerview-v7:23.2.0' }
  41. 3FDZDMFS7JFX w BDUJWJUZ@NBJOYNM <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars=“vertical"/>

  42. ࣮ػͰ֬ೝ w Ϧετ෦෼͸ۭന w ԿΛදࣔͤ͞Δ͔Λ·ܾͩ Ί͍ͯͳ͍

  43. ΫϦοΫˠจࣈྻऔಘ

  44. ϑϩʔ w Ϣʔβʔ͕ϘλϯΛԡ͢
 ˠEditText͔ΒݕࡧΩʔϫʔυΛऔಘ w ͦΕʹԠͯ͡(&53FRVFTUΛඈ͹͢ ᶄ

  45. 7JFXΛ"DUJWJUZ಺Ͱೝࣝ • View View#findViewById(int id) • YNMͰࢦఆͨ͠*%ͷ View Λऔಘ͢Δ •

    ྫ: id=“@+id/view_id” ͱࢦఆ
 → View view =
 findViewById(R.layout.view_id); • R.layout.~~ ͸YNMͰ*%Λࢦఆ͢Δͱ
 ࣗಈతʹ࡞ΒΕΔɺ*%ͷू߹Ϋϥε
  46. Ωʔϫʔυऔಘ • ಘΒΕͨ View Λ EditText ʹΩϟετ
 → EditText ͱͯ͠ϓϩάϥϜͰѻ͑Δ

    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText editText = (EditText) findViewById(R.id.edit_text); Button button = (Button) findViewById(R.id.button); } }
  47. ϘλϯͷΫϦοΫ • View View#setOnClickListener
 (OnClickListener listener) • Click ͞Εͨ࣌ͷϦεφʔΛઃఆ •

    ΫϦοΫ͞ΕΔ
 → Ϧεφʔʹ͋Δࢦఆͷؔ਺͕ݺ͹ΕΔ • java7 ʹϥϜμࣜ͸ແ͍
 → ແ໊ΦϒδΣΫτΛ࡞੒͢Δ
  48. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText

    editText = (EditText)
 findViewById(R.id.edit_text); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String searchText = 
 editText.getText().toString(); } }); } • ΫϦοΫ͞ΕͨΒ OnClick ͕ݺ͹Εɺ
 ɹEditText ͔ΒΩʔϫʔυऔಘ͢Δ
  49. ᶄ"1*Ͱ+40/औಘ

  50. ωοτϫʔΫ w ωοτϫʔΫΛඈ͹͢ʹ͸ݖݶ͕͍Δ w ΞϓϦͷݖݶ͸Πϯετʔϧ࣌ʹ֬ೝ͞ΕΔ w "OESPJE͔Β͸Ұ෦ͷݖݶ͕ڐՄ੍ʹ w "OESPJE.BOJGFTUYNMʹهड़

  51. ωοτϫʔΫݖݶͷ௥Ճ w "OESPJE.BOJGFTUYNM <manifest package="net.nonylene.stacker"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission ɹ
 ɹɹɹɹɹandroid:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application android:label="@string/app_name"> <activity android:name=".MainActivity"> </activity> </application> </manifest>
  52. ωοτϫʔΫ w "OESPJEͷσϑΥϧτͰ͸%FGBVMU)UUQ$MJFOU ͱ"TZOD5BTL -PBEFS Λ࢖͏ w গ͠೉͍͠ͷͰࠓճ͸0L)UUQΛ࢖͏ w 4RVBSFࣾͷKBWB޲͚௨৴ϥΠϒϥϦ

    w "OESPJE಺෦Ͱ΋࢖ΘΕ͍ͯΔ
  53. 0L)UUQ w build.gradleʹ௥Ճ dependencies { compile 'com.android.support:appcompat-v7:23.2.0' compile ‘com.android.support:recyclerview-v7:23.2.0' compile

    'com.squareup.okhttp3:okhttp:3.2.0' }
  54. ϦΫΤετΛ࡞੒ String encodedText = null; try { encodedText = URLEncoder.encode(text,

    "utf-8"); } catch (UnsupportedEncodingException ignore) {} String url = "https://api.stackexchange.com/2.2/search? order=desc&sort=activity&intitle=" + encodedText + "&site=stackoverflow&filter=!-*f(6pnztD5P"; Request request = new Request.Builder() .url(url) .build(); w ϦΫΤετ͢Δ63-Λγϡοͱ࡞੒ ˡ0L)UUQʹ౉͢ϦΫΤετͷ৘ใ
  55. ϦΫΤετΛ౤͛Δ w "OESPJEͰ͸6*ͷߋ৽ʹ࢖͏εϨου͸Ұͭ w ͜ͷεϨουҎ֎Ͱ6*ؔ܎Λ࿔ΔͱΤϥʔ w ωοτϫʔΫͷϦΫΤετ͸ɺ6*εϨουͰߦͬ ͯ͸͍͚ͳ͍ w ϦΫΤετʹ͕͔͔࣌ؒΔͱը໘͕ݻ·ΔͨΊ

  56. 0L)UUQΛ࢖ͬͨϦΫΤετ

  57. new OkHttpClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException

    e) { e.printStackTrace(); } @Override public void onResponse(Call call, final Response response)
 throws IOException { final String body = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, body, 
 Toast.LENGTH_LONG).show(); } }); } }); • enqueue ʹ Callback Λ౉͢ͱ
 ผεϨουͰ Request ͞ΕΔ
  58. new OkHttpClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException

    e) { e.printStackTrace(); } @Override public void onResponse(Call call, final Response response)
 throws IOException { final String body = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, body, 
 Toast.LENGTH_LONG).show(); } }); } }); • runOnUiThread() ʹ Runnable Λ౉͢ͱ
 6*εϨουͰ run() ͕࣮ߦ͞ΕΔ
  59. new OkHttpClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException

    e) { e.printStackTrace(); } @Override public void onResponse(Call call, final Response response)
 throws IOException { final String body = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, body, 
 Toast.LENGTH_LONG).show(); } }); } }); • ड͚औͬͨ body Λͦͷ··τʔετʹग़͢
  60. ࣮ػͰ֬ೝ

  61. ᶅ+40/Λॲཧ

  62. +40/Λύʔε • JsonObject(String json) • String Λύʔε͠ Json ͱͯ͠ѻ͏ •

    ྫ: String JsonObject#getString
 (String name) • json ͷ name ͱ͍͏߲໨ͷจࣈྻΛऔಘ
  63. • ฦ͖ͬͯͨ Response Λ 
 JsonObject ʹม׵ɺͦͷதͷ “items” Λऔಘ @Override

    public void onResponse(Call call, final Response response) throws … { final String body = response.body().string(); try { JSONObject json = new JSONObject(body); JSONArray questionsJson = json.getJSONArray("items"); } catch (JSONException ignore) {} }
  64. σʔλอ࣋Ϋϥε

  65. σʔλอ࣋Ϋϥε w ฦ͖ͬͯͨ+40/ΛಡΈࠐΈɺΫϥεʹ֨ೲ͢Δ w σʔλΛѻ͍΍͘͢͢ΔͨΊ

  66. σʔλอ࣋Ϋϥε • Question ΫϥεΛ࡞Δ • Question.java Λ࡞੒

  67. public class Question { public final boolean isAnswered; public final

    String ownerName; public final int upVoteCount; public final Date creationDate; public final String title; public Question(JSONObject json) throws ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹJSONException { isAnswered = ɹɹɹ ɹɹɹɹɹɹɹjson.getBoolean(“is_answered"); upVoteCount = 
 ɹɹɹɹɹɹɹjson.getInt(“up_vote_count"); creationDate = new Date(
 ɹɹɹɹɹɹɹjson.getInt("creation_date")
 ɹɹɹɹɹɹɹ * 1000); title = json.getString(“title"); JSONObject owner = 
 ɹɹɹɹɹɹɹjson.getJSONObject("owner"); ownerName = 
 ɹɹɹɹɹɹɹowner.getString("display_name"); } }
  68. public class Question { public final boolean isAnswered; public final

    String ownerName; public final int upVoteCount; public final Date creationDate; public final String title; public Question(JSONObject json) throws ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹJSONException { isAnswered = ɹɹɹ ɹɹɹɹɹɹɹjson.getBoolean(“is_answered"); upVoteCount = 
 ɹɹɹɹɹɹɹjson.getInt(“up_vote_count"); creationDate = new Date(
 ɹɹɹɹɹɹɹjson.getInt("creation_date")
 ɹɹɹɹɹɹɹ * 1000); title = json.getString(“title"); JSONObject owner = 
 ɹɹɹɹɹɹɹjson.getJSONObject("owner"); ownerName = 
 ɹɹɹɹɹɹɹowner.getString("display_name"); } }
  69. public class Question { public final boolean isAnswered; public final

    String ownerName; public final int upVoteCount; public final Date creationDate; public final String title; public Question(JSONObject json) throws ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹJSONException { isAnswered = ɹɹɹ ɹɹɹɹɹɹɹjson.getBoolean(“is_answered"); upVoteCount = 
 ɹɹɹɹɹɹɹjson.getInt(“up_vote_count"); creationDate = new Date(
 ɹɹɹɹɹɹɹjson.getInt("creation_date")
 ɹɹɹɹɹɹɹ * 1000); title = json.getString(“title"); JSONObject owner = 
 ɹɹɹɹɹɹɹjson.getJSONObject("owner"); ownerName = 
 ɹɹɹɹɹɹɹowner.getString("display_name"); } }
  70. public class Question { public final boolean isAnswered; public final

    String ownerName; public final int upVoteCount; public final Date creationDate; public final String title; public Question(JSONObject json) throws ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹJSONException { isAnswered = ɹɹɹ ɹɹɹɹɹɹɹjson.getBoolean(“is_answered"); upVoteCount = 
 ɹɹɹɹɹɹɹjson.getInt(“up_vote_count"); creationDate = new Date(
 ɹɹɹɹɹɹɹjson.getInt("creation_date")
 ɹɹɹɹɹɹɹ * 1000); title = json.getString(“title"); JSONObject owner = 
 ɹɹɹɹɹɹɹjson.getJSONObject("owner"); ownerName = 
 ɹɹɹɹɹɹɹowner.getString("display_name"); } }
  71. KTPOΛ2VFTUJPOʹม׵

  72. • json ͷ഑ྻͷཁૉ͢΂ͯΛ Question ʹม׵ @Override public void onResponse(Call call,

    final Response response) throws … { final String body = response.body().string(); try { JSONObject json = new JSONObject(body); JSONArray questionsJson = json.getJSONArray("items"); final List<Question> questions = new ArrayList<>(); for (int i = 0; i < questionsJson.length(); i++) { questions.add(new Question(questionsJson.getJSONObject(i))); } runOnUiThread(new Runnable() { … Toast.makeText(MainActivity.this, questions.get(0).title, 
 Toast.LENGTH_LONG).show(); }); } catch (JSONException ignore) {} }
  73. • Ұ൪໨ͷ Question ͷλΠτϧΛτʔετදࣔ @Override public void onResponse(Call call, final

    Response response) throws … { final String body = response.body().string(); try { JSONObject json = new JSONObject(body); JSONArray questionsJson = json.getJSONArray("items"); final List<Question> questions = new ArrayList<>(); for (int i = 0; i < questionsJson.length(); i++) { questions.add(new Question(questionsJson.getJSONObject(i))); } runOnUiThread(new Runnable() { … Toast.makeText(MainActivity.this, questions.get(0).title, 
 Toast.LENGTH_LONG).show(); }); } catch (JSONException ignore) {} }
  74. ࣮ػͰ֬ೝ

  75. ᶆॲཧͨ݁͠ՌΛදࣔ

  76. 3FDZDMFS7JFX ಉ͡7JFXΛ܁Γฦ͠Ϧετදࣔ͢Δ7JFX

  77. 3FDZDMFS7JFX ී௨ʹ্͔ΒViewΛஔ͚͹͍͍͡ΌΜʁ

  78. w ⚠ཁૉ͕ݸҎ্ʹͳΔ͜ͱ΋ w ྫ5XJUUFS w ͜ͷ࣌ݸಉ࣌ʹViewΛอ࣋ɾ؅ཧ͢Δʁ
 ˠ๲େͳϝϞϦɾॲཧΛফඅͯ͠͠·͏ 3FDZDMFS7JFX

  79. w Ϧετදࣔ͸ಉ͡ߏ଄ͷView͕࿈ͳΔ w จࣈྻ౳ͷ಺༰͕ҧ͏͚ͩ ˠɹอ࣋ɾ؅ཧ͸ը໘ʹදࣔ͞ΕΔViewͷΈ ˠɹҰ౓࡞ͬͨ7JFX͸࠶ར༻͠ɺ
 දࣔ࣌ʹ಺༰Λมߋ͢Δ 3FDZDMFS7JFX

  80. w ͢΂ͯΛอ࣋ɾ؅ཧ ී௨ͷ7JFX View 1 2 3 4 5 6

    7 8 9 10 11 12 13 14 15 16 17 18 ࣮ࡍͷදࣔྖҬ →
  81. w อ࣋ɾ؅ཧ͸ը໘্ͷΈ 3FDZDMFS7JFX View 3 4 5 6 7 8

    9 10 11 ະੜ੒ ࣮ࡍͷදࣔྖҬ →
  82. εΫϩʔϧ͞ΕΔͱʜ View 3 4 5 6 7 8 9 10

    11 ະੜ੒ View ͷ࠶ར༻ දࣔྖҬ →
  83. εΫϩʔϧ͞ΕΔͱʜ View 5 6 7 8 9 10 11 3

    ->12 4 ->13 ະੜ੒ ← ৽͍͠஋Λઃఆ දࣔྖҬ →
  84. 3FDZDMFS7JFX ࠶ར༻

  85. w ListView͕ݩʑ͋ͬͨʢ͜Ε΋࠶ར༻Մೳʣ w ͦͷڧԽɾΧελϚΠζՄೳ൛ 3FDZDMFS7JFX

  86. Ϧετදࣔ ߲໨ͷViewΛ࡞੒ ˣ RecyclerViewʹදࣔ

  87. ߲໨ͷ7JFXʢলུʣ

  88. w ཁૉΛදࣔ͢Δͱ͖ʹViewHolder͕߱ͬͯ͘Δ w ੜ੒PS࠶ར༻͞ΕͨViewΛؚΉΫϥε w 7JFX)PMEFSࣗମ΋࠶ར༻͞Εͨ΋ͷ w ͜ΕΛ༻͍ͯ಺༰Λઃఆ͢Δ 3FDZDMFS7JFXʹදࣔ

  89. w ViewͷछྨผʹͦΕͧΕViewHolderΛ࡞Δ w ࠓճ͸Ұ͚ͭͩ 7JFX)PMEFS࡞੒

  90. w ࠷ॳʹView͕ੜ੒͞ΕΔͱ͖ʹݺ͹ΕΔ w findViewById΋ੜ੒࣌ʹҰ౓͚ͩߦ͏ private class QuestionViewHolder extends RecyclerView.ViewHolder {

    private final TextView mCountView; private final TextView mTitleView; … public QuestionViewHolder(View itemView) { super(itemView); mCountView = (TextView) itemView.findViewById(R.id.count); mTitleView = (TextView) itemView.findViewById(R.id.title); … } public void bindView(Question question) { mCountView.setText(String.valueOf(question.upVoteCount)); mTitleView.setText(question.title); … itemView.setOnClickListener(new View.OnClickListener(){ … Intent intent = new Intent(Intent.ACTION_VIEW,
 Uri.parse(question.link)); v.getContext().startActivity(intent); }); } } }
  91. private class QuestionViewHolder extends RecyclerView.ViewHolder { private final TextView mCountView;

    private final TextView mTitleView; … public QuestionViewHolder(View itemView) { super(itemView); mCountView = (TextView) itemView.findViewById(R.id.count); mTitleView = (TextView) itemView.findViewById(R.id.title); … } public void bindView(Question question) { mCountView.setText(String.valueOf(question.upVoteCount)); mTitleView.setText(question.title); … itemView.setOnClickListener(new View.OnClickListener(){ … Intent intent = new Intent(Intent.ACTION_VIEW,
 Uri.parse(question.link)); v.getContext().startActivity(intent); }); } } } w View಺෦ͷ஋Λઃఆ
  92. private class QuestionViewHolder extends RecyclerView.ViewHolder { private final TextView mCountView;

    private final TextView mTitleView; … public QuestionViewHolder(View itemView) { super(itemView); mCountView = (TextView) itemView.findViewById(R.id.count); mTitleView = (TextView) itemView.findViewById(R.id.title); … } public void bindView(Question question) { mCountView.setText(String.valueOf(question.upVoteCount)); mTitleView.setText(question.title); … itemView.setOnClickListener(new View.OnClickListener(){ … Intent intent = new Intent(Intent.ACTION_VIEW,
 Uri.parse(question.link)); v.getContext().startActivity(intent); }); } } } w ΫϦοΫͨ͠Β࣭໰ϖʔδΛ։͘Α͏ʹ͢Δ
  ҉໧తIntentΛ౤͛Δ
  93. w RecyclerViewΛૢ࡞͢ΔΫϥε 3FDZDMFS"EBQUFS࡞੒

  94. w දࣔ͢ΔQuestionͷϦετ public class QuestionsRecyclerAdapter extends
 RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<Question>

    mQuestionList = new ArrayList<>(); @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View questionView = LayoutInflater.from(parent.getContext())
 .inflate(R.layout.question_item, parent, false); return new QuestionViewHolder(questionView); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((QuestionViewHolder) holder).bindView(mQuestionList.get(position)); } public void setQuestionList(List<Question> questionList) { mQuestionList = questionList; notifyDataSetChanged(); } @Override public int getItemCount() { return mQuestionList.size(); } }
  95. w ͜͜ͰViewHolderΛ࡞੒͢Δ w ϨΠΞ΢τΛੜ੒ˠViewHolderΛ࡞੒ public class QuestionsRecyclerAdapter extends
 RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Question> mQuestionList = new ArrayList<>(); @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View questionView = LayoutInflater.from(parent.getContext())
 .inflate(R.layout.question_item, parent, false); return new QuestionViewHolder(questionView); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((QuestionViewHolder) holder).bindView(mQuestionList.get(position)); } public void setQuestionList(List<Question> questionList) { mQuestionList = questionList; notifyDataSetChanged(); } @Override public int getItemCount() { return mQuestionList.size(); } }
  96. w position൪໨ͷViewͷ಺༰Λઃఆ͢Δ w ͜͜ͰViewHolderͷbindViewΛݺΜͰ͍Δ public class QuestionsRecyclerAdapter extends
 RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Question> mQuestionList = new ArrayList<>(); @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View questionView = LayoutInflater.from(parent.getContext())
 .inflate(R.layout.question_item, parent, false); return new QuestionViewHolder(questionView); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((QuestionViewHolder) holder).bindView(mQuestionList.get(position)); } public void setQuestionList(List<Question> questionList) { mQuestionList = questionList; notifyDataSetChanged(); } @Override public int getItemCount() { return mQuestionList.size(); } }
  97. w notifyDataSetChanged() Λߦ͏͜ͱͰ
 RecyclerViewʹมߋΛ௨஌͢Δ public class QuestionsRecyclerAdapter extends
 RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Question> mQuestionList = new ArrayList<>(); @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View questionView = LayoutInflater.from(parent.getContext())
 .inflate(R.layout.question_item, parent, false); return new QuestionViewHolder(questionView); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((QuestionViewHolder) holder).bindView(mQuestionList.get(position)); } public void setQuestionList(List<Question> questionList) { mQuestionList = questionList; notifyDataSetChanged(); } @Override public int getItemCount() { return mQuestionList.size(); } }
  98. w RecyclerViewʹRecyclerAdapterΛηοτ 3FDZDMFS7JFX΁ઃఆ public class MainActivity extends AppCompatActivity { private

    QuestionsRecyclerAdapter mQuestionsRecyclerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); … RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); mQuestionsRecyclerAdapter = new QuestionsRecyclerAdapter(); recyclerView.setAdapter(mQuestionsRecyclerAdapter); } }
  99. w RecyclerAdapterʹQuestionΛηοτ 2VFTUJPOΛઃఆ @Override public void onResponse(Call call, final Response

    response) throws IOException { final String body = response.body().string(); try { JSONObject json = new JSONObject(body); ɹɹɹɹɹJSONArray questionsJson = json.getJSONArray("items"); final List<Question> questions = new ArrayList<>(); ɹɹɹɹɹfor (int i = 0; i < questionsJson.length(); i++) { questions.add(new Question(questionsJson.getJSONObject(i))); } runOnUiThread(new Runnable() … mQuestionsRecyclerAdapter.setQuestionList(questions); ); } catch (JSONException ignore) {} }
  100. ࣮ػͰ֬ೝ

  101. J04ฤ͸ͪ͜Β