Skip to content

Commit

Permalink
Merge pull request #1 from kp-marczynski/layout-services
Browse files Browse the repository at this point in the history
Layout services
  • Loading branch information
kp-marczynski authored Nov 28, 2018
2 parents 9127130 + 03d7088 commit 8c01db0
Show file tree
Hide file tree
Showing 21 changed files with 593 additions and 128 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".MyApplication"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
Expand Down
17 changes: 0 additions & 17 deletions app/src/main/java/pl/kpmarczynski/gallery/Layout.kt

This file was deleted.

113 changes: 36 additions & 77 deletions app/src/main/java/pl/kpmarczynski/gallery/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,103 +1,62 @@
package pl.kpmarczynski.gallery

import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.Surface
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.view.SimpleDraweeView
import pl.kpmarczynski.gallery.ImageRepository.Companion.getNextPosition
import pl.kpmarczynski.gallery.ImageRepository.Companion.getPreviousPosition
import pl.kpmarczynski.gallery.layout.AbstractLayoutService
import pl.kpmarczynski.gallery.layout.Layout
import pl.kpmarczynski.gallery.layout.details.DetailsService
import pl.kpmarczynski.gallery.layout.grid.GridService
import pl.kpmarczynski.gallery.layout.puzzle.PuzzleService


class MainActivity : AppCompatActivity() {

private lateinit var viewAdapter: RecyclerView.Adapter<*>
private lateinit var recyclerView: RecyclerView
private lateinit var viewManager: GridLayoutManager
private val onScrollListener: GridOnScrollListener = GridOnScrollListener()
private val state: State = State(Layout.GRID, 0)
private val detailsService: AbstractLayoutService = DetailsService()
private val gridService: AbstractLayoutService = GridService()
private val puzzleService: AbstractLayoutService = PuzzleService()
private var currentLayout: Layout = Layout.GRID
private val fragmentManager = supportFragmentManager

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val rownum = getRownum()
viewAdapter = GridImageAdapter(this, rownum) { position: Int -> gridItemClicked(position) }
Fresco.initialize(this)
updateViewWithState()
}

private fun updateViewWithState() {
when (state.currentView) {
Layout.GRID -> setupGridLayout()
Layout.DETAILS -> setupDetailsLayout()
}
}

fun onPreviousButtonClick(view: View) = updateCurrentImage(::getPreviousPosition)
setContentView(R.layout.main_layout)

fun onNextButtonClick(view: View) = updateCurrentImage(::getNextPosition)

fun onHomeButtonClick(view: View) = setupGridLayout()

private fun getRownum(): Int {
val window: WindowManager = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
return if (window.defaultDisplay.rotation == Surface.ROTATION_0 || window.defaultDisplay.rotation == Surface.ROTATION_180) 2 else 4
updateView(currentLayout, 0)
}

private fun gridItemClicked(position: Int) {
state.currentView = Layout.DETAILS
state.currentImagePosition = position
setupDetailsLayout()
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
getService(currentLayout).refreshLayout()
}

private fun setupGridLayout() {
state.currentView = Layout.GRID
setContentView(Layout.GRID.value)
viewManager = GridLayoutManager(this, getRownum())
recyclerView = findViewById<RecyclerView>(R.id.gridview).apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
}
recyclerView.addOnScrollListener(onScrollListener)
}
override fun onBackPressed() = getService(currentLayout).onBackPressed()

private fun setupDetailsLayout() {
setContentView(Layout.DETAILS.value)
updateCurrentImage { state.currentImagePosition }
fun updateView(layout: Layout, position: Int) {
currentLayout = layout
val fragmentTransaction = fragmentManager.beginTransaction()
getService(layout).position = position
fragmentTransaction.replace(R.id.fragment_container, getService(layout))
fragmentTransaction.commit()
}

private fun updateCurrentImage(getNewPosition: (Int) -> Int?) {
val imageView = findViewById<SimpleDraweeView>(R.id.imageView)

val newPosition = getNewPosition(state.currentImagePosition)
if (newPosition != null) {
val imageId: Int? = ImageRepository.getImageId(newPosition)
if (imageId != null) {
imageView.setImageURI("res:/$imageId")
}
private fun getService(layout: Layout): AbstractLayoutService {
return when (layout) {
Layout.GRID -> gridService
Layout.DETAILS -> detailsService
Layout.PUZZLE -> puzzleService
}
findViewById<TextView>(R.id.textView).text = newPosition.toString()
state.currentImagePosition = newPosition!!
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)

outState.putInt("LAYOUT", state.currentView.value)
outState.putInt("POSITION", state.currentImagePosition)
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
getService(currentLayout).saveState(bundle)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
override fun onRestoreInstanceState(bundle: Bundle) {
super.onRestoreInstanceState(bundle)

state.currentImagePosition = savedInstanceState.getInt("POSITION")
state.currentView = Layout.createFromInt(savedInstanceState.getInt("LAYOUT"))
updateViewWithState()
val layout = AbstractLayoutService.restoreLayout(bundle)
getService(layout).restoreState(bundle)
updateView(layout, getService(layout).position)
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/pl/kpmarczynski/gallery/MyApplication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package pl.kpmarczynski.gallery

import android.app.Application
import com.facebook.drawee.backends.pipeline.Fresco


class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Fresco.initialize(this)
}
}
3 changes: 0 additions & 3 deletions app/src/main/java/pl/kpmarczynski/gallery/State.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package pl.kpmarczynski.gallery.layout

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import pl.kpmarczynski.gallery.MainActivity

abstract class AbstractLayoutService(protected val layout: Layout) : Fragment() {

var position: Int = 0

abstract fun setupLayout(position: Int)
abstract fun onBackPressed()

fun refreshLayout() = setupLayout(this.position)

fun switchView(target: Layout) = (activity as MainActivity).updateView(target, position)

open fun saveState(bundle: Bundle) {
bundle.putInt("LAYOUT", layout.value)
bundle.putInt("POSITION", position)
}

open fun restoreState(bundle: Bundle) {
position = bundle.getInt("POSITION")
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(layout.value, container, false)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setupLayout(position)
}

companion object {
fun restoreLayout(bundle: Bundle): Layout = Layout.createFromInt(bundle.getInt("LAYOUT"))
}
}
21 changes: 21 additions & 0 deletions app/src/main/java/pl/kpmarczynski/gallery/layout/Layout.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package pl.kpmarczynski.gallery.layout

import pl.kpmarczynski.gallery.R

enum class Layout(val value: Int) {
GRID(R.layout.grid_layout),
DETAILS(R.layout.details_layout),
PUZZLE(R.layout.puzzle_layout);

companion object {
fun createFromInt(layoutId: Int): Layout {
return when (layoutId) {
GRID.value -> GRID
DETAILS.value -> DETAILS
PUZZLE.value -> PUZZLE
else -> GRID
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package pl.kpmarczynski.gallery.layout.details

import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import com.facebook.drawee.view.SimpleDraweeView
import pl.kpmarczynski.gallery.R
import pl.kpmarczynski.gallery.layout.AbstractLayoutService
import pl.kpmarczynski.gallery.layout.Layout
import pl.kpmarczynski.gallery.repo.ImageRepository

class DetailsService : AbstractLayoutService(Layout.DETAILS) {

override fun setupLayout(position: Int) {
this.position = position
updateCurrentImage { position }

activity!!.findViewById<Button>(R.id.homeButton).setOnClickListener { switchView(Layout.GRID) }
activity!!.findViewById<Button>(R.id.previousButton)
.setOnClickListener { updateCurrentImage(ImageRepository.Companion::getPreviousPosition) }
activity!!.findViewById<Button>(R.id.nextButton)
.setOnClickListener { updateCurrentImage(ImageRepository.Companion::getNextPosition) }
activity!!.findViewById<ImageView>(R.id.imageView).setOnLongClickListener { switchView(Layout.PUZZLE); true }
}

override fun onBackPressed() = switchView(Layout.GRID)

private fun updateCurrentImage(getNewPosition: (Int) -> Int?) {
val imageView = activity!!.findViewById<SimpleDraweeView>(R.id.imageView)

val newPosition = getNewPosition(this.position)
if (newPosition != null) {
val imageId: Int? = ImageRepository.getImageId(newPosition)
if (imageId != null) {
imageView.setImageURI("res:/$imageId")
}
}
activity!!.findViewById<TextView>(R.id.textView).text = newPosition.toString()
this.position = newPosition!!
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package pl.kpmarczynski.gallery
package pl.kpmarczynski.gallery.layout.grid

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.util.DisplayMetrics
import android.view.ViewGroup
import android.view.WindowManager
import com.facebook.drawee.view.SimpleDraweeView
import pl.kpmarczynski.gallery.repo.ImageRepository

class GridImageAdapter(
private val mContext: Context,
private val rownum: Int,
private val clickListener: (Int) -> Unit
private val clickListener: (Int) -> Unit,
private val longClickListener: (Int) -> Boolean
) : RecyclerView.Adapter<GridImageAdapter.PartViewHolder>() {

class PartViewHolder(val imageView: SimpleDraweeView) : RecyclerView.ViewHolder(imageView) {
fun bind(position: Int, clickListener: (Int) -> Unit) {
fun bind(position: Int, clickListener: (Int) -> Unit, longClickListener: (Int) -> Boolean) {
itemView.isLongClickable = true
itemView.setOnLongClickListener { longClickListener(position) }
itemView.setOnClickListener { clickListener(position) }
}
}
Expand All @@ -35,7 +39,7 @@ class GridImageAdapter(
if (imageId != null) {
holder.imageView.setImageURI("res:/$imageId")
}
holder.bind(position, clickListener)
holder.bind(position, clickListener, longClickListener)
}

override fun getItemCount() = ImageRepository.getCount()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pl.kpmarczynski.gallery
package pl.kpmarczynski.gallery.layout.grid

import android.support.v7.widget.RecyclerView
import android.widget.AbsListView
Expand All @@ -12,7 +12,7 @@ class GridOnScrollListener : RecyclerView.OnScrollListener() {
val offset = Math.abs(firstVisibleItem.top)
val height = firstVisibleItem.height

val threshold = 2
val threshold = 2.5
if (offset < (height / threshold)) {
view.smoothScrollBy(0, firstVisibleItem.top)
} else if (offset > (height * (threshold - 1) / threshold)) {
Expand Down
Loading

0 comments on commit 8c01db0

Please sign in to comment.