Skip to content

Commit 30bfe69

Browse files
committed
Integrate jetpack navigation
1 parent 6ba760f commit 30bfe69

File tree

12 files changed

+196
-75
lines changed

12 files changed

+196
-75
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
<uses-permission android:name="android.permission.INTERNET"/>
77
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
8+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
89

910
<application
1011
android:name=".GankApplication"
@@ -17,7 +18,7 @@
1718
tools:ignore="GoogleAppIndexingWarning"
1819
>
1920
<activity
20-
android:name=".ui.home.MainActivity"
21+
android:name=".ui.MainActivity"
2122
android:launchMode="singleTop"
2223
>
2324
<intent-filter>
@@ -27,13 +28,9 @@
2728
</intent-filter>
2829
</activity>
2930

30-
<activity android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
31-
android:exported="true"/>
32-
3331
<activity
34-
android:name=".ui.pic.PicActivity"
35-
>
36-
</activity>
32+
android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
33+
android:exported="true"/>
3734

3835
</application>
3936

app/src/main/java/cn/nekocode/gank/ActivityRouter.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,9 @@
1616

1717
package cn.nekocode.gank
1818

19-
import android.content.Context
20-
import cn.nekocode.gank.ui.pic.PicActivity
21-
import cn.nekocode.meepo.annotation.Clazz
22-
2319
/**
2420
* @author nekocode ([email protected])
2521
*/
2622
interface ActivityRouter {
2723

28-
@Clazz(PicActivity::class)
29-
fun gotoPic(context: Context)
3024
}

app/src/main/java/cn/nekocode/gank/Extensions.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ import android.content.Context
2121
import android.content.Intent
2222
import android.content.IntentFilter
2323
import android.content.res.Resources
24+
import androidx.fragment.app.Fragment
2425
import androidx.localbroadcastmanager.content.LocalBroadcastManager
2526

2627
/**
2728
* @author nekocode ([email protected])
2829
*/
2930
val Context.activityRouter get() = (this.applicationContext as GankApplication).activityRouter
31+
val Fragment.activityRouter get() = this.requireActivity().activityRouter
3032
val Context.broadcastRouter get() = (this.applicationContext as GankApplication).broadcastRouter
33+
val Fragment.broadcastRouter get() = this.requireActivity().broadcastRouter
3134
val Context.apis get() = (this.applicationContext as GankApplication).apis
35+
val Fragment.apis get() = this.requireActivity().apis
3236

3337
fun Context.registerLocalReceiver(
3438
intentFilter: IntentFilter,

app/src/main/java/cn/nekocode/gank/base/BaseActivity.kt

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
package cn.nekocode.gank.base
1818

1919
import android.annotation.SuppressLint
20-
import androidx.core.app.NavUtils
2120
import androidx.appcompat.app.AppCompatActivity
22-
import android.view.MenuItem
2321
import com.uber.autodispose.*
2422
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider
2523
import io.reactivex.*
@@ -31,23 +29,6 @@ import io.reactivex.parallel.ParallelFlowable
3129
*/
3230
@SuppressLint("Registered")
3331
open class BaseActivity : AppCompatActivity() {
34-
override fun onOptionsItemSelected(item: MenuItem): Boolean {
35-
return when (item.itemId) {
36-
android.R.id.home -> {
37-
if (NavUtils.getParentActivityName(this) != null) {
38-
NavUtils.navigateUpFromSameTask(this)
39-
} else {
40-
finish()
41-
}
42-
true
43-
}
44-
45-
else -> {
46-
super.onOptionsItemSelected(item)
47-
}
48-
}
49-
}
50-
5132
private val scopeProvider by lazy { AndroidLifecycleScopeProvider.from(this) }
5233

5334
/**
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package cn.nekocode.gank.base
2+
3+
import androidx.fragment.app.Fragment
4+
import com.uber.autodispose.*
5+
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider
6+
import io.reactivex.*
7+
import io.reactivex.annotations.CheckReturnValue
8+
import io.reactivex.parallel.ParallelFlowable
9+
10+
/**
11+
* @author nekocode ([email protected])
12+
*/
13+
open class BaseFragment : Fragment() {
14+
private val scopeProvider by lazy { AndroidLifecycleScopeProvider.from(this) }
15+
16+
/**
17+
* Modified from https://github.com/uber/AutoDispose
18+
*/
19+
@CheckReturnValue
20+
fun <T> Flowable<T>.autoDisposable(): FlowableSubscribeProxy<T> =
21+
this.`as`(AutoDispose.autoDisposable(scopeProvider))
22+
23+
@CheckReturnValue
24+
fun <T> Observable<T>.autoDisposable(): ObservableSubscribeProxy<T> =
25+
this.`as`(AutoDispose.autoDisposable(scopeProvider))
26+
27+
@CheckReturnValue
28+
fun <T> Single<T>.autoDisposable(): SingleSubscribeProxy<T> =
29+
this.`as`(AutoDispose.autoDisposable(scopeProvider))
30+
31+
@CheckReturnValue
32+
fun <T> Maybe<T>.autoDisposable(): MaybeSubscribeProxy<T> =
33+
this.`as`(AutoDispose.autoDisposable(scopeProvider))
34+
35+
@CheckReturnValue
36+
fun Completable.autoDisposable(): CompletableSubscribeProxy =
37+
this.`as`(AutoDispose.autoDisposable<Any>(scopeProvider))
38+
39+
@CheckReturnValue
40+
fun <T> ParallelFlowable<T>.autoDisposable(): ParallelFlowableSubscribeProxy<T> =
41+
this.`as`(AutoDispose.autoDisposable(scopeProvider))
42+
}

app/src/main/java/cn/nekocode/gank/ui/home/MainActivity.kt renamed to app/src/main/java/cn/nekocode/gank/ui/MainActivity.kt

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,14 @@
1414
* limitations under the License.
1515
*/
1616

17-
package cn.nekocode.gank.ui.home
17+
package cn.nekocode.gank.ui
1818

1919
import android.os.Bundle
20-
import android.text.Html
20+
import androidx.navigation.findNavController
21+
import androidx.navigation.ui.setupActionBarWithNavController
2122
import cn.nekocode.gank.R
22-
import cn.nekocode.gank.activityRouter
2323
import cn.nekocode.gank.base.BaseActivity
24-
import cn.nekocode.gank.broadcast.BroadcastRouter
25-
import cn.nekocode.gank.registerLocalReceiver
2624
import com.evernote.android.state.StateSaver
27-
import kotlinx.android.synthetic.main.activity_main.*
2825

2926
/**
3027
* @author nekocode ([email protected])
@@ -35,26 +32,16 @@ class MainActivity : BaseActivity() {
3532
StateSaver.restoreInstanceState(this, savedInstanceState)
3633

3734
setContentView(R.layout.activity_main)
38-
fetchBtn.text = Html.fromHtml(getString(R.string.fetch_pic))
39-
fetchBtn.setOnClickListener {
40-
activityRouter.gotoPic(this)
41-
}
4235

43-
// Register local broadcast receiver
44-
registerLocalReceiver(BroadcastRouter.FETCH_SUC) { _, intent ->
45-
val action = (intent ?: return@registerLocalReceiver).action
46-
?: return@registerLocalReceiver
47-
when (action) {
48-
BroadcastRouter.FETCH_SUC -> {
49-
fetchBtn.text = getString(R.string.fetch_suc)
50-
fetchBtn.isEnabled = false
51-
}
52-
}
53-
}
36+
val navController = findNavController(R.id.frag_nav_host)
37+
setupActionBarWithNavController(navController)
5438
}
5539

5640
override fun onSaveInstanceState(outState: Bundle) {
5741
super.onSaveInstanceState(outState)
5842
StateSaver.saveInstanceState(this, outState)
5943
}
44+
45+
override fun onSupportNavigateUp() =
46+
findNavController(R.id.frag_nav_host).navigateUp()
6047
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2019. nekocode ([email protected])
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package cn.nekocode.gank.ui.home
18+
19+
import android.os.Bundle
20+
import android.text.Html
21+
import android.view.LayoutInflater
22+
import android.view.View
23+
import android.view.ViewGroup
24+
import androidx.navigation.fragment.findNavController
25+
import cn.nekocode.gank.R
26+
import cn.nekocode.gank.base.BaseFragment
27+
import com.evernote.android.state.StateSaver
28+
import kotlinx.android.synthetic.main.fragment_home.*
29+
30+
/**
31+
* @author nekocode ([email protected])
32+
*/
33+
class HomeFragment : BaseFragment() {
34+
override fun onCreate(savedInstanceState: Bundle?) {
35+
super.onCreate(savedInstanceState)
36+
StateSaver.restoreInstanceState(this, savedInstanceState)
37+
}
38+
39+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
40+
savedInstanceState: Bundle?): View? {
41+
return inflater.inflate(R.layout.fragment_home, container, false)
42+
}
43+
44+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
45+
super.onViewCreated(view, savedInstanceState)
46+
47+
fetchBtn.text = Html.fromHtml(getString(R.string.fetch_pic))
48+
fetchBtn.setOnClickListener {
49+
findNavController().navigate(HomeFragmentDirections.actionHomeToPic())
50+
}
51+
}
52+
53+
override fun onSaveInstanceState(outState: Bundle) {
54+
super.onSaveInstanceState(outState)
55+
StateSaver.saveInstanceState(this, outState)
56+
}
57+
}

app/src/main/java/cn/nekocode/gank/ui/pic/PicActivity.kt renamed to app/src/main/java/cn/nekocode/gank/ui/pic/PicFragment.kt

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018. nekocode ([email protected])
2+
* Copyright 2019. nekocode ([email protected])
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,34 +17,41 @@
1717
package cn.nekocode.gank.ui.pic
1818

1919
import android.os.Bundle
20+
import android.view.LayoutInflater
21+
import android.view.View
22+
import android.view.ViewGroup
2023
import android.widget.Toast
2124
import cn.nekocode.gank.R
2225
import cn.nekocode.gank.backend.model.MeiziPic
23-
import cn.nekocode.gank.base.BaseActivity
24-
import cn.nekocode.gank.broadcastRouter
2526
import cn.nekocode.gank.apis
27+
import cn.nekocode.gank.base.BaseFragment
2628
import com.evernote.android.state.State
2729
import com.evernote.android.state.StateSaver
2830
import com.squareup.picasso.Picasso
2931
import io.reactivex.Single
3032
import io.reactivex.android.schedulers.AndroidSchedulers
3133
import io.reactivex.schedulers.Schedulers
32-
import kotlinx.android.synthetic.main.activity_pic.*
34+
import kotlinx.android.synthetic.main.fragment_pic.*
3335

3436
/**
3537
* @author nekocode ([email protected])
3638
*/
37-
class PicActivity : BaseActivity() {
39+
class PicFragment : BaseFragment() {
3840
@State
3941
var pic: MeiziPic? = null
4042

4143
override fun onCreate(savedInstanceState: Bundle?) {
4244
super.onCreate(savedInstanceState)
4345
StateSaver.restoreInstanceState(this, savedInstanceState)
46+
}
47+
48+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
49+
savedInstanceState: Bundle?): View? {
50+
return inflater.inflate(R.layout.fragment_pic, container, false)
51+
}
4452

45-
setContentView(R.layout.activity_pic)
46-
supportActionBar?.setDisplayHomeAsUpEnabled(true)
47-
title = getString(R.string.fetching_data)
53+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
54+
super.onViewCreated(view, savedInstanceState)
4855
showPic()
4956
}
5057

@@ -63,12 +70,10 @@ class PicActivity : BaseActivity() {
6370
.observeOn(AndroidSchedulers.mainThread())
6471
.autoDisposable()
6572
.subscribe({ pic ->
66-
title = pic.id
67-
Picasso.with(this).load(pic.url).centerCrop().fit().into(imageView)
68-
broadcastRouter.tellFetchSuc(this)
73+
Picasso.with(requireActivity()).load(pic.url).centerCrop().fit().into(imageView)
6974

70-
}, { _ ->
71-
Toast.makeText(this, R.string.sth_went_wrong, Toast.LENGTH_SHORT).show()
75+
}, {
76+
Toast.makeText(requireActivity(), R.string.sth_went_wrong, Toast.LENGTH_SHORT).show()
7277
})
7378
}
7479

app/src/main/res/layout/activity_main.xml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
xmlns:tools="http://schemas.android.com/tools"
66
android:layout_width="match_parent"
77
android:layout_height="match_parent"
8-
tools:context=".ui.home.MainActivity"
8+
tools:context=".ui.MainActivity"
99
>
1010

11-
<Button
12-
android:id="@+id/fetchBtn"
13-
android:layout_width="wrap_content"
14-
android:layout_height="wrap_content"
15-
android:textAllCaps="false"
16-
app:layout_constraintBottom_toBottomOf="parent"
11+
<fragment
12+
android:id="@+id/frag_nav_host"
13+
android:name="androidx.navigation.fragment.NavHostFragment"
14+
android:layout_width="0dp"
15+
android:layout_height="0dp"
1716
app:layout_constraintLeft_toLeftOf="parent"
1817
app:layout_constraintRight_toRightOf="parent"
1918
app:layout_constraintTop_toTopOf="parent"
20-
tools:text="@string/fetch_pic"
19+
app:layout_constraintBottom_toBottomOf="parent"
20+
app:defaultNavHost="true"
21+
app:navGraph="@navigation/nav_main"
2122
/>
2223

2324
</androidx.constraintlayout.widget.ConstraintLayout>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:app="http://schemas.android.com/apk/res-auto"
5+
xmlns:tools="http://schemas.android.com/tools"
6+
android:layout_width="match_parent"
7+
android:layout_height="match_parent"
8+
tools:context=".ui.home.HomeFragment"
9+
>
10+
11+
<Button
12+
android:id="@+id/fetchBtn"
13+
android:layout_width="wrap_content"
14+
android:layout_height="wrap_content"
15+
android:textAllCaps="false"
16+
app:layout_constraintBottom_toBottomOf="parent"
17+
app:layout_constraintLeft_toLeftOf="parent"
18+
app:layout_constraintRight_toRightOf="parent"
19+
app:layout_constraintTop_toTopOf="parent"
20+
tools:text="@string/fetch_pic"
21+
/>
22+
23+
</androidx.constraintlayout.widget.ConstraintLayout>

0 commit comments

Comments
 (0)