Implement Material Design View in Kotlin

It is the 20th day of Dip Advent Calendar.

This is a continuation of Last time.

Since it's a big deal, I tried to find out how to implement Material Design related View in Kotlin. Basically, if you feed the source code written in Java to the Kotlin plugin, it will be converted to Kotlin, so I will rewrite the converted code where it can be rewritten like Kotlin. I tried to write an article on the theme of ⇒, but the Java ⇒ Kotlin code conversion function of the Kotlin plugin was so excellent that I could hardly fix anything other than the variable declaration related to Null safety, Kotlin is great. ..

Floating Action Button

When writing in Java

Layout files should be basically the same whether it's Java or Kotlin.

fragment_layout.xml


<android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/blue_grey_600"
        android:transitionGroup="false">

    <include layout="@layout/map_description" />

    <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/ic_panorama"
            android:contentDescription="@string/action_panorama"
            android:visibility="invisible"/>

</android.support.design.widget.CoordinatorLayout>

MyFragment.java


package com.samples.fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.transition.TransitionManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment extends Fragment {

    public static final String TAG = "MyFragment";
    private FloatingActionButton mFloatingActionButton;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment_layout, container, false);
        mFloatingActionButton = (FloatingActionButton) contentView.findViewById(R.id.fab);
        mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "FAB Pushed");
            }
        });
        return contentView;
    }
}

When writing in Kotlin

If you feed it to the Kotlin plugin, it will spit out the following code, but I will try to fix it.

MyFragment.kt(Immediately after the plugin is converted)


class DetailFragment : Fragment(), DataView<Detail> {
    private var mFloatingActionButton: FloatingActionButton? = null
    
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val contentView = inflater!!.inflate(R.layout.fragment_detail, container, false)
        mFloatingActionButton = contentView.findViewById(R.id.fab) as FloatingActionButton
        mFloatingActionButton!!.setOnClickListener(View.OnClickListener {
            Log.d(TAG, "FAB Pushed")
        })
        return contentView
    }
}

View.OnClickListener itself is Java code, so you can use SAM conversion. You can change View.OnClickListener to view->.

MyFragment.kt(Fixed to SAM)


class DetailFragment : Fragment(), DataView<Detail> {
    private var mFloatingActionButton: FloatingActionButton? = null
    
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val contentView = inflater!!.inflate(R.layout.fragment_detail, container, false)
        mFloatingActionButton = contentView.findViewById(R.id.fab) as FloatingActionButton

        // View.View OnClickListener->Change to
        mFloatingActionButton?.setOnClickListener {view ->
            Log.d(TAG, "FAB Pushed")
        }
        return contentView
    }
}

Navigation Drawer

Navigation Drawer seems to have almost no difference in implementation between Java and Kotlin.

When writing in Java

MainActivity.java


package com.sample.activity;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}

When writing in Kotlin

MainActivity.kt


package com.sample.activity

import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.design.widget.Snackbar
import android.view.View
import android.support.design.widget.NavigationView
import android.support.v4.view.GravityCompat
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.Menu
import android.view.MenuItem

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val toolbar = findViewById(R.id.toolbar) as Toolbar
        setSupportActionBar(toolbar)

        val drawer = findViewById(R.id.drawer_layout) as DrawerLayout
        val toggle = ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawer.setDrawerListener(toggle)
        toggle.syncState()

        val navigationView = findViewById(R.id.nav_view) as NavigationView
        navigationView.setNavigationItemSelectedListener(this)
    }

    override fun onBackPressed() {
        val drawer = findViewById(R.id.drawer_layout) as DrawerLayout
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START)
        } else {
            super.onBackPressed()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        val id = item.itemId


        if (id == R.id.action_settings) {
            return true
        }

        return super.onOptionsItemSelected(item)
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        // Handle navigation view item clicks here.
        val id = item.itemId

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        val drawer = findViewById(R.id.drawer_layout) as DrawerLayout
        drawer.closeDrawer(GravityCompat.START)
        return true
    }
}

Activity Transition

When writing in Java

See here. Basically, it seems that there is no particular change even if you write style.xml or AndroidManifest.xml settings and layout.xml in Kotlin.

When writing in Kotlin

The part where ActivityOptionsCompat.makeSceneTransitionAnimation is executed is not so different from Java. Intent instantiation is also in Java

Intent intent = new Intent(MainActivity.this, ImaveDetailActivity.class);but,


 In Kotlin, it seems that `` `val intent = Intent (this, ImageDetailActivity :: class.java)` `` can be used.


#### **`MainActivity.kt`**
```kotlin


class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        //imageview
        val imageview = findViewById(R.id.imageview_content) as ImageView
        imageview.setOnClickListener { view ->
            val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
                    this,
                    findViewById(R.id.imageview_content),
                    getString(R.string.trans_name))
            val intent = Intent(this, ImageDetailActivity::class.java)
            ActivityCompat.startActivity(this, intent, options.toBundle())

        }
    }
}

at the end

First of all, if you implement it with clean code that does not write unnecessary processing in Java and convert it with a plug-in, Kotlin code will be created, so it may be good to learn by looking at it. Kotlin is cute.

Recommended Posts

Implement Material Design View in Kotlin
HMAC in Kotlin
Implement iteration in View by rendering collection [Rails]
Big Decimal in Kotlin
Implement CustomView in code
Implement markdown in Rails
I tried to implement a buggy web application in Kotlin
Implement application function in Rails
Read design patterns in Ruby
Implement follow function in Rails
Implement LTI authentication in Rails
Implement Basic authentication in Java
[Java] Get KClass in Java [Kotlin]
Implement math combinations in Java
2 Implement simple parsing in Java
[Android] Implement Adblock in WebView
Implement Email Sending in Java
View monthly calendar in Rails
Implement Swift UITextField in code
Implement import process in Rails
Implement functional quicksort in Java
Implement rm -rf in Java.
Apache POI Excel in Kotlin
Implementation of HashMap in kotlin
View current date in Java
Implement XML signature in Java