Skip to content

Commit

Permalink
feat: リスト画面から詳細画面への遷移を実装 (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
kokoichi206 committed Dec 4, 2022
1 parent 9ffec3c commit d33fcac
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 9 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ dependencies {
// UI Tests
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
// Navigation
implementation "androidx.navigation:navigation-compose:2.5.3"
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
CustomTheme {
MainView()
Navigation()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package jp.co.yumemi.android.code_check.presentation

import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import jp.co.yumemi.android.code_check.presentation.detail.navigation.detailView
import jp.co.yumemi.android.code_check.presentation.detail.navigation.navigateToDetailView
import jp.co.yumemi.android.code_check.presentation.main.navigation.mainRoute
import jp.co.yumemi.android.code_check.presentation.main.navigation.mainView

@Composable
fun Navigation() {
val navController = rememberNavController()

NavHost(
navController = navController,
startDestination = mainRoute,
) {
mainView {
navController.navigateToDetailView(it)
}

detailView()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package jp.co.yumemi.android.code_check.presentation.detail

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import jp.co.yumemi.android.code_check.models.Repository

@Composable
fun DetailView() {
fun DetailView(repository: Repository) {
Text(text = repository.toString())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package jp.co.yumemi.android.code_check.presentation.detail.navigation

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import jp.co.yumemi.android.code_check.models.Repository
import jp.co.yumemi.android.code_check.presentation.detail.DetailView
import jp.co.yumemi.android.code_check.presentation.util.Constants


const val detailRoute = "detail_route"

const val name = "name"
const val iconUrl = "icon_url"
const val language = "language"
const val stars = "stars"
const val watchers = "watchers"
const val forks = "forks"
const val issues = "issues"


fun NavController.navigateToDetailView(repository: Repository) {

val icon = repository.ownerIconUrl
.replace("/", Constants.SLASH_ENCODED)
.replace("?", Constants.QUESTION_ENCODED)
val repoName = repository.name
.replace("/", Constants.SLASH_ENCODED)
.replace("?", Constants.QUESTION_ENCODED)
this.navigateUp()
this.navigate(
detailRoute
+ "/$name=${repoName}&$iconUrl=${icon}&$language=${repository.language}"
+ "&$stars=${repository.stargazersCount}&$watchers=${repository.watchersCount}"
+ "&$forks=${repository.forksCount}&$issues=${repository.openIssuesCount}"
)
}

fun NavGraphBuilder.detailView() {
composable(
route = detailRoute
+ "/$name={${name}}&$iconUrl={${iconUrl}}&$language={${language}}"
+ "&$stars={${stars}}&$watchers={${watchers}}"
+ "&$forks={${forks}}&$issues={${issues}}",

arguments = listOf(
navArgument(name) { type = NavType.StringType },
navArgument(iconUrl) { type = NavType.StringType },
navArgument(language) { type = NavType.StringType },
navArgument(stars) { type = NavType.LongType },
navArgument(watchers) { type = NavType.LongType },
navArgument(forks) { type = NavType.LongType },
navArgument(issues) { type = NavType.LongType },
)
) { backStackEntry ->

val name = backStackEntry.arguments?.getString(name)
?.replace(Constants.SLASH_ENCODED, "/")
?.replace(Constants.QUESTION_ENCODED, "?") ?: ""
val iconUrl = backStackEntry.arguments?.getString(iconUrl)
?.replace(Constants.SLASH_ENCODED, "/")
?.replace(Constants.QUESTION_ENCODED, "?") ?: ""
val language = backStackEntry.arguments?.getString(language) ?: ""
val stars = backStackEntry.arguments?.getLong(stars) ?: 0L
val watchers = backStackEntry.arguments?.getLong(watchers) ?: 0L
val forks = backStackEntry.arguments?.getLong(forks) ?: 0L
val issues = backStackEntry.arguments?.getLong(issues) ?: 0L
val repository = Repository(
name = name,
ownerIconUrl = iconUrl,
language = language,
stargazersCount = stars,
watchersCount = watchers,
forksCount = forks,
openIssuesCount = issues
)

DetailView(repository = repository)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import jp.co.yumemi.android.code_check.R
import jp.co.yumemi.android.code_check.models.Repository
import jp.co.yumemi.android.code_check.presentation.MainActivity.Companion.updateLastSearchDate
import jp.co.yumemi.android.code_check.presentation.main.component.OneRepository
import jp.co.yumemi.android.code_check.presentation.main.component.SearchBar

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainView() {
fun MainView(
onRepositoryClick: (Repository) -> Unit = {},
) {
Scaffold(
topBar = {
TopAppBar(
Expand All @@ -37,14 +39,15 @@ fun MainView() {
},
containerColor = MaterialTheme.colorScheme.background,
) {
SearchView(paddingValues = it)
SearchView(paddingValues = it, onRepositoryClick = onRepositoryClick)
}
}

@Composable
fun SearchView(
viewModel: MainViewModel = hiltViewModel(),
paddingValues: PaddingValues = PaddingValues(0.dp),
onRepositoryClick: (Repository) -> Unit = {},
) {
val uiState by viewModel.uiState.collectAsState()

Expand All @@ -66,7 +69,7 @@ fun SearchView(

LazyColumn {
items(uiState.repositories) { item ->
OneRepository(name = item.name)
OneRepository(repository = item, onRepositoryClick = onRepositoryClick)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package jp.co.yumemi.android.code_check.presentation.main.component

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
Expand All @@ -8,15 +10,21 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import jp.co.yumemi.android.code_check.models.Repository

@Composable
fun OneRepository(
name: String,
repository: Repository,
onRepositoryClick: (Repository) -> Unit = {},
) {
Text(
modifier = Modifier
.fillMaxWidth()
.clickable {
onRepositoryClick(repository)
}
.padding(horizontal = 16.dp, vertical = 8.dp),
text = name,
text = repository.name,
fontSize = 16.sp,
color = MaterialTheme.colorScheme.onBackground,
)
Expand All @@ -30,5 +38,14 @@ fun OneRepository(
@Preview
@Composable
fun OneRepositoryPreview() {
OneRepository("kokoichi2/kokoichi2")
val repository = Repository(
name = "kokoichi206/kokoichi206",
ownerIconUrl = "",
language = "",
stargazersCount = 0,
watchersCount = 1,
forksCount = 2,
openIssuesCount = 3,
)
OneRepository(repository)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package jp.co.yumemi.android.code_check.presentation.main.navigation

import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import jp.co.yumemi.android.code_check.models.Repository
import jp.co.yumemi.android.code_check.presentation.main.MainView

const val mainRoute = "main_route"

fun NavGraphBuilder.mainView(
onRepositoryClick: (Repository) -> Unit,
) {
composable(route = mainRoute) {
MainView(onRepositoryClick)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package jp.co.yumemi.android.code_check.presentation.util

object Constants {
/**
* Escape string (percent-encoding)
*/
const val SLASH_ENCODED = "%2F"
const val QUESTION_ENCODED = "%3F"
}

0 comments on commit d33fcac

Please sign in to comment.