Viewpager2 Extenstion Method로 처리한다.

 

pagePxWidth or pagePxHeight은 보통 기본값으로 처리한다.

한 화면 스크롤 할 경우 그냥 사용하면 됨.

viewpager2에서 scoll 방향이 가로 세로일 경우 나뉘어지기 때문에 orientation으로 구분해서 처리한다.

 


fun ViewPager2.setCurrentItem(
    item: Int,
    duration: Long,
    interpolator: TimeInterpolator = AccelerateDecelerateInterpolator(),
    pagePxWidth: Int = width, // Default value taken from getWidth() from ViewPager2 view
    pagePxHeight:Int = height
) {
    val pxToDrag: Int = if (orientation == ViewPager2.ORIENTATION_HORIZONTAL)
    {
        pagePxWidth * (item - currentItem)
    }
    else

    {
        pagePxHeight * (item - currentItem)
    }


    val animator = ValueAnimator.ofInt(0, pxToDrag)
    var previousValue = 0
    animator.addUpdateListener { valueAnimator ->
        val currentValue = valueAnimator.animatedValue as Int
        val currentPxToDrag = (currentValue - previousValue).toFloat()
        fakeDragBy(-currentPxToDrag)
        previousValue = currentValue
    }
    animator.addListener(object : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator?) { beginFakeDrag() }
        override fun onAnimationEnd(animation: Animator?) { endFakeDrag() }
        override fun onAnimationCancel(animation: Animator?) { /* Ignored */ }
        override fun onAnimationRepeat(animation: Animator?) { /* Ignored */ }
    })
    animator.interpolator = interpolator
    animator.duration = duration
    animator.start()
}


포지션 & 듀레이션만 적용시켜주면됨.

setCurrentItem(ticker.currentItem+1,500)

 

 

참조링크 : stackoverflow.com/questions/57505875/change-viewpager2-scroll-speed-when-sliding-programmatically

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

Fragment BackStack clear  (0) 2020.01.14
Android Tool bar change icon  (0) 2019.07.26
Android Studio 에서 JSON Kotlin Class 쉽게 만들기  (0) 2019.05.31
Kotlin Higher-Order Functions  (0) 2019.05.21
Android GPS Turn On  (0) 2019.02.21

Android Fragment replace 사용시 중복 fragment 처리를 위해 사용

 

fun clearStack()
{
    val backStackEntry = supportFragmentManager.backStackEntryCount
    if (backStackEntry > 0) {
        for (i in 0 until backStackEntry) {
            supportFragmentManager.popBackStackImmediate()
        }
    }
    if (supportFragmentManager.fragments.size > 0) {
        supportFragmentManager.fragments.forEach {
            if (it != null) {
                supportFragmentManager.beginTransaction().remove(it).commit()
            }
        }
    }
}

 

아래와 같이 확장함수로 처리해도 됨. 현재 아래 코드를 사용중

fun FragmentManager.clearBackStack() {
    popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}

 

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

ViewPager2 set scroll Speed  (0) 2020.11.25
Android Tool bar change icon  (0) 2019.07.26
Android Studio 에서 JSON Kotlin Class 쉽게 만들기  (0) 2019.05.31
Kotlin Higher-Order Functions  (0) 2019.05.21
Android GPS Turn On  (0) 2019.02.21

ex code ...........

 

val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val toggle = ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)

drawerLayout.addDrawerListener(toggle)
toggle.syncState()

 

//Change Left Menu Icon
supportActionBar?.setHomeButtonEnabled(true)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toolbar.setNavigationIcon(R.drawable.i_mymenu)

 

// Change Right Menu Icon
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    toolbar.overflowIcon = getDrawable(R.drawable.i_video)
}
else
{

    toolbar.overflowIcon = resources.getDrawable(R.drawable.i_video)
}
navView.setNavigationItemSelectedListener(this)

 

 

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

ViewPager2 set scroll Speed  (0) 2020.11.25
Fragment BackStack clear  (0) 2020.01.14
Android Studio 에서 JSON Kotlin Class 쉽게 만들기  (0) 2019.05.31
Kotlin Higher-Order Functions  (0) 2019.05.21
Android GPS Turn On  (0) 2019.02.21

JSON 데이터를 kotlin class 로 변환하기 위해

 

json to kotlin class 라는 플러그인을 설치한다.

 

https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-

 

JSON To Kotlin Class (JsonToKotlinClass) - Plugins | JetBrains

Welcome to the JetBrains plugin repository

plugins.jetbrains.com

 

Android Studio 에 plugin 검색에

json to kotlin class 을 검색하면

 

위와 같은 플러그인을 찾을 수 있다.

 

찾아서 설치 후 IDE를 재실행 하고

 

new -> Kotlin data class File from JSON 을 선택 하거나

 

JSON 데이터를 복사 한 후

 

command + N 을 누르게 되면

 

위와 같은 화면을 확인 할 수 있다.

 

Kotlin data classes from JSON 선택 할 경우

 

JSON 형식을 입력 할 수 있는 화면과

클래스 명을 입력 할 수 있는 화면이 노출된다.

 

입력 완료 후 Generate를 하게 되면

입력된 JSON 값을 이용해

형식에 맞는 data class를 생성해준다.

 

API 통신시 편하게 JSON 클래스를 만들어 사용 할 수 있다

Kotlin Higher-Order Functions

interface를 통해 간단한 연동이 필요할 경우

interface ExampleInterface
{
fun checkFun() 
}

fun testFunction(example:ExampleInterface)
{
example.checkFun()
}

와 같이 사용 되던 부분을


fun testFunction(checkFun:()->Unit)
{
checkFun()
}

로 표현 할 수 있다.

비동기 처리와 같이 데이터 처리 후 결과를 리턴 할 경우 Higher-Oder Functions을 사용해
기존의 Interface를 사용 하지 않고 코드량을 줄여서 사용 할 수 있다.



---------- 설명 ---------
fun testFunction(checkFun:()->Unit)

checkFun => 함수명
() => 리턴값이 없을 경우 () 로 표현한다. 
데이터를 넘겨야 할 경우 데이터 타입을 선언하면된다. 
(String) ->. Unit 과 같은 형태
(String,Int) -> Unit 등..

Unit => 리턴값은 없기 때문에 Unit으로 처리



Turn on GPS Programmatically in Android 4.4 or Higher


if (isGpsOff())
{
tryGpsOn()
}
private fun isGpsOff():Boolean {
return !(getSystemService(Context.LOCATION_SERVICE) as LocationManager).isProviderEnabled(LocationManager.GPS_PROVIDER)
}
private fun tryGpsOn() {
val googleApiClient:GoogleApiClient = GoogleApiClient.Builder(applicationContext).addApi(LocationServices.API).build()
googleApiClient.connect()


val builder:LocationSettingsRequest.Builder = LocationSettingsRequest.Builder().addLocationRequest(LocationRequest.create().apply {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY;
interval = 30 * 1000;
fastestInterval = 5 * 1000;
})
builder.setAlwaysShow(true) // this is the key ingredient

val result= LocationServices.SettingsApi .checkLocationSettings(googleApiClient, builder.build())
result.setResultCallback {
result: LocationSettingsResult ->

val status = result.status
val state = result .getLocationSettingsStates()

when(status.getStatusCode())
{
LocationSettingsStatusCodes.SUCCESS->{}
LocationSettingsStatusCodes.RESOLUTION_REQUIRED->{
try {
status.startResolutionForResult(this@RenewalPlaceActivity, 1000);
}
catch (e: IntentSender.SendIntentException)
{

}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE->{}
}
}

}



Reference Link : https://www.instructables.com/id/Turn-on-GPS-Programmatically-in-Android-44-or-High/


Android FullScreen Keyboard show hide issue






import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.view.View
import android.widget.FrameLayout
import android.view.ViewConfiguration


class AndroidBug5497Workaround private constructor(activity: Activity) {

private val mContext: Context
private val mChildOfContent: View
private var usableHeightPrevious: Int = 0
private val frameLayoutParams: FrameLayout.LayoutParams

init {
mContext = activity
val content = activity.findViewById<View>(android.R.id.content) as FrameLayout
mChildOfContent = content.getChildAt(0)
mChildOfContent.viewTreeObserver.addOnGlobalLayoutListener { possiblyResizeChildOfContent() }
frameLayoutParams = mChildOfContent.layoutParams as FrameLayout.LayoutParams
}

private fun possiblyResizeChildOfContent() {
val usableHeightNow = computeUsableHeight()
val navigationBarHeight = getNavigationBarHeight()
if (usableHeightNow != usableHeightPrevious) {
val usableHeightSansKeyboard = mChildOfContent.rootView.height
val heightDifference = usableHeightSansKeyboard - usableHeightNow
if (heightDifference > usableHeightSansKeyboard / 4) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference
} else {
// heightDifference == 0 >> navigationbar invisible
if (heightDifference == 0)
{
frameLayoutParams.height = usableHeightSansKeyboard
}
else
{
frameLayoutParams.height = usableHeightSansKeyboard - navigationBarHeight
}
}
mChildOfContent.requestLayout()
usableHeightPrevious = usableHeightNow
}
}

private fun computeUsableHeight(): Int {
val r = Rect()
mChildOfContent.getWindowVisibleDisplayFrame(r)
return r.bottom - r.top
}

private fun getNavigationBarHeight(): Int {
val hasMenuKey = ViewConfiguration.get(mContext).hasPermanentMenuKey()
val resourceId = mContext.resources.getIdentifier("navigation_bar_height", "dimen", "android")
return if (resourceId > 0 && !hasMenuKey) {
mContext.resources.getDimensionPixelSize(resourceId)
} else 0
}



companion object {

// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

fun assistActivity(activity: Activity) {
AndroidBug5497Workaround(activity)
}
}

}


https://github.com/googlesamples/

Rip Tutorial



lib dependencies setting 및 proguard setting 

    val REQUEST_TAKE_PHOTO = 1
val REQUEST_SELECT_PICTURE = 2

private fun dispatchTakePictureIntent()
{
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

takePictureIntent.resolveActivity(getPackageManager())?.let {
var photoFile:File? = null
try {
photoFile = createImageFile();
} catch (ex:IOException) {
// Error occurred while creating the File
ex.printStackTrace()
}
// Continue only if the File was successfully created
if (photoFile != null) {
val photoURI: Uri = FileProvider.getUriForFile(this,
"lonepine.jis.playcardforkids",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}

private fun galleryAddPic() {
val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
val f = File(mCurrentPhotoPath)
val contentUri = Uri.fromFile(f)
mediaScanIntent.data = contentUri
this.sendBroadcast(mediaScanIntent)
}



private fun selectImageFromGallery()
{
// 사진 선택
val intent = Intent()
intent.type = "image/*"
// intent.action = Intent.ACTION_GET_CONTENT
intent.action = Intent.ACTION_PICK
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), REQUEST_SELECT_PICTURE)
}

private fun getPath(uri: Uri?): String? {
// uri가 null일경우 null반환
if (uri == null) {
return null
}
// 미디어스토어에서 유저가 선택한 사진의 URI를 받아온다.
val projection = arrayOf(MediaStore.Images.Media.DATA)
val cursor = managedQuery(uri, projection, null, null, null)
if (cursor != null) {
val column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
return cursor.getString(column_index)
}
// URI경로를 반환한다.
return uri.path
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_TAKE_PHOTO) {
Log.d("jis","resultCode >> ${resultCode}")
val resultFile = File(mCurrentPhotoPath)
Log.d("jis","resultFile.exists() >> ${resultFile.exists()}")
if (resultCode == Activity.RESULT_OK)
{
galleryAddPic()
mCurrentPhotoPath?.let {
runOnIoScheduler {
cardDao.update(vpa.items.get(vp.currentItem).seq,it)
runOnUiThread {
vpa.notifyDataSetChanged()
}
}
}
}
else
{
if (resultFile.exists())
{
resultFile.delete()
}
}
}
else if (requestCode == REQUEST_SELECT_PICTURE)
{
getPath(data?.getData())?.let {
val resultFile = File(it)
if (resultFile.exists())
{
runOnIoScheduler {
cardDao.update(vpa.items.get(vp.currentItem).seq,it)
runOnUiThread {
vpa.notifyDataSetChanged()
}
}
}
}
}
}

@Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
)

// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath()
return image
}


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

Google Samples Links  (0) 2018.06.26
lib dependencies setting 및 proguard setting example url  (0) 2018.06.19
Google Translate  (0) 2018.05.30
Multipart used retrofit2  (0) 2018.05.16
Android Glide Proguard rules  (0) 2018.05.16

+ Recent posts