Menampilkan dan Membuat Channel dengan Menggunakan Rainbow SDK
Halo, apa kabar teman-teman developer?
Pada tutorial kali ini kita akan membuat sebuah aplikasi yang dapat menampilkan dan membuat Channel dengan menggunakan Rainbow SDK. Nantinya aplikasi yang akan kita buat akan seperti di bawah ini:
💻 Mulai Belajar Pemrograman
Belajar pemrograman di Dicoding Academy dan mulai perjalanan Anda sebagai developer profesional.
Daftar SekarangPembuatan Project
Dalam project kali ini kita akan menulis kode dengan menggunakan bahasa pemrograman Kotlin. Pertama, buat project baru di Android Studio, lalu buka berkas (file) build.gradle (Project) dan tambahkan beberapa baris kode sehingga menjadi seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
buildscript { ext { kotlin_version = '1.3.50' rainbow_version = '1.64.0' androidXVersion = '1.0.0' androidXTestVersion = '1.1.0' androidXAnnotations = '1.0.1' androidXLegacySupport = '1.0.0' materialVersion = '1.0.0' cardVersion = '1.0.0' recyclerViewVersion = '1.1.0' appCompatVersion = '1.0.2' constraintLayoutVersion = "1.1.3" archLifecycleVersion = '2.1.0' archVersion = '1.1.1' glideVersion = '4.9.0' } repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.5.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() maven { url "http://maven.openrainbow.io" } } } task clean(type: Delete) { delete rootProject.buildDir } |
Kemudian ubah baris kode pada berkas build.gradle (App) menjadi seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 buildToolsVersion "29.0.2" defaultConfig { applicationId "com.dicoding.rainbowapi_channel" minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility 1.8 targetCompatibility 1.8 } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.1.0' // Rainbow API SDK implementation "com.ale:rainbowsdk:$rainbow_version" // Dependencies for Android Support implementation "androidx.appcompat:appcompat:$appCompatVersion" implementation "androidx.cardview:cardview:$cardVersion" implementation "com.google.android.material:material:$materialVersion" implementation "androidx.recyclerview:recyclerview:$recyclerViewVersion" implementation "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" implementation "androidx.annotation:annotation:$androidXAnnotations" implementation "androidx.legacy:legacy-support-v4:$androidXLegacySupport" implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion" implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } |
Jika semua sudah disesuaikan dengan project-mu, lakukan sinkronisasi project dengan menekan tombol Sync Now di pojok kanan atas. Kita telah berhasil melakukan import library yang kita butuhkan. Setelah selesai buatlah kelas baru dengan nama App yang akan digunakan untuk inisialisasi Rainbow seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class App : Application() { override fun onCreate() { super.onCreate() RainbowSdk .instance() .initialize( this, "ad0e6660223311eab5828dd44f5e3313", "DsAWuRlXjGXcRLdudjpymiNSI8EkLrUqs7F2S33pysHet1C3kgBMaXBd6osyYXzu" ) } } |
Jangan lupa untuk mendaftarkan kelas tersebut dan menambahkan beberapa permission ke dalam berkas (file) AndroidManifest.xml sehingga berkas menjadi seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.dicoding.rainbowapi_channel"> <application android:name=".app.App" 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=".ui.channel.ChannelListActivity" android:label="Channel" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
Untuk struktur kelas dan package dari project kali ini, akan menjadi seperti berikut :
Komponen Rainbow
Pertama kita akan membuat beberapa kelas yang berguna untuk berinteraksi dengan library Rainbow SDK. Kelas yang pertama kita buat adalah RainbowConnectionListener. Kode pada kelas RainbowConnectionListener akan seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class RainbowConnectionListener { interface Connection { fun onConnectionSuccess() fun onConnectionFailed(error: String) } interface Login { fun onSignInSuccess() fun onSignInFailed(error: String) } } |
Pada kelas RainbowConnectionListener di atas terdapat beberapa interfaces yang akan digunakan sebagai Callback Listener dari kelas berikutnya yaitu RainbowConnection. Isi dari kelas RainbowConnection adalah seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
object RainbowConnection { val rainbowInstance: RainbowSdk get() = RainbowSdk.instance() private val allChannels: List<Channel> get() = RainbowSdk.instance().channels().allChannels.copyOfDataList fun startConnection(connection: RainbowConnectionListener.Connection) { rainbowInstance.connection().start(object : StartResponseListener() { override fun onStartSucceeded() { Handler(Looper.getMainLooper()) .post(connection::onConnectionSuccess) } override fun onRequestFailed(errorCode: RainbowSdk.ErrorCode, s: String) { Handler(Looper.getMainLooper()) .post { connection.onConnectionFailed(s) } } }) } fun startSignIn(email: String, password: String, login: RainbowConnectionListener.Login) { rainbowInstance.connection() .signin(email, password, "sandbox.openrainbow.com", object : SigninResponseListener() { override fun onSigninSucceeded() { Handler(Looper.getMainLooper()) .post(login::onSignInSuccess) } override fun onRequestFailed(errorCode: RainbowSdk.ErrorCode, s: String) { Handler(Looper.getMainLooper()) .post { login.onSignInFailed(s) } } }) } fun registerChannelChangeListener(listener: IItemListChangeListener) = RainbowSdk.instance().channels().allChannels.registerChangeListener(listener) fun unregisterChannelChangeListener(listener: IItemListChangeListener) = RainbowSdk.instance().channels().allChannels.unregisterChangeListener(listener) fun registerAllChannel(listener: Channel.IChannelListener) { for (channel in allChannels) { channel.registerListener(listener) channel.mode = Channel.ChannelMode.ALL_PUBLIC } } fun unregisterAllChannel(listener: Channel.IChannelListener) { for (channel in allChannels) { channel.unregisterListener(listener) channel.mode = Channel.ChannelMode.ALL_PUBLIC } } } |
Di dalam kelas RainbowConnection terdapat beberapa static method dengan detail fungsi sebagai berikut :
- startConnection()
Menjalankan service Rainbow agar fungsi seperti Sign In bisa digunakan.
- startSignIn()
Masuk / Sign In (masuk) ke platform Rainbow.
- getAllChannels()
Mendapatkan daftar semua channel. - registerChannelChangeListener()
Mendaftarkan listener untuk mengetahui perubahan yang terjadi pada channel secara real time. - unregisterChannelChangeListener()
Menghapus listener yang telah didaftarkan. - registerAllChannel()
Mendaftarkan semua listener dari setiap data channel yang telah didapatkan. - unregisterAllChannel()
Menghapus semua listener yang telah didaftarkan.
Penggunaan komponen Handler pada fungsi start() dan fungsi sign() bertujuan agar komponen yang berjalan pada UI Thread bisa dipanggil dan dijalankan. Sebabnya, Callback Listener dari beberapa fungsi Rainbow SDK masih berada pada Background Thread.
Untuk mendapatkan data channel kita menggunakan module pada Rainbow SDK yang detailnya bisa dibaca pada tautan berikut:
https://hub.openrainbow.com/#/documentation/doc/sdk/android/modules/Channels
https://hub.openrainbow.com/#/documentation/doc/sdk/android/objects/Channel
Komponen Adapter
Pertama kita membutuhkan sebuah pager adapter untuk menampilkan setiap halaman. Untuk itu kita akan membuat layout untuk setiap halaman terlebih dahulu seperti berikut:
Halaman all channel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".ui.channel.all.AllChannelFragment"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_all_channel" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingStart="16dp" android:paddingTop="16dp" android:paddingEnd="16dp" android:paddingBottom="30dp" /> <TextView android:id="@+id/tv_all_channel_empty" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:text="No one channel to show" android:visibility="gone"/> </androidx.constraintlayout.widget.ConstraintLayout> |
Halaman subcribed channel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".ui.channel.subscribe.SubscribedChannelFragment"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_subscribed_channel" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingStart="16dp" android:paddingTop="16dp" android:paddingEnd="16dp" android:paddingBottom="30dp" /> <TextView android:id="@+id/tv_subscribed_channel_empty" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:text="No one channel to show" android:visibility="gone"/> </androidx.constraintlayout.widget.ConstraintLayout> |
Halaman owned channel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".ui.channel.owned.OwnedChannelFragment"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_owned_channel" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingStart="16dp" android:paddingTop="16dp" android:paddingEnd="16dp" android:paddingBottom="30dp" /> <TextView android:id="@+id/tv_owned_channel_empty" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:text="No one channel to show" android:visibility="gone"/> </androidx.constraintlayout.widget.ConstraintLayout> |
Ketiga berkas layout membutuhkan widget RecyclerView untuk menampilkan data daftar channel sesuai dengan yang dibutuhkan.
Selanjutnya kita membuat kelas Adapter yang di dalamnya terdapat judul setiap halaman, kelas adapter akan menjadi seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class ChannelListPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getItem(position: Int): Fragment = when (position) { 0 -> AllChannelFragment() 1 -> SubscribedChannelFragment() 2 -> OwnedChannelFragment() else -> throw IllegalArgumentException("Unknown position") } override fun getPageTitle(position: Int): CharSequence = when (position) { 0 -> "All" 1 -> "Subscribe" 2 -> "Owned" else -> throw IllegalArgumentException("Unknown position") } override fun getCount() = 3 } |
Kedua kita akan membutuhkan sebuah adapter untuk menampilkan data tiap kontak. Untuk itu kita akan membuat sebuah layout terlebih dahulu seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView 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:id="@+id/layout_item_channel" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="10dp" android:layout_marginEnd="8dp" app:cardCornerRadius="16dp" app:cardElevation="1dp" app:cardMaxElevation="1dp"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_logo_subscribe" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:src="@drawable/ic_subscribe" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tv_channel_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:textSize="17sp" android:textColor="#000" app:layout_constraintStart_toEndOf="@id/iv_logo_subscribe" app:layout_constraintTop_toTopOf="@id/iv_logo_subscribe" tools:text="Channel Name" /> <TextView android:id="@+id/tv_channel_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:layout_marginTop="5dp" android:textSize="12sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="@id/tv_channel_name" app:layout_constraintTop_toBottomOf="@+id/tv_channel_name" tools:text="Description" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> |
Pada berkas layout di atas memiliki beberapa view yaitu ImageView untuk menampilkan gambar channel dan juga TextView untuk menampilkan nama channel dan deskripsi channel.
Selanjutnya kita membuat kelas Adapter yang di dalamnya terdapat kelas holder yang akan digunakan untuk me-render tampilan aplikasi menjadi seperti berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
class ChannelListAdapter( private val context: Context ) : ListAdapter<Channel, ChannelListAdapter.ChannelViewHolder>( object : DiffUtil.ItemCallback<Channel>() { override fun areItemsTheSame(oldItem: Channel, newItem: Channel): Boolean { return oldItem == newItem } override fun areContentsTheSame( oldItem: Channel, newItem: Channel ): Boolean { return oldItem.id == newItem.id } } ) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelViewHolder { return ChannelViewHolder( LayoutInflater .from(context) .inflate(R.layout.item_channel, parent, false) ) } override fun onBindViewHolder(holder: ChannelViewHolder, position: Int) { holder.bind(getItem(position)) } inner class ChannelViewHolder(view: View) : RecyclerView.ViewHolder(view) { private val textChannel = view.findViewById<TextView>(R.id.tv_channel_name) private val textChannelDescription = view.findViewById<TextView>(R.id.tv_channel_description) fun bind(channel: Channel) { textChannel.text = channel.name textChannelDescription.text = channel.description } } } |
Kelas adapter sendiri akan digunakan untuk menjembatani data yang akan ditampilkan dengan antarmuka aplikasi.
Halaman List Channel
Pada halaman Channel hanya terdapat satu buah widget, yaitu widget RecyclerView dan akan digunakan untuk menampilkan daftar kontak seperti berikut :
activity_channel_list.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout 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=".ui.channel.ChannelListActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay" app:elevation="0dp"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </com.google.android.material.appbar.AppBarLayout> <include layout="@layout/content_main" /> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab_add_channel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" app:srcCompat="@drawable/ic_add_black_24dp" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> |
content_main.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?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" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".ui.channel.ChannelListActivity" tools:showIn="@layout/activity_channel_list"> <com.google.android.material.tabs.TabLayout android:id="@+id/main_tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.viewpager.widget.ViewPager android:id="@+id/pv_channel_list" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/main_tab_layout" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Kemudian pada kelas ChannelListActivity terdapat inisialisasi ChannelListPagerAdapter dan pemanggilan beberapa static method dari kelas RainbowConnection yang sebelumnya sudah dibuat seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
class ChannelListActivity : AppCompatActivity(), RainbowConnectionListener.Connection, RainbowConnectionListener.Login { private lateinit var channelListPagerAdapter: ChannelListPagerAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_channel_list) setSupportActionBar(toolbar) fab_add_channel.hide() channelListPagerAdapter = ChannelListPagerAdapter(supportFragmentManager) pv_channel_list.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { // TODO: will added something later } override fun onPageScrolled( position: Int, positionOffset: Float, positionOffsetPixels: Int ) { // TODO: will added something later } override fun onPageSelected(position: Int) { if (position == 2) fab_add_channel.show() else fab_add_channel.hide() } }) pv_channel_list.offscreenPageLimit = 3 main_tab_layout.setupWithViewPager(pv_channel_list) fab_add_channel.setOnClickListener { //startActivity(Intent(this, AddChannelActivity::class.java)) cretePublicChannel() } RainbowConnection.startConnection(this) } private fun cretePublicChannel() { val name = "Khrisna Channel" val description = "My description" val category = "Global" RainbowConnection.rainbowInstance.channels().createPublicChannel( name, description, category, 100, object : IChannelProxy.IChannelCreateListener { override fun onCreateSuccess(p0: Channel?) { runOnUiThread { Toast.makeText( this@ChannelListActivity, "Create channel success! [$name] ${p0?.mode}", Toast.LENGTH_SHORT ).show() } } override fun onCreateFailed(p0: RainbowServiceException?) { runOnUiThread { Toast.makeText( this@ChannelListActivity, "Create channel failed!", Toast.LENGTH_SHORT ).show() } } } ) } /** val email = "user1@email.com" val password = "Test1_1234" val email = "user2@email.com" val password = "Test2_1234" **/ override fun onConnectionSuccess() { val email = "user1@email.com" val password = "Test1_1234" RainbowConnection.startSignIn(email, password, this) } override fun onConnectionFailed(error: String) { Toast.makeText( this, "Connection to Rainbow API failed: $error", Toast.LENGTH_SHORT ).show() } override fun onSignInSuccess() { pv_channel_list.adapter = channelListPagerAdapter } override fun onSignInFailed(error: String) { Toast.makeText( this, "Sign in to Rainbow API failed: $error", Toast.LENGTH_SHORT ).show() } } |
Pada kelas ChannelListActivity kita juga memiliki fungsi untuk membuat channel baru dengan memanggul fungsi createPublicChannel() untuk membuat channel public. Untuk fungsi-fungsi lainnya dalam membuat channel, silakan pelajari lebih lanjut pada tautan berikut:
https://hub.openrainbow.com/#/documentation/doc/sdk/android/modules/Channels
Berkutnya kita juga perlu membuat beberapa Fragment untuk menampilkan halaman yang sesuai. Kita akan membuat 3 buah fragment yaitu AllChannelFragment, OwnedChannelFragment dan SubscribeChannelFragment. Kode pada masing-masing kelas akan menjadi sebagai berikut:
kelas AllChannelFragment:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
class AllChannelFragment : Fragment(), Channel.IChannelListener { private lateinit var channelListAdapter: ChannelListAdapter private val channelChangeListener = IItemListChangeListener { RainbowConnection.registerAllChannel(this) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_all_channel, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) channelListAdapter = ChannelListAdapter(activity as ChannelListActivity) rv_all_channel.setHasFixedSize(true) rv_all_channel.layoutManager = LinearLayoutManager(context) rv_all_channel.adapter = channelListAdapter RainbowConnection.registerChannelChangeListener(channelChangeListener) } override fun onUpdate() { activity?.runOnUiThread { val channels = RainbowContext.getInfrastructure().channelMgr.tenBestChannels if (channels.isNotEmpty()) { channelListAdapter.submitList(channels) tv_all_channel_empty.visibility = View.GONE } else { tv_all_channel_empty.visibility = View.VISIBLE } } } override fun onDestroy() { super.onDestroy() RainbowConnection.unregisterChannelChangeListener(channelChangeListener) RainbowConnection.unregisterAllChannel(this) } } |
Pada kelas AllChannelFragment kita akan mengambil data theBestChannel sebagai contoh yang akan menampilkan 10 data channel terpopuler.
Kelas OwnedChannelFragment:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
class OwnedChannelFragment : Fragment(), Channel.IChannelListener { private lateinit var channelListAdapter: ChannelListAdapter private val channelChangeListener = IItemListChangeListener { RainbowConnection.registerAllChannel(this) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_owned_channel, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) channelListAdapter = ChannelListAdapter(activity as ChannelListActivity) rv_owned_channel.setHasFixedSize(true) rv_owned_channel.layoutManager = LinearLayoutManager(context) rv_owned_channel.adapter = channelListAdapter RainbowConnection.registerChannelChangeListener(channelChangeListener) } override fun onUpdate() { activity?.runOnUiThread { val channels = RainbowSdk.instance().channels().allOwnedChannels if (channels.isNotEmpty()) { channelListAdapter.submitList(channels) tv_owned_channel_empty.visibility = View.GONE } else { tv_owned_channel_empty.visibility = View.VISIBLE } } } override fun onDestroy() { super.onDestroy() RainbowConnection.unregisterChannelChangeListener(channelChangeListener) RainbowConnection.registerAllChannel(this) } } |
Pada kelas OwnedChannelFragment diatas akan mengambil data daftar channel yang kita miliki.
kelas SubscribedChannelFragment:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class SubscribedChannelFragment : Fragment(), Channel.IChannelListener { private lateinit var channelListAdapter: ChannelListAdapter private val channelChangeListener = IItemListChangeListener { RainbowConnection.registerAllChannel(this) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_subscribed_channel, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) channelListAdapter = ChannelListAdapter(activity as ChannelListActivity) rv_subscribed_channel.setHasFixedSize(true) rv_subscribed_channel.layoutManager = LinearLayoutManager(context) rv_subscribed_channel.adapter = channelListAdapter RainbowConnection.registerChannelChangeListener(channelChangeListener) } override fun onUpdate() { activity?.runOnUiThread { val channels = RainbowSdk.instance().channels().allSubscribedChannels if (channels.isNotEmpty()) { channelListAdapter.submitList(channels) tv_subscribed_channel_empty.visibility = View.GONE } else { tv_subscribed_channel_empty.visibility = View.VISIBLE } } } override fun onDestroy() { super.onDestroy() RainbowConnection.unregisterChannelChangeListener(channelChangeListener) RainbowConnection.unregisterAllChannel(this) } } |
Terakhir pada kelas SubscribedChannelFragment akan menampilkan semua channel yang telah kita subscribe.
Setelah selesai, jalankan project kamu. Jika semua berjalan sempurna, tampilan aplikasi akan seperti berikut:
Sekian tutorial menampilkan dan membuat Channel dengan menggunakan Rainbow SDK. Semoga artikel ini bermanfaat buatmu.
Jika ada pertanyaan, silakan tinggalkan komentar di halaman blog ini. Kami akan membantumu!
Menampilkan dan Membuat Channel dengan Menggunakan Rainbow SDK- end
Simak artikel terkait: