Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

nonylene
March 13, 2016

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

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

nonylene

March 13, 2016
Tweet

More Decks by nonylene

Other Decks in Technology

Transcript

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

    IUUQTBQJTUBDLFYDIBOHFDPNTFBSDI PSEFSEFTDTPSUBDUJWJUZJOUJUMFBOESPJET JUFTUBDLPWFSqPXpMUFS GQO[U%1
  2. .BJO"DUJWJUZKBWB public class MainActivity extends AppCompatActivity { @Override protected void

    onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } ˣޙͰઆ໌ ˢϨΠΞ΢τΛදࣔ w ը໘੍ޚ
  3. 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
  4. "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ͷ৘ใ
  5. 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
  6. 7JFXΛ"DUJWJUZ಺Ͱೝࣝ • View View#findViewById(int id) • YNMͰࢦఆͨ͠*%ͷ View Λऔಘ͢Δ •

    ྫ: id=“@+id/view_id” ͱࢦఆ
 → View view =
 findViewById(R.layout.view_id); • R.layout.~~ ͸YNMͰ*%Λࢦఆ͢Δͱ
 ࣗಈతʹ࡞ΒΕΔɺ*%ͷू߹Ϋϥε
  7. Ωʔϫʔυऔಘ • ಘΒΕͨ 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); } }
  8. ϘλϯͷΫϦοΫ • View View#setOnClickListener
 (OnClickListener listener) • Click ͞Εͨ࣌ͷϦεφʔΛઃఆ •

    ΫϦοΫ͞ΕΔ
 → Ϧεφʔʹ͋Δࢦఆͷؔ਺͕ݺ͹ΕΔ • java7 ʹϥϜμࣜ͸ແ͍
 → ແ໊ΦϒδΣΫτΛ࡞੒͢Δ
  9. @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 ͔ΒΩʔϫʔυऔಘ͢Δ
  10. ϦΫΤετΛ࡞੒ 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ʹ౉͢ϦΫΤετͷ৘ใ
  11. 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 ͞ΕΔ
  12. 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() ͕࣮ߦ͞ΕΔ
  13. 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 Λͦͷ··τʔετʹग़͢
  14. +40/Λύʔε • JsonObject(String json) • String Λύʔε͠ Json ͱͯ͠ѻ͏ •

    ྫ: String JsonObject#getString
 (String name) • json ͷ name ͱ͍͏߲໨ͷจࣈྻΛऔಘ
  15. • ฦ͖ͬͯͨ 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) {} }
  16. 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"); } }
  17. 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"); } }
  18. 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"); } }
  19. 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"); } }
  20. • 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) {} }
  21. • Ұ൪໨ͷ 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) {} }
  22. w ͢΂ͯΛอ࣋ɾ؅ཧ ී௨ͷ7JFX View 1 2 3 4 5 6

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

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

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

    ->12 4 ->13 ະੜ੒ ← ৽͍͠஋Λઃఆ දࣔྖҬ →
  26. 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); }); } } }
  27. 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಺෦ͷ஋Λઃఆ
  28. 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Λ౤͛Δ
  29. 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(); } }
  30. 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(); } }
  31. 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(); } }
  32. 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(); } }
  33. 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); } }
  34. 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) {} }