6 Temmuz 2020 Pazartesi

Kotlin-12 (Android Kotlin Local Notification - Kotlin ile lokal bildirim)

Merhaba,
bu yazı Kotlin ile geliştirilen bir Android uygulamasında lokal bildirimin(notification) nasıl gönderileceği paylaşılmıştır. İlk adımda bir Android projesi oluşturularak uygulamaya bir buton eklenmiştir. Bu butona basınca lokal bildirim tetiklenerek hayata geçirilmiştir. Aşağıdaki adımları takip ederek projenize lokal bildirimi uygulayabilirsiniz.

İlk olarak Android Studio ile bir Android projesi oluşturun.

activity_main.xml e Button ekleyin. Bu butona tıklayınca local bildirim tetiklenecektir. activity_main.xml dosyasının içeriği aşağıdaki gibi olacaktır. 


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<Button
android:id="@+id/notificationBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create Notification"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 ikinci adımda ise "src/main/res/mipmap" dizinine "mipmap-xhdpi/notify.png" adında bir bildirim iconu eklenmiştir.

Son adım işlemleri ise "MainActivity.kt" class'ında olacaktır. Bildirim tetikleyecek olan button'a onClickListener set edilir. NotificationBuilder ile bildirimin başlık, açıklama icon gibi bilgileri doldurulur. NotificationChannel üzerinden titreşim ve renk bilgileri tanımlanır. Son aşamada NotificationManager'ın notify(...) methodu çağrılarak bildirim tetiklenir. MainActivity.kt dosyasının içeriği aşağıdaki gibi olacaktır.



class MainActivity : AppCompatActivity() {

lateinit var manager: NotificationManager
lateinit var channel: NotificationChannel
lateinit var notificationBuilder: Notification.Builder

private val channelId: String = "com.tutorials.localnotification"
private val description: String = "Notification Sample Description"
private val notoficationId = 1001
private val requestCode = 1002

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

manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

notificationBtn.setOnClickListener {

val intent = Intent(this, LauncherActivity::class.java)
val pendingIntent = PendingIntent
.getActivity(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)


val notificationTitle = "some notification title"
val notificationContent = "some notification text"

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//auto generated by idea
channel = NotificationChannel(channelId, description,
NotificationManager.IMPORTANCE_HIGH)
channel.enableLights(true)
channel.lightColor = Color.BLUE
channel.enableVibration(true)

manager.createNotificationChannel(channel)

notificationBuilder = Notification.Builder(this, channelId)
.setContentTitle(notificationTitle)
.setContentText(notificationContent)
.setSmallIcon(R.mipmap.notify)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.notify))
.setContentIntent(pendingIntent)
} else {
notificationBuilder = Notification.Builder(this)
.setContentTitle(notificationTitle)
.setContentText(notificationContent)
.setSmallIcon(R.mipmap.notify)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.mipmap.notify))
.setContentIntent(pendingIntent)
}

manager.notify(notoficationId, notificationBuilder.build())
}
}
}

 


NOT1: NotificationManager, NotificationChannel ve NotificationBuilder lateinit olarak tanımlanmıştır. Bu class lar ButtonClick işleminden sonra initialize edilecektir.



lateinit var manager: NotificationManager
lateinit var channel: NotificationChannel
lateinit var notificationBuilder: Notification.Builder

 

 

NOT2: API versiyon 26 ve üzeri için NotificationBuilder deprecate edilmiştir. Dolayısıyla uygulamada 26 versiyon öncesi ve sonrası için ayrı işlem yapılmıştır.



if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//auto generated by idea
//...
notificationBuilder = Notification.Builder(this, channelId)
.setContentTitle(notificationTitle)
.setContentText(notificationContent)
.setSmallIcon(R.mipmap.notify)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.notify))
.setContentIntent(pendingIntent)
} else {
notificationBuilder = Notification.Builder(this)
.setContentTitle(notificationTitle)
.setContentText(notificationContent)
.setSmallIcon(R.mipmap.notify)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.mipmap.notify))
.setContentIntent(pendingIntent)
}


 

uygulamanın kaynak kodlarına aşağıdan erişebilirsiniz.
github: https://github.com/lvntyldz/tutorials/tree/master/kotlin-android-app-examples/12-local-notification




3 Temmuz 2020 Cuma

Kotlin-11 (Android Kotlin Play Sound - Kotlin ile ses oynatma)

Merhaba,

bu yazıda Kotlin ile geliştirilen bir Android uygulamasında nasıl ses çalınacağı(oynatılacağı) paylaşılmıştır.

 

İlk olarak Android Studio ile Kotlin destekli bir Android projesi oluşturulur.

 

Uygulamada kullanılacak ses tonu dosyası "res/raw/" dizini altına "alert.mp3" olarak eklenir.

 

layout/activity_main.xml dosyası LinearLayut'a dönüştürülerek içine bir Button eklenir. Bu butona tıklayınca ses dosyası oynatılacaktır.

layout/activity_main.xml dosyasının içeriği aşağıdaki gibi olacaktır.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".MainActivity">

<Button
android:id="@+id/playSoundBtn"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Play" />

</LinearLayout>

 

  

Son adımda "MainActivity.kt" dosyasına gidilerek activity_main.xml'e eklenen Button'a clickEventListener eklenir.

Button'a tıklanınca ses dosyasını oynatması için bir MediaPlayer nesnesi oluşturularak start edilir.

MainActivity.kt dosyasının son hali aşağıdaki gibi olmalıdır.

 


class MainActivity : AppCompatActivity() {
var mediaPlayer: MediaPlayer? = null

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

playSoundBtn.setOnClickListener {

mediaPlayer = MediaPlayer.create(this, R.raw.alert)
mediaPlayer?.start()
}
}
}



NOT: R.raw.alert ile MediaPlayer'a ses dosyasının bulunduğu yol parametre olarak geçilmiştir. 


Uygulamanın kaynak kodlarına aşağıdaki linkten ulaşabilirsiniz.

Github : https://github.com/lvntyldz/tutorials/tree/master/kotlin-android-app-examples/11-play-sound

 

 

Kotlin-10 (Android Kotlin Camera - Kotlin ile camera görüntüsü alma)

Merhaba,

bu yazım Kotlin ile uygulama üzerinden kamera' ya erişim ve kamera görüntüsü almayla alakalı olacaktır.

Android ile uygulama geliştirirken varsayılan durumda dosya sistemine ve kameraya erişim kapalı olarak gelmektedir. Uygulamada kamera ile alakalı bir işlem yapılacaksa uygulamanın beyni olarak adlandırabileceğimiz AndroidManifest.xml dosyası üzerinden kameraya ve external storage'a erişim yetkisi tanımlanmalıdır. Bu tanımlama sonrasında yazılacak birkaç satır kod ile harici(3rd) kütüphane kullanmadan Kotlin ile kamera görüntüsü alınabilmektedir. Aşağıdaki adımları takip ederek geliştirdiğiniz uygulamada kamera ile görüntü alabilirsiniz.

 

İlk olarak Android Studio ile kotlin destekli bir Android uygulaması oluşturun.

 

Uygulamada kamerayı açmak ve kameradan alınacak görüntüyü kullanıcıya göstermek için birer Button ve  ImageView'a ihtiyaç olacaktır. ImageView ve Button'u layout/activity_main.xml dosyasına ekleyin.

layout/activity_main.xml dosyasının son hali aşağıdaki gibi olmalıdır.



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">

<ImageView
android:id="@+id/cameraImage"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="center"
android:src="@drawable/ic_launcher_background" />

<Button
android:id="@+id/imageCaptureBtn"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="capture image" />

</LinearLayout>

 

 

Üstte bahsedilen camera ve disk erişimi yetkileri için ise  AndroidManifest.xml dosyasına android.permission.CAMERA ve android.permission.WRITE_EXTERNAL_STORAGE izinlerini ekleyin.

AndroidManifest.xml dosyasının son hali aşağıdaki gibi olacaktır.



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutorials.cameraimage">

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
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>


  

Son adım olarak ta MainActivity.kt class'ına giderek birkaç satır kotlin koduna ihtiyaç duyulacaktır. Burada imageCaptureBtn'a onClickListner set edilerek kullanıcının kamera açma isteği algılanacaktır. Button'a tıklandıktan sonra camera erişimi olup olmadığı kontrol edilecektir. Eğer erişim verilmemişse kullanıcı gereken yetkileri vermesi için Toast mesajı ile bilgilendirilecektir. Bu erişim yetkisi isteme işlemi BuildVersion (API) 23 ve üzeri için geçerlidir. Dolayısıyla kodlamada BuildVersion kontrolü yapılarak ilerlenmiştir.

 

MainActivity.kt dosyasının son hali aşağıdaki gibi olacaktır.



class MainActivity : AppCompatActivity() {

val PERMISSION_CODE: Int = 12345
val IMAGE_CAPTURE_CODE: Int = 12346
var imageUri: Uri? = null

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

imageCaptureBtn.setOnClickListener {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.CAMERA)
== PackageManager.PERMISSION_DENIED
|| checkSelfPermission(
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_DENIED
) {
val permission = arrayOf(
android.Manifest.permission.CAMERA,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
)

requestPermissions(permission, PERMISSION_CODE)
} else {
openCamera()
}

} else {
//api<23
openCamera()
}
}
}

private fun openCamera() {
val contentValues = ContentValues()
contentValues.put(MediaStore.Images.Media.TITLE, "imageTitle")
imageUri =
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(intent, IMAGE_CAPTURE_CODE)
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSION_CODE -> {

if (grantResults.size > 0 && grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
Toast.makeText(this,
R.string.permission_denied_msg, Toast.LENGTH_SHORT).show()
}

}
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
cameraImage.setImageURI(imageUri)
}
}
}


 

Bu aşamalardan sonra uygulama ilk çalıştığında tanımlı izinler için kullanıcıdan onay isteyecektir. Gereken izinleri vererek uygulamayı test edebilirsiniz.


NOT1: Activity'nin onRequestPermission methodu override edilerek camera erişimi için gereken izin alınıp alınmadığı kontrol edilmiştir. İzin varsa camera açılmış yoksa kullanıcıya izin vermesi için mesaj gösterilmiştir. Bu işlemleri yapan kod bloğu aşağıdadır.



when (requestCode) {
PERMISSION_CODE -> {

if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
Toast.makeText(this, R.string.permission_denied_msg, Toast.LENGTH_SHORT).show()
}

}
}

 


 

NOT2: Yine FragmentActivity'nin onActivityResult methodu override edilerek kamera görüntüsü alıntıktan sonra işlemin başarılı bir şelikde snuçlandığından emin olunarak camera görüntüsü kullanıcıya gösterilmek üzere  ekrandaki ImageView'a set edilmiştir. Bu işlemleri gerçekleştiren kotlin satırları aşağıdadır.



if (resultCode == Activity.RESULT_OK) {
cameraImage.setImageURI(imageUri)
}

 


  

Uygulamanın kaynak kodlarına aşağıdaki linkten erişebilirsiniz.

github: https://github.com/lvntyldz/tutorials/tree/master/kotlin-android-app-examples/10-camera-image 

 

 

Kotlin-9 (Android Kotlin ProgressBar - Kotlin ile ProgressBar gösterimi)

Herkse merhaba,

bu yazımda Kotlin ile ProgressBar gösterimini paylaşacağım.

 

İlk adım olarak Android Studio ile Kotlin destekli bir Android projesi oluşturun.

 

layout/activity_main.xml dosyasına geçerek buraya bir ProgressBar componenti ekleyin. ProgressBar'ın ilerleme statüsünü gösteren bir TextView ve ProgressBar'ı tetiklemek için bir Button ekleyin.

Dosyanın son hali aşağıdaki gibi olacaktır.



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ProgressBar
android:id="@+id/progressBarComp"
style="?android:attr/progressBarStyle"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:layout_marginLeft="70dp"
android:layout_marginTop="150dp"
android:indeterminate="true"
android:max="100"
android:minWidth="200dp"
android:minHeight="100dp"
android:progress="0"
android:visibility="invisible" />

<TextView
android:id="@+id/progressBarStatusText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/progressBarComp"
android:layout_alignLeft="@+id/progressBarComp" />

<Button
android:id="@+id/startProgressBtn"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_below="@+id/progressBarStatusText"
android:layout_alignStart="@+id/progressBarComp"
android:layout_alignEnd="@+id/progressBarComp"
android:layout_centerHorizontal="true"
android:layout_marginStart="2dp"
android:layout_marginTop="21dp"
android:layout_marginEnd="-2dp"
android:gravity="center"
android:text="Progress Bar" />
</RelativeLayout>

 

  

MainActivity.kt class'ına  giderek ProgressBar için bir setOnClickListener tanımlayın. Daha sonra butona tıklayınca ekranda ProgressBar'ın görünmesi için             progressBarComp.setVisibility(View.VISIBLE) satırını ekleyin. Farklı bir thread de ProgressBar'ın statüsünü 1 saniye aralıkla beşer beşer artırın. Handler().post(...) methodu aracılığıyla main thread deki textView'a erişerek ProgressBar değerini ekrana basın. Son olarak ProgressBar ilerleme değeri 100 olduğunda ProgressBar'ın görünürlüğünü kapatın(progressBarComp.setVisibility(View.INVISIBLE)).

 

MainActivity.kt dosyasının son hali aşağıdaki gibi olacaktır.



class MainActivity : AppCompatActivity() {

private var i = 0
private val handler = Handler()

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

startProgressBtn.setOnClickListener {

progressBarComp.setVisibility(View.VISIBLE)

i = progressBarComp!!.progress

Thread(Runnable {

while (i < 100) {
i += 5
handler.post(Runnable {
progressBarComp!!.progress = i
progressBarStatusText!!.text = i.toString() + "/" + progressBarComp!!.max
})
try {
Thread.sleep(100)
} catch (e: InterruptedException) {
e.printStackTrace()
}

}

if (i == 100) {
progressBarComp.setVisibility(View.INVISIBLE)
}

}).start()


}
}
}

 

 

Uygulamanın kaynak kodlarına aşağıdan erişebilirsiniz.

Github :https://github.com/lvntyldz/tutorials/tree/master/kotlin-android-app-examples/09-progressbar 


Kotlin-8 (Android Kotlin DatePicker & TimePicker - Kotlin ile Tarih Saat Diyaloğu)

Merhaba,

bu yazımda Android uygulamasında Kotlin ile DatePicker ve TimePicker nasıl ekleneceğini paylaşacağım. Aslında Android projelerinin içinde  hazır komponent şeklinde DatePicker ve TimePicker bulunmaktadır. Ancak burada geliştirilen uygulamada kotlin ile programatik bir şekilde DatePicker ve TimePicker diyaloğu örneklenmiştir. Uygulamada iki adet buton eklenmiştir. Bu butonlara basınca DatePicker ve TimePicker diyalog şeklinde gösterilmektedir. Daha sonra kullanıcın seçimi activity_main.xml'e eklenen textView lar aracılığıyla yine ekranda gösterilmektedir.

 

İlk olarak Android Studio aracılığıyla bir Kotlin projesi oluşturun.

 

Öncelikli olarak oluşturulan projede  activity_main.xml dosyasını LinearLayout olarak düzenleyin. Bu sayede ekrana eklenen componentler blok şeklinde gösterilecektir. activity_main.xml dosyasına 2 adet TextView ve 2 adet Button ekleyin. Butonlara tıklayınca DatePicker ve TimePicker açılacak, TextView larda ise seçilen değerler gösterilecektir.

activity_main.xml dosyasının içeriği aşağıdaki gibi olmalıdır.



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">

<TextView
android:id="@+id/dateTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="30dp" />

<TextView
android:id="@+id/timeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="30dp" />

<Button
android:id="@+id/changeDateBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Date" />

<Button
android:id="@+id/changeTimeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Time" />

</LinearLayout>


 

Uygulamanın sonraki adımlarında MainActivity.kt dosyasına geçilerek onCreate methodunda Date ve Time picker için TextView üzerinde varsayılan değer verilmiştir.



dateTextView!!.text = "--/--/----"
timeTextView!!.text = "--:--"

 

  

Yine hem TimePicker hem de DatePicker butonları için setOnClickListener methodları tanımlanarak içerisinde DatePicker ve TimePicker'ın dialog olarak gösterimi sağlanmıştır.

 

 DatePickerDialog.OnDateSetListener ile kullanıcının seçtiği tarih değeri alınarak TextView da gösterilmiştir.

 TimePickerDialog.OnTimeSetListener methodu ile de kullanıcının seçtiği zaman değeri yine TextView da gösterilmiştir.

 

MainActivity.kt dosyasının son hali aşağıdaki gibi olacaktır.



class MainActivity : AppCompatActivity() {

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

dateTextView!!.text = "--/--/----"
timeTextView!!.text = "--:--"

val now = Calendar.getInstance()

changeDateBtn.setOnClickListener {
val datePicker = DatePickerDialog(this,
DatePickerDialog.OnDateSetListener { view, year, month, dayOfMonth ->
dateTextView!!.text = "$dayOfMonth/$month/$year"
},
now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH)
)
datePicker.show()
}

changeTimeBtn.setOnClickListener {

val timePicker = TimePickerDialog(this,
TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute ->
timeTextView!!.text = "$hourOfDay:$minute"
},
now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), false)
timePicker.show()

}

}
}


 

 uygulamanın kaynak kodlarına aşağıdaki linkten ulaşabilirsiniz.

github: https://github.com/lvntyldz/tutorials/tree/master/kotlin-android-app-examples/08-date-time-picker 


Kotlin-7 (Android Kotlin GridView(Api Response) - Kotlin ile API'den veri alınıp GridView üzerinde gösterilmesi)

 

Herkese merhaba,

bu yazımda Kotlin ile bir API den veri okuyarak GridView üzerinden nasıl listeleneceiğini paylaşacağım.

 

İlk olarak Android Studio ile bir Kotlin projesi oluşturun.

Ardından uygulamanın internete çıkabilmesi için AndroidManifest.xml dosyasına gereken tanımlamayı yapın. Dosyanın son hali aşağıdaki gibi olmalıdır.



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutorials.apiresponsegridview">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
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> 


 

API den dönecek olan response'ları dönüştürmek için Photo.kt adında bir class file oluşturun.

Photo.kt class'ı aşağıdaki gibi olmalıdır.



class Photo {

var albumId: Int? = null
var id: Int? = null
var title: String? = null
var url: String? = null
var thumbnailUrl: String? = null

override fun toString(): String {
return "Photo(albumId=$albumId, id=$id, title=$title," +
" url=$url, thumbnailUrl=$thumbnailUrl)"
}
}

 

  

Photo objelerini bir list halinde GridView'e verebilmek için PhotoAdapter.kt adında bir class oluşturun.

PhotoAdapter.kt class'ının içeriği aşağıdaki gibi olmalıdır.



class PhotoAdapter : BaseAdapter {

var context: Context? = null
var photos = ArrayList<Photo>();

constructor(context: Context?, photos: ArrayList<Photo>) {
this.context = context
this.photos = photos
}

override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var photo = this.photos[position]

var inflator = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
var photoView = inflator.inflate(R.layout.photo_content, null)
photoView.image.setImageResource(R.drawable.ic_launcher_background)
photoView.title.setText(photo.title!!)

Picasso.get()
.load(photo.url)
.resize(150, 150)
.centerCrop()
.into(photoView.image)


return photoView
}

override fun getItem(position: Int): Any {
return photos[position]
}

override fun getItemId(position: Int): Long {
return position.toLong()
}

override fun getCount(): Int {
return photos.size
}
}

 

 

activity_main.xml dosyası içerisine bir GridView ekleyin. Dosyasın son hali aşağıdaki gibi olmalıdır.



<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<GridView
android:id="@+id/photosGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="150dp"
android:horizontalSpacing="15dp"
android:numColumns="auto_fit"
android:verticalSpacing="15dp" />

</androidx.constraintlayout.widget.ConstraintLayout>


 

activity_main.xml dosyasının yanına  GridView içeriği olması için photo_content.xml adında bir xml dosyası oluşturun. Bu xml dosyası  LinearLayout içinde bir TextView ve bir ImageView barındıracaktır.

photo_content.xml dosyasının son hali aşağıdaki gibi olacaktır.



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:background="#ddd"
android:gravity="center"
android:orientation="vertical"
android:padding="15dp">

<ImageView
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
/>

<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20sp" />
</LinearLayout>

 

 

Tüm bu adımlardan sonra MainActivity'e giderek onCreate methodunda çağrılmak üzere bir doApiCall(...) methodu oluşturun. Bu method içerisinde varsayılan olarak asenkron bir şekilde yapılan HttpRequest ler countDownLatch.await() ile senkron hale getirilmiştir.

MainActivity.kt dosyasının son hali aşağıdaki gibi olmalıdır.



class MainActivity : AppCompatActivity() {
var adapter: PhotoAdapter? = null
var photos = ArrayList<Photo>()

private val client = OkHttpClient()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doApiCall("https://jsonplaceholder.typicode.com/albums/1/photos")

adapter = PhotoAdapter(this, photos)

photosGridView.adapter = adapter
}

fun doApiCall(url: String) {
val request = Request.Builder().url(url).build()

val countDownLatch = CountDownLatch(1)
client.newCall(request).enqueue(object : Callback {

override fun onFailure(call: Call, e: IOException) {
println("Error! e : ${e.message} ")
countDownLatch.countDown();
}

override fun onResponse(call: Call, response: Response) {

println("Success...")

val responseStr = response.body?.string()
val photoList: List<Photo> =
Gson().fromJson(responseStr, Array<Photo>::class.java).toList()

println("photo : $photoList")

photos = photoList as ArrayList<Photo>
countDownLatch.countDown();
}
})

countDownLatch.await();
}
}


 

uygylamanın kaynak kodlarına aşağıdaki linkten erişebilirsiniz.

github: https://github.com/lvntyldz/tutorials/tree/master/kotlin-android-app-examples/07-api-response-grid-view