質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • Android Studio

    4221questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

  • Kotlin

    571questions

    Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

ボタンを押して日付を反映させたカードをlistViewに追加したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 307

aNomoto

score 4

 前提・実現したいこと

初めて自主製作アプリを開発しているものです。
食事記録アプリ?のようなものが作りたくて
以下のような処理を実現させたいです。

floating Action Buttonを押す。
↓
カレンダーのダイアログが表示される。
↓
list_item.xmlの内容がlistViewに出力される。このときダイアログで選択した日付がdate_button.textに代入されている。

 発生している問題

ネットのサンプルコードや本を頼りにコーディングを行ったのですが、
以下のような処理になってしまいます。

floating Action Buttonを押す。
↓
add(ListItem(""))の数だけlist_item.xmlの内容が一度に出力される。
↓
カレンダーのダイアログが表示される。
↓
ダイアログで選択した日付が一番上のカードにだけ反映される。

 該当のソースコード

//MainActivity.kt
package com.example.promoto.proc

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.text.format.DateFormat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageButton
import android.widget.ListView
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.list_item.*


import java.util.*


class MainActivity : AppCompatActivity() ,DatePickerFragment.OnDateSelectedListener {

    override fun onSelected(year: Int, month: Int, date: Int) {
        val c = Calendar.getInstance()
        c.set(year, month, date)
        date_button.text = DateFormat.format("MM/dd", c)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        floatingActionButton.setOnClickListener {

            //初期のリスト項目を設定
            val arrayAdapter = MyArrayAdapter(this, 0).apply{
                add(ListItem(""))
            }
            //ListViewにリスト項目とArrayAdapterを設定
            val listView: ListView = findViewById(R.id.listView)
            listView.adapter = arrayAdapter

            val dialog = DatePickerFragment()
            dialog.show(supportFragmentManager, "date_dialog")
        }
    }
}


class ListItem(val date_data : String){}
//リスト項目を再利用するためのホルダー
data class ViewHolder(val date_dataView: TextView,val morningIcon:ImageButton,val lunchIcon:ImageButton,val dinnerIcon:ImageButton)

//自作のリスト項目データを扱えるようにしたArrayAdapter
class MyArrayAdapter : ArrayAdapter<ListItem> {
    private var inflater : LayoutInflater? = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)as LayoutInflater?

    constructor(context: Context,resource :Int):super(context,resource){}
    override fun getView(position:Int, convertView: View?, parent: ViewGroup?):View{

        var viewHolder : ViewHolder? = null
        var view = convertView

        //再利用の設定
        if(view == null){

            view = inflater!!.inflate(R.layout.list_item,parent,false)

            viewHolder = ViewHolder(
                    view.findViewById(R.id.date_button),
                    view.findViewById(R.id.morning_button),
                    view.findViewById(R.id.lunch_button),
                    view.findViewById(R.id.dinner_button)
            )
            view.tag = viewHolder
        }else{
            viewHolder = view.tag as ViewHolder
        }

        //項目の情報設定
        val listItem = getItem(position)
        viewHolder.date_dataView.text =listItem!!.date_data

        viewHolder.morningIcon.setOnClickListener{
            //削除ボタンを押したときの処理
            this.remove(listItem)
            this.notifyDataSetChanged()
        }
        return view!!
    }
}
//Dialogs.kt
package com.example.promoto.proc

import android.app.DatePickerDialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.support.v4.app.DialogFragment
import android.widget.DatePicker
import java.util.*

class DatePickerFragment : DialogFragment(),
    DatePickerDialog.OnDateSetListener{

    interface OnDateSelectedListener{
        fun onSelected(year: Int,month: Int,date: Int)
    }

    private lateinit var listener: OnDateSelectedListener

    override fun onAttach(context: Context?){
        super.onAttach(context)
        if(context is OnDateSelectedListener){
            listener = context
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val c = Calendar.getInstance()
        val year = c.get(Calendar.YEAR)
        val month = c.get(Calendar.MONTH)
        val date =c.get(Calendar.DAY_OF_MONTH)
        return DatePickerDialog(context,this,year,month,date)

    }

    override fun onDateSet(view: DatePicker,year:Int,month: Int,date: Int) {
        listener.onSelected(year,month,date) //To change body of created functions use File | Settings | File Templates.
    }
}
//list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <android.support.v7.widget.CardView
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="135dp"
            card_view:cardCornerRadius="4dp"
            android:id="@+id/cardView"
            tools:layout_editor_absoluteX="31dp"
            card_view:layout_constraintTop_toTopOf="parent"
            card_view:layout_constraintBottom_toBottomOf="parent">

        <!-- カードに載せる情報 -->

        <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center_horizontal"
                android:id="@+id/cardRelative"
        >
            <Button
                    android:layout_width="65dp"
                    android:layout_height="match_parent"
                    android:textAllCaps="false" android:layout_alignParentStart="true"
                    android:layout_alignParentTop="true" android:layout_marginTop="0dp"
                    android:layout_marginStart="2dp" android:layout_alignParentBottom="true"
                    android:layout_marginBottom="0dp" android:textStyle="italic"
                    android:layout_toStartOf="@+id/morning_button" android:layout_marginRight="0dp"
                    android:layout_marginEnd="0dp" android:layout_toLeftOf="@+id/morning_button"
                    android:id="@+id/date_button"/>
            <ImageButton
                    android:layout_width="100dp"
                    android:layout_height="match_parent" app:srcCompat="@drawable/morning_icon"
                    android:id="@+id/morning_button"
                    android:layout_alignParentTop="true"
                    android:layout_marginTop="0dp" android:layout_alignParentBottom="true"
                    android:layout_marginBottom="0dp"
                    android:layout_toStartOf="@+id/lunch_button" android:layout_marginRight="2dp"
                    android:layout_marginEnd="2dp" android:layout_toLeftOf="@+id/lunch_button"/>
            <ImageButton
                    android:layout_width="100dp"
                    android:layout_height="wrap_content" app:srcCompat="@drawable/lunch_icon"
                    android:id="@+id/lunch_button"
                    android:layout_alignParentTop="true" android:layout_marginTop="0dp"
                    android:layout_alignParentBottom="true" android:layout_marginBottom="0dp"
                    android:layout_toStartOf="@+id/dinner_button" android:layout_marginRight="2dp"
                    android:layout_marginEnd="2dp" android:layout_toLeftOf="@+id/dinner_button"/>
            <ImageButton
                    android:layout_width="100dp"
                    android:layout_height="wrap_content" app:srcCompat="@drawable/dinner_icon"
                    android:id="@+id/dinner_button"
                    android:layout_alignParentTop="true" android:layout_marginTop="0dp"
                    android:layout_alignParentBottom="true"
                    android:layout_marginBottom="0dp"
                    android:layout_alignParentEnd="true" android:layout_alignParentRight="true"
                    android:layout_marginRight="5dp" android:layout_marginEnd="5dp"/>
        </RelativeLayout>
    </android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>

 試したこと

似たような処理について書かれている記事が見つからない。Buildも問題なくできている事から原因がわからず、手詰まり状態です。

 補足情報(FW/ツールのバージョンなど)

Gradle version 4.6
AndroidStudio 3.2.1

プログラミング初心者で、不慣れな点が多く、質問の説明もわかりにくいと思いますが
回答よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • shal0ne

    2018/10/21 00:08

    すみません、誤タッチで記入途中なのにしかも複数回送信してしまいました。続きを書くと、視覚的にイメージしやすくなるようなものなどを資料として追加した方が回答率が上がると思います。

    キャンセル

  • aNomoto

    2018/10/21 01:07

    ご指摘ありがとうございます。内容に変更があり新たな質問を作成しました。そちらのほうには図やmainのxmlが記述してあるのでよければご覧ください

    キャンセル

  • キャンセル

回答 1

checkベストアンサー

+2

回答ついてないので一応解決策のアイデアだけでも。
ソースコードを補完してAndroidStudioで最初の状態を再現しようと試みましたが動かなかったので、実際にコードを直して、エミュレータで動かして確認した訳ではないことを断っておきます。

override fun onSelected(year: Int, month: Int, date: Int) {
        val c = Calendar.getInstance()
        c.set(year, month, date)
            date_button.text= DateFormat.format("MM/dd", c)
    }


のdate_buttonにはおそらく一番最初に作ったviewHolderのものがずっと保存されています。
なので2つ目を作っても、onSelectedが呼ばれた際には最初のviewHolderのdate_buttonに日付が反映されます。

override fun onSelected(year: Int, month: Int, date: Int) {
        val c = Calendar.getInstance()
        c.set(year, month, date)
            date_button.text= DateFormat.format("MM/dd", c)
    }

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        floatingActionButton.setOnClickListener {

            //初期のリスト項目を設定
            val arrayAdapter = MyArrayAdapter(this, 0).apply{
                add(ListItem(""))
            }
            //ListViewにリスト項目とArrayAdapterを設定
            val listView: ListView = findViewById(R.id.listView)
            listView.adapter = arrayAdapter

            val dialog = DatePickerFragment()
            dialog.show(supportFragmentManager, "date_dialog")
        }
    }


このFABの処理だと、
FABを押してDialog表示
->(Dialogがキャンセルされたかどうかに関わらず)AdapterにListItem("")を追加
->onSelectedで一番最初に作ったdate_buttonに日付を反映
->最初に作ったdate_button.textにはDialogで選択した日付が入り、二つ目にdate_button.textには""がそのまま入った状態で表示
の流れになっていると思います。

override fun onSelected(year: Int, month: Int, date: Int) {
        val c = Calendar.getInstance()
        c.set(year, month, date)

        //Dialogで選択したセットしたい日付を文字列にしてstrに代入
        //(そのままだと型がCharSequenceで、ListItemのString型のプロパティに代入できないので、as Stringでキャスト)
        val str=DateFormat.format("MM/dd", c) as String

        //ここに移動
        //初期のリスト項目を設定
        val arrayAdapter = MyArrayAdapter(this, 0).apply{
            add(ListItem(str))//空の文字列""の代わりに先ほどの文字列を使用
        }
        //ListViewにリスト項目とArrayAdapterを設定
        val listView: ListView = findViewById(R.id.listView)
        listView.adapter = arrayAdapter

        //消す
        //date_button.text = DateFormat.format("MM/dd", c)

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val floatingActionButton=findViewById<FloatingActionButton>(R.id.fab)
        floatingActionButton.setOnClickListener {

            //onSelectedの方に移動
            /*//初期のリスト項目を設定
            val arrayAdapter = MyArrayAdapter(this, 0).apply{
                add(ListItem(""))
            }
            //ListViewにリスト項目とArrayAdapterを設定
            val listView: ListView = findViewById(R.id.listView)
            listView.adapter = arrayAdapter*/

            val dialog = DatePickerFragment()
            dialog.show(supportFragmentManager, "date_dialog")
        }
    }


なので上記のように変更することで処理を
FABを押してDialog表示
->Dialogで日付を選択すれば変数strに日付のフォーマットをString型で保存(選択しなければ全てキャンセル)
->AdapterにListItem(str)を追加
->Adapterを適用し、最初に作ったものと、二つ目に作った、文字列strがdate_button.textに適用されたものが表示
という処理の流れになると思うのでうまくいくと思います。
色々間違っているところもあると思いますが、参考までに。

11/1追記

上記の書き方だとadapterが初期化されてしまっていそうなので、応急手当として次のことをしてもらえればいいと思います。

class MainActivity : AppCompatActivity() ,DatePickerFragment.OnDateSelectedListener {

    //MainActivityのメンバとして追加
    lateinit var arrayAdapter:MyArrayAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //ここで初期化
        arrayAdapter=MyArrayAdapter(this, 0)
        ...
    }
    override fun onSelected(year: Int, month: Int, date: Int) {
        val c = Calendar.getInstance()
        c.set(year, month, date)
        val str=DateFormat.format("MM/dd", c) as String

        //メンバにMyArrayAdapterを保持しているので、その中にListItemを付け足す処理を書く
        arrayAdapter.apply{
            add(ListItem((str)))
        }
        //消す
        /*val arrayAdapter = MyArrayAdapter(this, 0).apply{
            add(ListItem(str))
        }*/
        val listView: ListView = findViewById(R.id.listView)
        listView.adapter = arrayAdapter
    }

    ...
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/29 21:01

    回答ありがとうございました。
    お礼が遅くなって申し訳ありません。
    ソースコードを参考にしましたが1つ目以降のアダプターが表示されませんでした。
    追加したListItemの数だけアダプターが表示されるという風に解釈しているのですがこの考えは間違いないでしょうか?

    キャンセル

  • 2018/11/01 19:47

    返信遅い人ですすみません。
    おそらく仕様をちゃんと理解しておらずゴミ回答してしまいました。
    あと、AdapterはList<ListItem>というListItemが入った袋を持っていて、ViewにItemを反映させてくれる人のことです。
    なので、正しくは「Itemが表示される」だと思います。

    本題に戻り結論から言うと、その考えは半分合ってて半分間違っていると思います。

    まずはじめに、fun onSelected(){~}というのは大まかに言うと、『onSelectedとどこかでまた書かれたら、メモリ上のどこかにある()のなかの情報を元に、{}の中の~と言う処理をメモリ上のどこかに新しく書いて実行してね』と言うことです。
    きっとDialogで日付を選択したらonSelectedが呼び出されるよう、Androidに書いてあると思います。

    もし、onSelectedの中に
    val arrayAdapter = MyArrayAdapter(this, 0)
    と書いたなら、onSelectedが実行される度にメモリ上のどこかに新しくMyArrayAdapterが生成されます。
    二回目に実行した時も新しくMyArrayAdapterがメモリ上に生成されますが、これは1回目のものとは別物なので1回目に入力した情報は持っていません。
    その後
    listView.adapter = arrayAdapter
    と書いてあるので、2回目に実行した際には、2回目に入力した情報のみを持つMyArrayAdapterがlistViewに適用されます。
    したがってonSelectedの中に移した際には一つ目以降のItemが表示されないという問題が発生したのだと思います。


    ところが最初はonClickListener{}の中に書いていました。
    この記法はonClickListener({})の略で{}の中には処理を書きます。
    print("Hello World!")であれば、fun print(){~}が別のファイルに書かれていて、アプリを起動した際にHello World!と言う文がメモリ上のどこかに保存され、~の部分を実行するときに呼び出されます。
    onClickListener({})の場合は別のファイルにfun onClickListener(){~}が書かれていて、今回は()の中に{}という処理が書いてあるので、それを元に~の部分を実行するということです。

    printの時にHelloWorldが保存されたように、{}もメモリ上のどこかに保存されますから、当然その中身であるMyArrayAdapterの情報も保存されます。
    また、{}は保存されているので、onSelectedの時とは違い2回目3回目に実行される時も毎回新しく作り直す必要がありません。
    したがってonClickListener{}の中に
    val arrayAdapter = MyArrayAdapter(this, 0)
    と書いたときには、onSelected()の時のように毎回MyArrayAdapterを生成し直すということが起きず、『追加したListItemの数だけアダプターが表示される』という状態が成り立っていたのだと思います。


    毎度間違った記述を含んでいそうですが、認識としてはこれで大筋は合っていると思います。
    詳しくは「関数オブジェクト」などでググってもらえれば大丈夫です。

    キャンセル

  • 2018/11/02 00:49 編集

    親切に説明していただきありがとうございます。
    おかげでListItemが一つしか表示されなかった理由がわかりました。
    関数オブジェクトについて改めて勉強したいと思います。

    追記内容を試したところアプリが起動できなくなってしまいました。
    エラーメッセージは追記の通りです。

    エラーケースについて調べたのですが有力な情報が得られずにいます。
    見覚えのないファイルのエラーが多いのですが、この場合MainActivity内のエラーがほかのファイルに影響を及ぼしていると考えていいのでしょうか?
    質問ばかりで申し訳ないです。

    キャンセル

  • 2018/11/02 01:04

    文字数の関係で追記できなかったためコメント欄で記述します。
    Process: com.example.promoto.proc, PID: 6913
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.promoto.proc/com.example.promoto.proc.MainActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2679)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
    Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
    at android.app.Activity.getSystemService(Activity.java:5915)
    at android.view.LayoutInflater.from(LayoutInflater.java:229)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:210)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:204)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:138)
    at com.example.promoto.proc.MyArrayAdapter.<init>(MainActivity.kt:62)
    at com.example.promoto.proc.MainActivity.<init>(MainActivity.kt:22)
    at java.lang.Class.newInstance(Native Method)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

    キャンセル

  • 2018/11/02 01:31 編集

    あー、ごめんなさい。

    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.promoto.proc/com.example.promoto.proc.MainActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()

    これはonCreateが終わるまでLayoutInflaterとかが出来上がらないので、LayoutInflaterをメンバに持つMyArrayAdapterを初期化するとまずいよみたいなやつだと思います。

    val arrayAdapter=MyArrayAdapter(this,0)
    だとonCreateの前に実行されてしまうので
    lateinit var arrayAdapter:MyArrayAdapter
    とすれば初期化を遅らせる(late initialize)ことができるので、試してみてください。
    その際、onCreateの最後に
    arrayAdapter = MyArrayAdapter(this, 0)
    と書けば、onCreateが一通り終わった後に初期化されます。

    キャンセル

  • 2018/11/02 09:59

    横入り失礼します。
    arrayAdapterの初期化を遅らせたいなら、lateinitよりもlazyを使ったほうがスマートかつ安全ですね。

    private val arrayAdapter by lazy { MyArrayAdapter(this, 0) }

    lateinitはうっかり初期化忘れをしてバグを発生させる可能性もあるので、あまり好ましくありません。

    キャンセル

  • 2018/11/02 12:05

    そんなものがあるんですね。
    調べてみましたが、初めて呼ばれた時に自動で
    arrayAdapter=MyArrayAdapter(this, 0)
    としてくれるみたいですね。
    いちいちonCreateの中で初期化する文を書く必要がないですし、ベストだと思います。
    横入りしてもらえて助かりましたm(__)m

    キャンセル

  • 2018/11/04 06:56

    返信が遅くなってしまい申し訳ないです。
    無事起動、処理の確認が終わりました。
    数日にわたって、まめにコメントしてくださり本当に助かりました。
    また機会があればよろしくお願いします。

    キャンセル

  • 2018/11/04 14:19

    よかったです。
    お互い頑張りましょう。
    kakajikaさんありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • Android Studio

    4221questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

  • Kotlin

    571questions

    Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。