1. 程式人生 > >Kotlin程式設計開發Android運用程式(Volley+Gson依賴庫)

Kotlin程式設計開發Android運用程式(Volley+Gson依賴庫)

Kotlin程式設計開發Android運用程式的相關介紹

image

在2017年Google IO大會中,宣佈Kotlin 作為官方語言。跟著黨走總沒錯的想法,開始滿懷激情的開始Kotlin之旅。

歷經一個下午的探索Kotlin程式設計後。昨晚按耐不住激動心情,邊摸石頭邊過河的方式,花了一個晚上時間,擼了本專案程式碼。過完一段時間的後,Kotlin理解提高了,再回頭看下本專案,肯定是左右嫌棄的,但是這畢竟是本人的第一個Kotlin專案。

1. AndroidStudio支援Kotlin的配置

若是使用的AndroidStudio3.0以下,是預設不支援Kotlin語言的,需要自行配置。

Androistudio 3.0以上是自帶支援Kotlin。

2. 在Gralde中新增依賴庫

注意點:這裡展示的專案已經支援Kotlin編寫,在Project的Gralde 和Moudle的Gralde已經有Kotlin配置。

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support'
, module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support:recyclerview-v7:25.3.1' testCompile 'junit:junit:4.12' compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
//官方框架 compile 'com.android.volley:volley:1.0.0' compile 'com.google.code.gson:gson:2.8.0' }

3. 根據需求開始用Kotlin編寫

使用AndroidStudio怎麼建立Kotlin檔案或者專案,請閱讀 Kotlin程式設計之AndroidStudio使用

專案需求

  • 在豆豌API中搜索導演的電影
  • 在裡列表中載入電影

實現

  • Kotlin語言編寫
  • Volley+Gson官方框架非同步載入和解析
  • RecyclerView中顯示電影

根據分析,開始編寫程式碼

1. 編寫Volley的單例操作類

  • object關鍵字宣告單例類

  • lateinit關鍵字宣告宣告一個非空變數,好處不需要設定初始值。

  • lazy() 延遲屬性,同步的產生一個單個物件。

  • Val關鍵字宣告一個只讀物件,Var關鍵字宣告一個可寫物件。

  • 注意點: 建立物件不需要使用Java中new關鍵字。

/***
 *  object 用於單例模式
 *
 *  object宣告物件名後,通過物件名來訪問,但是不能使用 = 右邊賦值。
 *
 */
object  VolleySingletion{
    /**
     * lateinit 宣告一個非空變數,且不需要設定初始值。
     */
    private lateinit  var context:Context

    /**
     *  這裡使用 延遲屬性(lazy properties):首次訪問時計算結果,以後再次訪問時候,將拷貝第一次記錄的結果。
     *
     *
     *   使用形式: var p: String by lazy {   }
     *
     *   lazy()返回一個lazy<T> 的 T 物件.
     *
     *   注意點: lazy屬性的計算結果的過程是同步鎖的(synchronized)。
     *
     *   作用: 單例物件
     */
    val  requestQueque :RequestQueue by lazy {
        Volley.newRequestQueue(context)
    }

    val  imageLoader :ImageLoader by lazy {
        // 不需要呼叫  new  關鍵字才建立物件
        ImageLoader(requestQueque,LruBtimapCache() )
    }

    fun  initConfi(context:Context){
        this.context =context.applicationContext
    }

}

2. 編寫ImageLoader需要用到的LruCache

  • 一個類繼承父類和實現介面的方式 : class 類名 :超類名(),介面名

  • LruBitmapCache主建構函式中,指定引數型別為Int,同時也指定一個預設值。

  • LruBitmapCache帶有主建構函式,因此超類(這裡是LruCache)必須在主建構函式中初始化。

  • Companion關鍵字,修飾伴生物件。伴生物件類名,可以省略
/***
 *   LruBitmapCache主建構函式中,指定一個預設值。
 *
 *   LruBitmapCache帶有主建構函式,因此超類(這裡是LruCache)必須在主建構函式中初始化。
 *
 */
class LruBtimapCache (size: Int= defaultSize ): LruCache<String,Bitmap>(size) ,ImageLoader.ImageCache{

    override fun getBitmap(url: String): Bitmap ?{
        return get(url)
    }
    override fun putBitmap(url: String?, bitmap: Bitmap?) {
        put(url,bitmap)
    }
    override fun sizeOf(key: String, value: Bitmap): Int {
        return   value.rowBytes*value.height/1024
    }
    /**
     * 使用Companion關鍵字,伴生物件類名,可以省略。
     */
    companion object{
        /**
         *  val宣告一個只讀的變數
         *
         */
         val  defaultSize: Int get() {
             val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
             val cacheSize = maxMemory / 8
             return cacheSize
         }
    }
}

3. 編寫自定義的Application:

  • override關鍵字用於複寫超類或者介面中存在的方法
class BaseApplication :Application(){
    override fun onCreate() {
        super.onCreate()
        //初始化Volley配置
        VolleySingletion.initConfi(this)
    }
}

在AndroidManifest.xml中配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xingen.kotlindemo">
   //聯網許可權
    <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:name=".BaseApplication"  //使用自定義的Application
        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>

4. 編寫實體類

這裡也存在一個點疑問:data關鍵字修飾資料物件,但是必須帶有主構造器函式。
因此,這裡並未使用data修飾資料物件。

  • 型別後面帶有?是允許該物件為空
//https://api.douban.com/v2/movie/search?q=張藝謀,返回的資料結構。
class MovieList {

    lateinit var subjects: List<Movie>

    class Movie {
       lateinit var year: String
        var title: String? = null
        var id: String? = null
        lateinit  var images: Images

        class Images {
            var small: String?= null

            var large: String? = null
        }
    }
}

5. 編寫RecyclerView的Adapter

  • this引用是最內層的物件,若是引用外層物件,需要使用[email protected]類名

  • 除開下文的初始化全域性變數方式外,還可以在主建構函式中宣告型別的方式

class ImageListAdapter(movieList: List<MovieList.Movie>) : RecyclerView.Adapter<ImageListAdapter.ViewHolder>() {
    /**
     * 指定一個全域性的變數,從主建構函式中獲取到引數,進行初始化
     */
    var list = movieList

    /**
     * 載入的數量
     */
    override fun getItemCount(): Int {
        return list.size
    }

    /**
     * 建立 ViewHolder
     */
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

        var rootView = View.inflate(parent.context, R.layout.item_imagelist_layout, null)

        return ViewHolder(rootView)
    }

    /**
     *  繫結ViewHolder,進行載入資料
     */
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.loadImage(position)
    }
    /**
     *  inner修飾內部類
     */
    inner class ViewHolder(var rootView: View) : RecyclerView.ViewHolder(rootView) {

        /**
         * 構建一個載入資料的方法,引數為RecyclerView中的當前的位置
         */
        fun loadImage(position: Int) {
            var iv = rootView.findViewById(R.id.imagelist_iv) as NetworkImageView
            var title = rootView.findViewById(R.id.imagelist_title) as TextView

            /**
             *  [email protected]類名的方式,拿到需要對應類的this指向。
             */
            var  adapter=this@ImageListAdapter
            /**
             *   NetWorkImageView開始載入圖片
             */
            iv.setDefaultImageResId(R.mipmap.ic_launcher)
            iv.setErrorImageResId(R.mipmap.ic_launcher)
            iv.setImageUrl(adapter.list[position].images.large,VolleySingletion.imageLoader)

            title.text=adapter.list[position].title
        }
    }
}

6. 編寫MainActivity,進行傳送請求和更新資料

/**
 *  一個類繼承父類和實現介面的方式; class 類名 :超類名(),介面名
 */
class MainActivity : AppCompatActivity() {
    /**
     * override用於覆寫繼承父類或者實現介面中方法。
     *
     * fun 用於標識方法
     *
     * 引數形式: 引數名: 型別
     *
     *  ? 是用於指定可以為空物件
     *
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        shwoDiaglog()
        this.initView()
        this.sendRequest()

    }

    lateinit var recyclerView: RecyclerView
    /**
     * 初始化控制元件
     */
    fun initView() {
        recyclerView = this.findViewById(R.id.main_recycler_view) as RecyclerView
    }

    /**
     *  將網路資料載入到RecyclerView
     */
    fun loadData(movieList: List<MovieList.Movie>) {
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = ImageListAdapter(movieList)
    }

   lateinit var progressDialog: ProgressDialog
    /**
     * 顯示dialog
     */
    fun shwoDiaglog() {
        progressDialog = ProgressDialog(this)
        progressDialog.show()
    }

    /**
     * 取消dialog
     */
    fun cancleDialog() {
        progressDialog.dismiss()
    }

    /**
     * Toast顯示
     */

    fun loadToast(content: String?) {
        Toast.makeText(this, content, Toast.LENGTH_SHORT).show()
    }

    /**
     * 傳送請求,這裡使用douban公開的搜尋電影的API
     */
    fun sendRequest() {
        var url = "https://api.douban.com/v2/movie/search?q=張藝謀"

        val request = StringRequest(url, Response.Listener<String> {
            response -> 

            //請求成功,Gson解析json
            var movilist = Gson().fromJson(response, MovieList::class.java)
            loadData(movilist.subjects)
            cancleDialog()

        }, Response.ErrorListener {
            error -> 

            loadToast(error.message)
            cancleDialog()
        })
        // 單利類中物件的引用
        VolleySingletion.requestQueque.add(request)
    }
}

activity_main.xml程式碼如下:

<android.support.constraint.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="com.xingen.kotlindemo.MainActivity">

  <android.support.v7.widget.RecyclerView
      android:id="@+id/main_recycler_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

  </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

item_imagelist_layout.xml程式碼如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp">
    <com.android.volley.toolbox.NetworkImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:id="@+id/imagelist_iv"/>
    <TextView
        android:layout_width="wrap_content"
        android:id="@+id/imagelist_title"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="20dp"
        android:layout_height="wrap_content" />

</LinearLayout>

專案的最終目錄結構,如下:

這裡寫圖片描述

專案執行結果

這裡寫圖片描述

資源參考:

相關推薦

Kotlin程式設計開發Android運用程式Volley+Gson依賴

Kotlin程式設計開發Android運用程式的相關介紹: 在2017年Google IO大會中,宣佈Kotlin 作為官方語言。跟著黨走總沒錯的想法,開始滿懷激情的開始Kotlin之旅。 歷經一個下午的探索Kotlin程式設計後。昨晚按耐不住激

求職:上海 設計/程式設計開發類研發職位 設計自動化/設計優化

Dr. Ing. 白途思(Begtostudy) 微訊號:Begtostudy QQ:370566617 Email: [email protected] 點選這裡給我發郵件 工作單位:上海航天技術研究院 身份:上海交通大學 工學博士 校內名片

linux 核心模組程式設計之LED驅動程式

我使用的是tiny6410的核心板,板子如下,淘寶可以買到 為了不與板子上的任何驅動發生IO衝突,我使用CON1那一排沒用到的IO口,引腳如下   LED1 LED2 LED3 LED4

安卓程式與設計 app開發 校園點餐類似餓了麼

     大二上學期選了《安卓程式與設計》這門課,看了《安卓應用開發教程》視訊書籍,跟著學長學姐們完成了該專案,其中也有老師的指導。程式含完整執行的app程式碼,連線了資料庫,能搭建後臺伺服器,實現了賬號登陸、註冊、點餐、支付、評論等功能。其中圖片資源使用短連結生成的,

手把手教你用nginx開發自己的伺服器------利用nginx開發一個helloWorld程式

之前兩篇文章已經說明了過程,今天稍微把過程說細一點,畢竟知其然還要知其所以然嘛,整個呼叫的邏輯是怎完整的呢?其實上兩篇文章看似簡單的將nginx處理一個請求的過程說出來了,但實際過程一點也不簡單,一個連線處理的過程,主要是複雜在準備階段(也就是各種回撥函式的掛載,上下文的準備

手把手教你用nginx開發自己的伺服器------利用nginx開發一個helloWorld程式

能開始學習nginx的你,肯定也擼了不少程式碼了,相信你學習程式碼都是從helloWorld開始的,那麼,今天我們就用nginx開發一個helloWorld,我們將要實現的功能就是當瀏覽器來訪問你的伺服器時,你的終端列印一個helloWorld。先別急著開始擼程式碼,先聊一聊

手把手教你用nginx開發自己的伺服器------利用nginx開發一個helloWorld程式

現在我們正式開始編寫nginx的helloWorld功能,該從哪下手呢?別急,我們在上一篇文章中提到了事件驅動對吧。nginx是怎麼樣事件驅動的呢?我們來看看ngx_worker_process_cycle()這個函式的一部分for ( ;; ) { if

使用kotlin開發android

近期應為工作原因得寫android的程式, 作為習慣於使用python, ruby, scala語言的開發者來說, 使用java這是一個很痛苦的,  所以開始尋找替換品. 在選擇語言上一般我會有以下考慮: 相容java上面的類庫 可以使用lambda 可以拓展語言本身 由

程式開發的一些經驗自定義picker元件

最近這段時間接了一個小程式的開發,開發了一段時間,總結一些經驗,與大家交流下。 1.小程式的頭部title,可以在json裡配置,也可以動態修改。 2.微信小程式連續點選跳轉頁面會跳轉多個頁面,可以加個公共方法,可以加在util.js裡,比如: let button

Android開發-載入公用佈局如公用標題欄

前言: 目前越來越多的activity頁面都會在頁面的頭部載入一個標題欄,為了減少重複程式碼,修改樣式方便。所以就簡單的來說說如何在當前頁面的頭部載入一個公用的佈局頭部檔案。 效果如下圖: 具

Arduino 高階教程 02:用 Visual Studio 2015 開發 Arduino 應用程式

Arduino IDE 的缺點 雖然 Arduino 很流行很火爆,但是 Arduino IDE 卻非常、非常、非常弱。編寫程式碼很不方便,只能說提供了一個最基本的寫程式碼的工具而已,除錯程式碼也很不方便。而且,Arduino IDE 中寫程式碼,只能是把

如何在真機上除錯Android應用程式圖文詳解

C:\Users\xxxxxx>netstat -ano | findstr "5037" TCP 127.0.0.1:5037 0.0.0.0:0 LISTENING 4236 TCP 127.0.0.

android開發的一些經驗轉載,自己看看

前言: 很早以前,就聽人說過android以後會火起來,作為一個前瞻性對它有所瞭解會是一個轉型的好機會,javaweb太成熟飽和了,現在市面上各種android手機層出不窮,網上各種android視訊連續劇一樣跟進,安卓一下子成為了熱門話題,剛開始也是出於個人興趣學的很hi

Android開發之listView使用手機應用列表顯示

public class MainActivity extends Activity implements OnItemLongClickListener { private ListView lv_main; private List<AppInfo> data; private App

Javascript設計模式與開發實踐詳解二:策略模式 http://www.jianshu.com/p/ef53781f6ef2

的人 思想 ram gis pan pro msg have 改變 上一章我們介紹了單例模式及JavaScript惰性單例模式應用這一次我主要介紹策略模式策略模式是定義一系列的算法,把它們一個個封裝起來,並且讓他們可以互相替換。比方說在現實中很多時候也有很多途徑到達同一個

angularjs開發常見問題-2angularjs內置過濾器

post row key end php for java int 過濾 在angular中內置了幾個經常使用的filter,能夠簡化我們的操作。 過濾器使用 ‘|’ 符號,概念有點相似於linux中的管道。 1、filter (過濾) filte

開發電子商城5linux下安裝tvsftpd

install conf enable 創建文件夾 nbsp .org tails all 家目錄 1:先檢查linux下是否安裝了vsftpd 2:安裝了的話就刪除原來的 yum remove vsftpd 3::再到yum庫中安裝 yum -y

開發電子商城3linux下安裝tomact

conn XML cto nbsp strong connector 修改 節點 etc 1:確認安裝了jdk 2:把linux的tomcat 壓縮包上傳到/usr/java 中 3;解壓 tar -zxvf apache-tomcat-7.0.30.tar.gz

開發電子商城6linux下安裝nginx

usr 執行 下載 where linux下 linu 解壓 spa figure 1:確定本機是否安裝了gcc-c++的庫 沒有的話就安裝 whereis gcc yum install gcc-c++ 2:確定本機是否安裝了pcre的函數庫 沒有的話就

大數據全棧開發工程師培訓課程2018最新最全

大數據大數據全棧開發工程師(2018最新最全)課程學習地址:http://www.xuetuwuyou.com/course/230課程出自學途無憂網:http://www.xuetuwuyou.com 課程大綱(分四大階段)第一階段:Java開發階段第二階段:大數據階段第三階段:機器學習階段第四階段:大數據