a
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.aisier">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:icon="@mipmap/icon_android"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".ui.SecondActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.aisier
|
||||
|
||||
import com.aisier.architecture.base.BaseApp
|
||||
import com.ldlywt.colorful.ColorThemeConfig
|
||||
import com.ldlywt.colorful.initColorful
|
||||
|
||||
class App : BaseApp() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
val colorThemeConfig = ColorThemeConfig(
|
||||
useDarkTheme = true,
|
||||
translucent = false,
|
||||
customTheme = R.style.Theme_Red
|
||||
)
|
||||
initColorful(this, colorThemeConfig)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.aisier.bean
|
||||
|
||||
data class User(
|
||||
val admin: Boolean?,
|
||||
val chapterTops: List<Any>?,
|
||||
val email: String?,
|
||||
val icon: String?,
|
||||
val id: Int?,
|
||||
val nickname: String?,
|
||||
val publicName: String?,
|
||||
val username: String?
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.aisier.bean
|
||||
|
||||
/**
|
||||
* author : wutao
|
||||
* time : 2020/01/01
|
||||
* desc :
|
||||
* version: 1.0
|
||||
*/
|
||||
class WxArticleBean {
|
||||
/**
|
||||
* id : 408
|
||||
* name : 鸿洋
|
||||
* order : 190000
|
||||
* visible : 1
|
||||
*/
|
||||
var id = 0
|
||||
var name: String? = null
|
||||
var visible = 0
|
||||
|
||||
override fun toString(): String {
|
||||
return "TestBean(id=$id, name=$name, visible=$visible)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.aisier.net
|
||||
|
||||
import com.aisier.bean.User
|
||||
import com.aisier.bean.WxArticleBean
|
||||
import com.aisier.network.entity.ApiResponse
|
||||
import retrofit2.http.Field
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface ApiService {
|
||||
|
||||
@GET("wxarticle/chapters/json")
|
||||
suspend fun getWxArticle(): ApiResponse<List<WxArticleBean>>
|
||||
|
||||
@GET("abc/chapters/json")
|
||||
suspend fun getWxArticleError(): ApiResponse<List<WxArticleBean>>
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("user/login")
|
||||
suspend fun login(@Field("username") userName: String, @Field("password") passWord: String): ApiResponse<User?>
|
||||
|
||||
companion object {
|
||||
const val BASE_URL = "https://wanandroid.com/"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.aisier.net
|
||||
|
||||
import com.aisier.network.base.BaseRetrofitClient
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
object RetrofitClient : BaseRetrofitClient() {
|
||||
|
||||
val service by lazy { getService(ApiService::class.java, ApiService.BASE_URL) }
|
||||
|
||||
override fun handleBuilder(builder: OkHttpClient.Builder) = Unit
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.aisier.net
|
||||
|
||||
import com.aisier.bean.User
|
||||
import com.aisier.bean.WxArticleBean
|
||||
import com.aisier.network.base.BaseRepository
|
||||
import com.aisier.network.entity.ApiResponse
|
||||
|
||||
class WxArticleRepository : BaseRepository() {
|
||||
|
||||
private val mService by lazy {
|
||||
RetrofitClient.service
|
||||
}
|
||||
|
||||
suspend fun fetchWxArticleFromNet(): ApiResponse<List<WxArticleBean>> {
|
||||
return executeHttp {
|
||||
mService.getWxArticle()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun fetchWxArticleError(): ApiResponse<List<WxArticleBean>> {
|
||||
return executeHttp {
|
||||
mService.getWxArticleError()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun login(username: String, password: String): ApiResponse<User?> {
|
||||
return executeHttp {
|
||||
mService.login(username, password)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.aisier.ui
|
||||
|
||||
import com.aisier.R
|
||||
import com.aisier.architecture.base.BaseActivity
|
||||
|
||||
class MainActivity : BaseActivity(R.layout.activity_home)
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.aisier.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.aisier.R
|
||||
import com.aisier.architecture.base.BaseActivity
|
||||
import com.ldlywt.colorful.ColorTheme
|
||||
import com.ldlywt.colorful.ThemeStyle
|
||||
|
||||
class SecondActivity : BaseActivity(R.layout.activity_second) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
findViewById<View>(R.id.bt_change_theme).setOnClickListener {
|
||||
ColorTheme().edit()
|
||||
.setDarkTheme(false)
|
||||
.setCustomThemeOverride(ThemeStyle.values().random().res)
|
||||
.applyAndRestart(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.aisier.ui.fragment
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import androidx.navigation.findNavController
|
||||
import com.aisier.R
|
||||
import com.aisier.architecture.base.BaseFragment
|
||||
import com.aisier.ui.SecondActivity
|
||||
|
||||
class MainFragment : BaseFragment(R.layout.fragment_main) {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
view.findViewById<View>(R.id.bt_api).setOnClickListener {
|
||||
view.findNavController().navigate(R.id.netListFragment)
|
||||
}
|
||||
view.findViewById<Button>(R.id.bt_save_state).setOnClickListener {
|
||||
view.findNavController().navigate(R.id.savedStateFragment)
|
||||
}
|
||||
view.findViewById<Button>(R.id.bt_change_theme).setOnClickListener {
|
||||
requireActivity().startActivity(Intent(requireActivity(), SecondActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.aisier.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.asLiveData
|
||||
import com.aisier.R
|
||||
import com.aisier.architecture.base.BaseFragment
|
||||
import com.aisier.architecture.util.collectIn
|
||||
import com.aisier.architecture.util.launchFlow
|
||||
import com.aisier.architecture.util.launchWithLoading
|
||||
import com.aisier.architecture.util.launchWithLoadingAndCollect
|
||||
import com.aisier.bean.WxArticleBean
|
||||
import com.aisier.databinding.FragmentNetListBinding
|
||||
import com.aisier.network.observeState
|
||||
import com.aisier.network.toast
|
||||
import com.aisier.vm.ApiViewModel
|
||||
import com.dylanc.viewbinding.binding
|
||||
|
||||
/**
|
||||
* dev 分支去掉LiveData,使用Flow
|
||||
*/
|
||||
class NetListFragment : BaseFragment(R.layout.fragment_net_list) {
|
||||
|
||||
// navigation情况下不能用Activity的ViewModel
|
||||
private val mViewModel by viewModels<ApiViewModel>()
|
||||
private val mBinding: FragmentNetListBinding by binding()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initData()
|
||||
initObserver()
|
||||
}
|
||||
|
||||
private fun initObserver() {
|
||||
mViewModel.uiState.collectIn(this, Lifecycle.State.STARTED) {
|
||||
onSuccess = { result: List<WxArticleBean>? ->
|
||||
showNetErrorPic(false)
|
||||
mBinding.tvContent.text = result.toString()
|
||||
}
|
||||
|
||||
onComplete = { Log.i("NetListFragment", ": onComplete") }
|
||||
|
||||
onFailed = { code, msg -> toast("errorCode: $code errorMsg: $msg") }
|
||||
|
||||
onError = { showNetErrorPic(true) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNetErrorPic(isShowError: Boolean) {
|
||||
mBinding.tvContent.isGone = isShowError
|
||||
mBinding.ivContent.isVisible = isShowError
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
mBinding.btnNet.setOnClickListener { requestNet() }
|
||||
|
||||
mBinding.btnNetError.setOnClickListener {
|
||||
showNetErrorPic(false)
|
||||
requestNetError()
|
||||
}
|
||||
|
||||
mBinding.btLogin.setOnClickListener {
|
||||
showNetErrorPic(false)
|
||||
login()
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestNet() = launchWithLoading(mViewModel::requestNet)
|
||||
|
||||
private fun requestNetError() = launchWithLoading(mViewModel::requestNetError)
|
||||
|
||||
/**
|
||||
* 链式调用,返回结果的处理都在一起,viewmodel中不需要创建一个livedata对象
|
||||
* 适用于不需要监听数据变化的场景
|
||||
* 屏幕旋转,Activity销毁重建,数据会消失
|
||||
*/
|
||||
private fun login() {
|
||||
launchWithLoadingAndCollect({
|
||||
mViewModel.login("FastJetpack", "FastJetpack")
|
||||
}) {
|
||||
onSuccess = {
|
||||
mBinding.tvContent.text = it.toString()
|
||||
}
|
||||
onFailed = { errorCode, errorMsg ->
|
||||
toast("errorCode: $errorCode errorMsg: $errorMsg")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Flow转变为LiveData
|
||||
*/
|
||||
private fun loginAsLiveData() {
|
||||
val loginLiveData =
|
||||
launchFlow(requestBlock = {
|
||||
mViewModel.login(
|
||||
"FastJetpack",
|
||||
"FastJetpack11"
|
||||
)
|
||||
}).asLiveData()
|
||||
|
||||
loginLiveData.observeState(this) {
|
||||
onSuccess = { mBinding.tvContent.text = it.toString() }
|
||||
onFailed =
|
||||
{ errorCode, errorMsg -> toast("errorCode: $errorCode errorMsg: $errorMsg") }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.aisier.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.aisier.R
|
||||
import com.aisier.vm.SavedStateViewModel
|
||||
|
||||
class SavedStateFragment : Fragment(R.layout.fragment_saved_state) {
|
||||
|
||||
private val stateViewModel by viewModels<SavedStateViewModel>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
Log.i("SavedStateActivity--> ", "SavedStateViewModel: $stateViewModel")
|
||||
Log.i("SavedStateActivity--> ", "userName: ${stateViewModel.userName}")
|
||||
val value: String = stateViewModel.inputLiveData.value.toString()
|
||||
Log.i("SavedStateActivity--> ", "input text: ${value}")
|
||||
|
||||
val submit = view.findViewById<Button>(R.id.submit)
|
||||
val editText = view.findViewById<EditText>(R.id.edit_text)
|
||||
|
||||
submit.setOnClickListener {
|
||||
stateViewModel.userName = "Hello world"
|
||||
val inputText: String = editText.toString()
|
||||
stateViewModel.inputLiveData.value = inputText
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.aisier.vm
|
||||
|
||||
import com.aisier.architecture.base.BaseViewModel
|
||||
import com.aisier.bean.User
|
||||
import com.aisier.bean.WxArticleBean
|
||||
import com.aisier.net.WxArticleRepository
|
||||
import com.aisier.network.entity.ApiResponse
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* @author : wutao
|
||||
* time : 2019/08/17
|
||||
* desc :
|
||||
* version: 1.0
|
||||
</pre> *
|
||||
*/
|
||||
class ApiViewModel : BaseViewModel() {
|
||||
|
||||
private val repository by lazy { WxArticleRepository() }
|
||||
|
||||
// 使用StateFlow 替代livedata
|
||||
// val wxArticleLiveData = StateMutableLiveData<List<WxArticleBean>>()
|
||||
|
||||
private val _uiState = MutableStateFlow<ApiResponse<List<WxArticleBean>>>(ApiResponse())
|
||||
val uiState: StateFlow<ApiResponse<List<WxArticleBean>>> = _uiState.asStateFlow()
|
||||
|
||||
suspend fun requestNet() {
|
||||
_uiState.value = repository.fetchWxArticleFromNet()
|
||||
}
|
||||
|
||||
suspend fun requestNetError() {
|
||||
_uiState.value = repository.fetchWxArticleError()
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景:不需要监听数据变化
|
||||
*/
|
||||
suspend fun login(username: String, password: String): ApiResponse<User?> {
|
||||
return repository.login(username, password)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.aisier.vm
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
|
||||
|
||||
companion object {
|
||||
const val SAVE_STATE_KEY_STRING = "user_name"
|
||||
const val SAVE_STATE_KEY_LIVE_DATE = "input_livedata"
|
||||
}
|
||||
|
||||
var userName: String?
|
||||
get() = savedStateHandle.get(SAVE_STATE_KEY_STRING)
|
||||
set(value) = savedStateHandle.set(SAVE_STATE_KEY_STRING, value)
|
||||
|
||||
val inputLiveData = savedStateHandle.getLiveData<String>(SAVE_STATE_KEY_LIVE_DATE)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_graph" />
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.SecondActivity">
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt_change_theme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="改变主题" />
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="占位" />
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<SeekBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:progress="50" />
|
||||
|
||||
<Switch
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/app_name" />
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TimePicker
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.fragment.MainFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt_api"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:text="网络请求封装" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt_save_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:text="数据恢复" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt_change_theme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:text="随机改变主题" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.fragment.NetListFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt_login"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_weight="1"
|
||||
android:text="登录" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_net"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="请求网络" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_net_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="请求网络错误" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_weight="1"
|
||||
android:text="网络请求结果:" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="400dp"
|
||||
android:layout_margin="10dp"
|
||||
android:src="@mipmap/icon_net_error"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入名字" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/submit"
|
||||
android:text="提交"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph"
|
||||
app:startDestination="@id/mainFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/mainFragment"
|
||||
android:name="com.aisier.ui.fragment.MainFragment"
|
||||
android:label="fragment_main"
|
||||
tools:layout="@layout/fragment_main">
|
||||
<action
|
||||
android:id="@+id/action_mainFragment_to_netListFragment"
|
||||
app:destination="@id/netListFragment" />
|
||||
<action
|
||||
android:id="@+id/action_mainFragment_to_savedStateFragment"
|
||||
app:destination="@id/savedStateFragment" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/netListFragment"
|
||||
android:name="com.aisier.ui.fragment.NetListFragment"
|
||||
android:label="fragment_net_list"
|
||||
tools:layout="@layout/fragment_net_list" />
|
||||
<fragment
|
||||
android:id="@+id/savedStateFragment"
|
||||
android:name="com.aisier.ui.fragment.SavedStateFragment"
|
||||
android:label="fragment_saved_state"
|
||||
tools:layout="@layout/fragment_saved_state" />
|
||||
</navigation>
|
||||
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">FastJetpack</string>
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
</network-security-config>
|
||||
|
||||
Reference in New Issue
Block a user