Android
Kotlin

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

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


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

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でアクションボタンの色を変える

<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>

val builder = AlertDialog.Builder(this, R.style.RegisterDialogTheme)

builder.setView(layoutInflater.inflate(R.layout.my_dialog_layout, null))
builder.create().show()


ImageViewを丸くする

view.outlineProvider = object : ViewOutlineProvider() {

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


ボタンを角丸にする

<?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>

<Button

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


文字リソースで値展開

<resources>

<string name="welcom">ようこそ %1$s !</string>
</resources>

val message = getString(R.string.welcom, "太郎")


ActionBarの影を消す

<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>

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

mainAppVarLayout.outlineProvider = object : ViewOutlineProvider() {

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


1秒おきにViewを点滅させる

    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の取得の仕方

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


SearchViewの開閉

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
}


ソフトキーボードを閉じる

if (activity.currentFocus != null) {

val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
imm?.hideSoftInputFromWindow(activity.currentFocus!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}


Dialog

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を同時に使う

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 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>


毎分コールされるインテント

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が必要

class CustomViewModelFactory(private val test: String) : ViewModelProvider.NewInstanceFactory() {  

override fun <T : ViewModel?> create(modelClass: Class<T>?): T {
return LoginViewmodel(test) as T
}

}

val viewModel = ViewModelProviders.of  

(this,CustomViewModelFactory("somerandomvalue")).get(LoginViewmodel::class._java_)


kotlin拡張関数を使いたい場合以下の記述が必要。(@BindingAdapterの記述等

// build.gradle(app:module)

apply plugin: 'kotlin-kapt'


別のアクティビティを開始する

startActivity(Intent(this, SettingsActivity::class.java))


別のアクティビティを開始してデータを受け取る

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
}
}


フラグメントを開始する

<FrameLayout

android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">

</FrameLayout>

val fragmentManager = getSupportFragmentManager()

val fragView = FragmentView.newInstance("", "")
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragView)
.commit()


フラグメントを取得する

val view = supportFragmentManager.findFragmentById(R.id.content_frame) as FragmentView?

if (view is FragmentView) {
view.onEvent()
}


設定値の書き込み・取得

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")


画面回転時に値を保持しておく

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

    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();
}
}
}