In the 2017 Google IO Conference, Kotlin was announced as the official language. Follow the party always the right idea, began a passionate start kotlin journey.
After an afternoon of exploration kotlin programmed. Last night, according to the excitement of the mood, while touching the stone side across the way, spent a night time, the project code. After a period of time, Kotlin understand improve, and then look back to this project, is certainly left and right, but this is my first Kotlin project.
1. Androidstudio support for Kotlin configuration:
If you use the AndroidStudio3.0 below, it is not supported by default Kotlin language, you need to configure it yourself.
Androistudio 3.0 or more is self-supporting kotlin.
Specific configuration and use, you can refer to the previous article, Kotlin programming of the Androidstudio (including version 3.0 and 2.x) configuration and use.
2. Adding dependent libraries in Gralde:
Note : The project shown here already supports Kotlin writing, and the Gralde of Project Gralde and Moudle already have Kotlin configuration.
dependencies {Compile filetree (include: [' *.jar '], dir:' Libs ') Androidtestcompile (' com.android.support.test.espresso:espresso-core:2.2.2 ', {ExcludeGroup:' 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" //Official FrameworkCompile' com.android.volley:volley:1.0.0 'Compile' com.google.code.gson:gson:2.8.0 '}
3. Start writing with Kotlin as required:
Use Androidstudio to create Kotlin files or projects, read the Androidstudio use of Kotlin programming.
Project Requirements :
- Search for director's movies in the Bean Pea API
- Load a movie in the list
Implementation :
- Kotlin language Writing
- Volley+gson official framework asynchronous loading and parsing
- Show movies in Recyclerview
based on the analysis, start writing code :
1. Write the volley single-instance operation class :
object
Keyword declaration Singleton class
lateinit
The keyword declaration declares a non-null variable, and the benefit does not need to set the initial value.
lazy()
The deferred attribute, which synchronously produces a single object.
Val
Keyword declares a read-only object, and the keyword Var
declares a writable object.
Note : Creating objects does not require the use of new
keywords in java.
/*** * object is used for Singleton mode * * Object declares object name, accessed by object name, but cannot be assigned using = right. * */ Objectvolleysingletion{ /** * Lateinit declares a non-null variable and does not need to set the initial value. */ PrivateLateinitvarContext:context/** * This uses the delay attribute (lazy properties): The results are computed on first access, and the results of the first record are copied at a later time. * * * Use form: var p:string by lazy {} * * lazy () returns a Lazy<t> T object. * * Note: The process of calculating the result of the lazy attribute is a synchronous lock (synchronized). * * Function: Singleton object */ ValRequestqueque:requestqueue byLazy{Volley.newrequestqueue (context)}ValImageloader:imageloader byLazy{//Do not need to call the New keyword to create an objectImageloader (Requestqueque,lrubtimapcache ())} Fun Initconfi (Context:context) { This. Context =context.applicationcontext}}
2. LRUCache needed to write Imageloader:
A class inherits the parent class and the way it implements the interface:class 类名 :超类名(),接口名
Lrubitmapcache The main constructor, specify that the parameter type is int and also specify a default value.
Lrubitmapcache has a main constructor, so the superclass (here is LRUCache) must be initialized in the main constructor.
Companion
Keyword that modifies the associated object. Associated object class name, can be omitted
/*** * Lrubitmapcache The primary constructor, specify a default value. * * Lrubitmapcache with the main constructor, so the superclass (here is LRUCache) must be initialized in the main constructor. * */Class Lrubtimapcache (size:int= defaultsize): lrucache<string,bitmap> (size), imageloader.imagecache{override F Un getbitmap (url:string): Bitmap? {returnGet (URL)} override fun Putbitmap (url:string?, Bitmap:bitmap?) {Put (Url,bitmap)} Override Fun SizeOf (key:string, Value:bitmap): Int {returnvalue.rowbytes*value.height/1024x768}/** * Use the companion keyword, the associated object class name, can be omitted. */Companion object{/** * Val declares a read-only variable * */Val Defaultsize:int get () {val maxmemory = (Runtime.getruntime (). MaxMemory ()/1024x768). ToInt () Val cacheSize = maxmemory/8 returnCacheSize}}}
3. Write a custom application:
override
Keyword used to replicate a method that exists in a superclass or interface
class BaseApplication :Application(){ override fun onCreate() { super.onCreate() //初始化Volley配置 VolleySingletion.initConfi(this) }}
Configure in Androidmanifest.xml:
<manifest xmlns:android="Http://schemas.android.com/apk/res/android" package ="Com.xingen.kotlindemo"> Networking permissions<uses-permission android : Name = "Android.permission.INTERNET" /> <application android: Allowbackup = "true" android:icon =< Span class= "Hljs-value" > "@mipmap/ic_launcher" android:label = "@string/app_name" android:roundicon =" @mipmap/ic_launcher_round " android:supportsrtl = "true" android:name = ". Baseapplication "//Use custom 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. Writing entity classes
There is also a point data
in the question: The keyword modifies the data object, but must have the main constructor function.
Therefore, the data object is not decorated here.
- Type is followed
?
by a yes to allow the object to be empty
//https://api.douban.com/v2/movie/search?q= Zhang Yimou, the data structure returned. classmovielist {LateinitvarSubjects:list<movie>classMovie {LateinitvarYearString varTitleString? =NULL varId:String? =NULLLateinitvarImages:imagesclassImages {varSmallString?=NULL varLargeString? =NULL} }}
5. Write the Recyclerview adapter:
this
References are the most inner objects, and if you reference an outer object, you need to use the[email protected]类名
In addition to the initialization of global variables in the following ways, you can declare types in the main constructor
Class Imagelistadapter (movielist:list<movielist.movie>): recyclerview.adapter< Imagelistadapter.viewholder> () {/** * Specifies a global variable, gets the parameter from the main constructor, initializes the */var list = Movielist/** * Number of loads * *Override Fun GetItemCount (): Int {returnList.size}/** * Create Viewholder * *Override Fun Oncreateviewholder (Parent:viewgroup, Viewtype:int): viewholder {var rootview = view.inflate (parent. Context, R.layout.item_imagelist_layout,NULL)returnViewholder (Rootview)}/** * Bind viewholder to load data * /Override Fun Onbindviewholder (Holder:viewholder, Position:int) {holder.loadimage (position)}/** * Inner modifier inner class */Inner class Viewholder (var Rootview:view): Recyclerview.viewholder (Rootview) {/** * Constructs a method for loading data with the current position in the parameter 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] class name way to get the corresponding class of this point. */var adapter= This@ImageListAdapter /** * Networkimageview Start loading pictures * *Iv.setdefaultimageresid (R.mipmap.ic_launcher) iv.seterrorimageresid (r.mipmap.ic_launcher) Iv.setImag Eurl (Adapter.list[position].images.large,volleysingletion.imageloader) title.text=adapter.list[position].title } }}
6. Write the mainactivity to send the request and update the data :
/** * A class inherits the parent class and implements the interface; Class class name: Super Class name (), Interface name */Class Mainactivity:appcompatactivity () {/** * Override is used to overwrite inherited parent classes or implement methods in an interface. * * Fun is used to identify the method * * Parameter form: Parameter name: Type * *? is used to specify that an object can be empty * */Override Fun OnCreate (Savedinstancestate:bundle?) {Super. OnCreate (Savedinstancestate) Setcontentview (R.layout.activity_main) Shwodiaglog () This. Initview () This. SendRequest ()} lateinit var Recyclerview:recyclerview/** * Initialize control * /Fun Initview () {Recyclerview = This. Findviewbyid (R.id.main_recycler_view) as Recyclerview}/** * Load network data into Recyclerview * /Fun LoadData (movielist:list<movielist.movie>) {Recyclerview.layoutmanager = Linearlayoutmanager ( This) Recyclerview.adapter = Imagelistadapter (movielist)} lateinit var Progressdialog:progressdialog/** * Display Dialog * /Fun Shwodiaglog () {ProgressDialog = ProgressDialog ( This) Progressdialog.show ()}/** * Cancel Dialog * *Fun Cancledialog () {Progressdialog.dismiss ()}/** * Toast Display * /Fun Loadtoast (content:string?) {Toast.maketext ( This, content, Toast.length_short). Show ()}/** * Send request, here use Douban public search Movie API * /Fun SendRequest () {var url ="https://api.douban.com/v2/movie/search?q= Zhang Yimou"Val request = stringrequest (URL, response.listener<string> {Response-//Request succeeded, Gson parse JSONvar movilist = Gson (). Fromjson (response, Movielist::class.java) LoadData (movilist.subjects) Cancledi Alog ()}, Response.errorlistener {error-Loadtoast (error.message) Cancledia Log ()})a reference to an object in the//Simple interest ClassVolleySingletion.requestQueque.add (Request)}}
The Activity_main.xml code is as follows:
<android. Support. Constraint. ConstraintlayoutXmlns: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. Widgets. RecyclerviewAndroid:id="@+id/main_recycler_view"Android:layout_width="Match_parent"android:layout_height="Match_parent"> </android. Support. V7. Widgets. Recyclerview></android. Support. Constraint. Constraintlayout>
The Item_imagelist_layout.xml code is as follows:
<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. NetworkimageviewAndroid: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>
The final directory structure of the project, as follows:
Project Run Results:
Project Code: Https://github.com/13767004362/KotlinVolleyDemo
Resource Reference :
Configuration of Androidstudio: http://blog.csdn.net/hexingen/article/details/72621795
Kotlin Chinese and English comparison of the official website: https://www.kotlincn.net/
Kotlin Chinese: https://huanglizhuo.gitbooks.io/kotlin-in-chinese/content/
Kotlin Chinese translation group: Https://github.com/huanglizhuo/kotlin-in-chinese
Kotlin Programming Android Applications (Volley+gson dependent libraries)