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
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;
}
}
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.
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;
}
}
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
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.
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())
}
}
}
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