Android Kotlinでよく使うスニペット

Androidの開発中にためこんだスニペット的なものの一覧です。

### NfCのON/OFFが切り替わったらイベントを受け取る

```kotlin
val mNfcReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) {
            when (intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
                    NfcAdapter.STATE_OFF)) {
                NfcAdapter.STATE_OFF -> {
                }
                NfcAdapter.STATE_TURNING_OFF -> {
                }
                NfcAdapter.STATE_ON -> {
                }
                NfcAdapter.STATE_TURNING_ON -> {
                }
            }
        }
    }
}
registerReceiver(mNfcReceiver, IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED))
```

### Dialogでアクションボタンの色を変える
```xml
<resources>
    <style name="MyDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
        <item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
        <item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
    </style>

    <style name="NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
        <item name="android:textColor">#4A4A4A</item>
    </style>

    <style name="PositiveButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
        <item name="android:textColor">#1A89FF</item>
    </style>
</resources>
```

```kotlin
val builder = AlertDialog.Builder(this, R.style.RegisterDialogTheme)
builder.setView(layoutInflater.inflate(R.layout.my_dialog_layout, null))
builder.create().show()
```


### ImageViewを丸くする
```kotlin
view.outlineProvider = object : ViewOutlineProvider() {

    override fun getOutline(view: View, outline: Outline) {
        outline.setOval(
                0,
                0,
                view.width,
                view.height
        )
    }
}
view.clipToOutline = true

```

### ボタンを角丸にする
```xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle" >
            <solid android:color="#3399FF" />
            <corners android:radius="5dp"/>
        </shape>
    </item>
</selector>
```

```xml
<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/round_button"
    android:text="button"/>
```


### 文字リソースで値展開

```xml
<resources>
    <string name="welcom">ようこそ %1$s !</string>
</resources>
```
```kotlin
val message = getString(R.string.welcom, "太郎")
```

### ActionBarの影を消す

```xml
<android.support.design.widget.AppBarLayout
    android:id="@+id/mainAppVarLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:elevation="0dp"
    android:theme="@style/AppTheme.AppBarOverlay">
    <!-- toobar here-->
</android.support.design.widget.AppBarLayout>
```

上記で消えない場合、（背景に画像をおいている場合など

```kotlin
mainAppVarLayout.outlineProvider = object : ViewOutlineProvider() {

    override fun getOutline(view: View, outline: Outline) {
        outline.setOval(
                0,
                0,
                0,
                0
        )
    }
}
```

### 1秒おきにViewを点滅させる
```kotlin
    private fun blink(view: View) {
        val handler = Handler()
        Thread(Runnable {
            val timeToBlink = 1000
            try {
                Thread.sleep(timeToBlink.toLong())
            } catch (e: Exception) {
            }

            handler.post {
                if (view.alpha == 1f) {
                    view.alpha = 0.2f
                } else {
                    view.alpha = 1f
                }
                blink(view)
            }
        }).start()
    }
```

### Drwableの取得の仕方

```kotlin
val drwable = ResourcesCompat.getDrawable(resources, android.R.drawable.ic_delete, null)
```


### SearchViewの開閉
```kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.activity_main, menu)
    val menuItem = menu.findItem(R.id.menu_item_bar_search)
    val searchView = menuItem?.actionView as android.support.v7.widget.SearchView
    searchView.isIconified = false
    return true
}

```

### ソフトキーボードを閉じる
```kotlin
if (activity.currentFocus != null) {
    val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
    imm?.hideSoftInputFromWindow(activity.currentFocus!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
```

### Dialog

```kotlin
createDialog().show()

private fun createDialog(): Dialog {
    val builder = AlertDialog.Builder(this)

    builder.setView(layoutInflater.inflate(R.layout.custom_layout, null))
            .setPositiveButton(R.string.card_dialog_ok) { dialog, id ->
                // etc...
            }
            .setNegativeButton(R.string.cancel) { dialog, id ->
                dialog.cancel()
            }
    return builder.create()
}

```


### daggerを使うときのgradle
```
    implementation "com.google.dagger:dagger:2.16"  
    implementation 'com.google.dagger:dagger-android:2.15'  
    annotationProcessor "android.arch.lifecycle:compiler:1.1.1"  
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1'  
    kapt 'com.google.dagger:dagger-compiler:2.15'
```


### XMLアニメーションとAnimationListernerを同時に使う
```kotlin
fun viewToAlpha(view: View) {
    val anim = AnimationUtils.loadAnimation(activity, R.anim.to_alpha)
    anim.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationStart(animation: Animation?) {}
        override fun onAnimationRepeat(animation: Animation?) {}
        override fun onAnimationEnd(animation: Animation) {
            view.visibility = View.GONE
        }
    })
    view.startAnimation(anim)
}

```

```xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:duration="100000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        />
</set>

```


### 毎分コールされるインテント
```kotlin
val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        println("Call every minute.")
    }
}
registerReceiver(receiver, IntentFilter(Intent.ACTION_TIME_TICK))
```

### リストを逆向きにする
```
<android.support.v7.widget.RecyclerView
    app:stackFromEnd="true"
    app:reverseLayout="true"/>
```


### Androud Studio コマンド
コードフォーマット ``cmd + alt + shift + L``
ファイル名インクリメントサーチ ``cmd + shift + O``
クラス名インクリメントサーチ ``cmd + O``


### ViewModelProviderで作るViewModelに引数を渡したいときはFactoryが必要
```kotlin
class CustomViewModelFactory(private val test: String) : ViewModelProvider.NewInstanceFactory() {  
  
    override fun <T : ViewModel?> create(modelClass: Class<T>?): T {  
        return LoginViewmodel(test) as T  
    }  
  
}
```

```kotlin
val viewModel = ViewModelProviders.of  
(this,CustomViewModelFactory("somerandomvalue")).get(LoginViewmodel::class._java_)
```

### kotlin拡張関数を使いたい場合以下の記述が必要。（@BindingAdapterの記述等
```kotlin
// build.gradle(app:module)
apply plugin: 'kotlin-kapt'
```

### 別のアクティビティを開始する
```kotlin
startActivity(Intent(this, SettingsActivity::class.java))
```

### 別のアクティビティを開始してデータを受け取る
```kotlin
val RESULT_CODE = 200
startActivityForResult(Intent(this, UserActivity::class.java), RESULT_CODE);

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == RESULT_CODE && resultCode == Activity.RESULT_OK) {
        // etc
    }
}

```

### フラグメントを開始する
```xml
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</FrameLayout>
```
```kotlin
val fragmentManager = getSupportFragmentManager()
val fragView = FragmentView.newInstance("", "")
fragmentManager.beginTransaction()
    .replace(R.id.content_frame, fragView)
    .commit()

```

### フラグメントを取得する

```kotlin
val view = supportFragmentManager.findFragmentById(R.id.content_frame) as FragmentView?
if (view is FragmentView) {
    view.onEvent()
}
```


### 設定値の書き込み・取得
```kotlin
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
with (sharedPref.edit()) {
    putString("pref_account_email", "foo@example.com")
    commit()
}

val sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
val email = sharedPref.getString("pref_account_email", "default@example.com")

```

### 画面回転時に値を保持しておく
```kotlin
override fun onSaveInstanceState(savedInstanceState: Bundle) {
    super.onSaveInstanceState(savedInstanceState)
    savedInstanceState.putSerializable("myList", myList as Serializable)
    savedInstanceState.putInt("radioButtonId", id)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                            savedInstanceState: Bundle?): View? {
    val rootView = inflater.inflate(R.layout.fragment_stamp, container, false)
    rootView.myList.layoutManager = LinearLayoutManager(context)

    val rootView = inflater.inflate(R.layout.fragment, container, false)
    if (savedInstanceState == null) {
        rootView.myList.adapter = MyRecyclerViewAdapter(ListOf(), listListener)
    } else {
        val myList = savedInstanceState.getInt("myList") as Mylist
        rootView.myList.adapter = MyRecyclerViewAdapter(myList, listListener)

        val id = savedInstanceState.getInt("radioButtonId")
        rootView.radioGroup.check(id)
    }
    return rootView
}
```

### Wifi network
```kotlin
    class NetworkReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context?, intent: Intent?) {
            val conn = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val networkInfo = conn.activeNetworkInfo
            Log.d("onReceive", networkInfo?.toString() ?: "networkInfo is null")

            if (networkInfo == null) {
                Toast.makeText(context, "Lost network..." , Toast.LENGTH_SHORT).show();

            } else if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected ) {

                // Wifi is connected
                val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager
                val wifiInfo = wifiManager.getConnectionInfo() ?: return

                if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
                    val ssid = wifiInfo.ssid
                    val message = "Wifi connected! " + ssid
                    Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "Wifi staying...", Toast.LENGTH_SHORT).show()
                }

            } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE && networkInfo.isConnected ) {
                Toast.makeText(context, "Mobile connected!", Toast.LENGTH_SHORT).show();

            } else {
                Toast.makeText(context, "Wifi lost!", Toast.LENGTH_SHORT).show();
            }
        }
    }
```