Constraint Layout을 이용하여 간단한 이동 애니메이션을 구현할 수 있다.


먼저 Constraint Layout을 어떤식으로 사용하는지 알아야 하기 때문에 모를 경우 배우고 난 뒤 읽는 것을 추천


결과물





1. Floating action button을 Constraint Layout에 넣기

<android.support.constraint.ConstraintLayout
android:id="@+id/menu_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom|end" >

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@android:drawable/ic_dialog_alert"
app:fabSize="mini" />

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@android:drawable/ic_dialog_info"
app:fabSize="mini" />

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@android:drawable/ic_dialog_email" />

</android.support.constraint.ConstraintLayout>

fab은 메뉴 버튼, fab1과 fab2는 fab을 누를 시 나오는 항목들


2. fab 버튼 이벤트 구현

class MainActivity : AppCompatActivity() {

private var isMenuCollapsed = true

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)

fab.setOnClickListener { view ->
val constraintSet = ConstraintSet()
constraintSet.clone(menu_layout)

if(isMenuCollapsed) {
// Set fab1's position to top of fab
constraintSet.connect(fab1.id, ConstraintSet.BOTTOM, fab.id, ConstraintSet.TOP)
// Set fab2's position to top of fab1
constraintSet.connect(fab2.id, ConstraintSet.BOTTOM, fab1.id, ConstraintSet.TOP)
}
else {
// Set fab1's position back to bottom
constraintSet.connect(fab1.id, ConstraintSet.BOTTOM, fab.id, ConstraintSet.BOTTOM)
// Set fab2's position back to bottom
constraintSet.connect(fab2.id, ConstraintSet.BOTTOM, fab.id, ConstraintSet.BOTTOM)
}
val transition = AutoTransition()
transition.duration = 300
transition.interpolator = AccelerateDecelerateInterpolator()

TransitionManager.beginDelayedTransition(menu_layout, transition)
constraintSet.applyTo(menu_layout)

isMenuCollapsed = !isMenuCollapsed
}
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.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.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
}


이 방법은 menu_layout의 클론(constraintSet)을 만들고 fab1과 fab2의 새로운 위치를 지정 해주고 Transition을 한다. 결과적으로는 두 개의 menu_layout을 통해 애니메이션을 구현한 것이다.


Constraint를 잘 활용하면 예제처럼 아래서 위로 가는 것뿐만 아니라 오른쪽에서 왼쪽 또는 대각선 까지 다양한 방향 전환이 가능하다.


GitHub : https://github.com/Hot6ix/FloatingActionButton

참조 : https://robinhood.engineering/beautiful-animations-using-android-constraintlayout-eee5b72ecae3

'Android > Kotlin' 카테고리의 다른 글

커스텀 리스트뷰 ( Custom ListView)  (0) 2017.12.21
Volley를 이용한 간단한 네트워크 통신  (0) 2017.12.21
by JamesY 2018. 1. 9. 23:45

Kotlin으로 작성된 커스텀 리스트뷰 예제



MainActivity.kt

import android.content.Context
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val list: ArrayList<CustomItem> = ArrayList()
list.add(CustomItem("James", 23, "Male"))
list.add(CustomItem("Jamie", 20, "Female"))
list.add(CustomItem("John", 30, "Male"))

listview1.adapter = CustomAdapter(this, list)
}

private class CustomAdapter(context: Context, array: ArrayList<CustomItem>): BaseAdapter() {

private var list: ArrayList<CustomItem> = array
private var inflater: LayoutInflater = LayoutInflater.from(context)

override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {

val view: View?
val viewHolder: ViewHolder

if(p1 == null) {
view = this.inflater.inflate(R.layout.listview_item, p2,false)
viewHolder = ViewHolder(view)
view.tag = viewHolder
}
else {
view = p1
viewHolder = view.tag as ViewHolder
}

viewHolder.name.text = list[p0].name
viewHolder.age.text = list[p0].age.toString()
viewHolder.gender.text = list[p0].gender

return view!!
}

override fun getItem(p0: Int): Any {
return list[p0]
}

override fun getItemId(p0: Int): Long {
return p0.toLong()
}

override fun getCount(): Int {
return list.size
}

}

private class ViewHolder(view: View?) {

val name: TextView = view?.findViewById(R.id.nameTextView) as TextView
val age: TextView = view?.findViewById(R.id.ageTextView) as TextView
val gender: TextView = view?.findViewById(R.id.genderTextView) as TextView
}

data class CustomItem(var name: String, var age: Int, var gender: String)
}


listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />

<TextView
android:id="@+id/ageTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />

<TextView
android:id="@+id/genderTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>


GitHub : https://github.com/Hot6ix/SimpleCustomListView

by JamesY 2017. 12. 21. 17:52

Volley를 이용하여 간단한 HTTP 통신을 하는 예제이다.


1. AndroidManifest.xml 에서 권한 명시 

<uses-permission android:name="android.permission.INTERNET" />


2. build.gradle 내  dependencies 에 Volley 사용을 위한 명시

compile 'com.android.volley:volley:1.1.0'


3. Build - Make Project 를 하여 프로젝트에서 Volley 사용 가능


4. HTTP 통신 예제

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log.i
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

lateinit var request: RequestQueue
lateinit var stringRequest: StringRequest

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Setup RequestQueue
request = Volley.newRequestQueue(this)
val url = "http://www.google.com"

// Setup StringRequest
stringRequest = StringRequest(Request.Method.GET, url, Response.Listener<String> {
response -> textView1.text = response // Print http source using textview
}, Response.ErrorListener {
error -> i(applicationContext.packageName, error.toString()) // Print log if error occurred
})

// Set tag for cancel
stringRequest.tag = applicationContext.packageName
// Request
request.add(stringRequest)
}

override fun onStop() {
super.onStop()

// Cancel all request that have packageName tag
if(request != null) {
request.cancelAll(applicationContext.packageName)
}
}
}


GitHub : https://github.com/Hot6ix/SimpleHttpRequest


출처 : https://developer.android.com/training/volley/simple.html

by JamesY 2017. 12. 21. 16:30
| 1 |