Update Compose
This commit is contained in:
+7
-21
@@ -10,11 +10,11 @@ android {
|
||||
compileSdkVersion = 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.lsp.view"
|
||||
applicationId "moe.uni.moe"
|
||||
minSdkVersion 29
|
||||
targetSdkVersion 34
|
||||
versionCode 221022
|
||||
versionName "1.2.7"
|
||||
versionCode 240629
|
||||
versionName "2.0.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
@@ -27,12 +27,10 @@ android {
|
||||
debuggable true
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
@@ -42,7 +40,7 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
namespace 'com.lsp.view'
|
||||
namespace 'moe.uni.view'
|
||||
buildFeatures {
|
||||
compose true
|
||||
}
|
||||
@@ -58,7 +56,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation("androidx.navigation:navigation-compose:2.7.7")
|
||||
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.9.1")
|
||||
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.2'
|
||||
@@ -73,29 +70,18 @@ dependencies {
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
|
||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
||||
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
||||
def room_version = "2.5.0"
|
||||
implementation("io.coil-kt:coil-compose:2.6.0")
|
||||
|
||||
def room_version = "2.6.1"
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
implementation "androidx.room:room-ktx:$room_version"
|
||||
annotationProcessor "androidx.room:room-compiler:$room_version"
|
||||
ksp "androidx.room:room-compiler:$room_version"
|
||||
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
|
||||
implementation("com.google.android.material:material:1.10.0")
|
||||
implementation 'jp.wasabeef:recyclerview-animators:4.0.2'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||
implementation ('androidx.swiperefreshlayout:swiperefreshlayout:1.1.0')
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.2")
|
||||
implementation ('com.squareup.retrofit2:retrofit:2.9.0')
|
||||
implementation ('com.squareup.retrofit2:converter-gson:2.9.0')
|
||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.5'
|
||||
implementation "androidx.navigation:navigation-ui-ktx:2.7.5"
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.22"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
|
||||
implementation 'androidx.core:core-ktx:1.13.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="com.lsp.view.fileprovider"
|
||||
android:authorities="moe.uni.view.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
@@ -38,11 +38,7 @@
|
||||
android:name=".service.DownloadService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
<activity
|
||||
android:name=".ui.activity.MainActivity"
|
||||
android:exported="true">
|
||||
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,190 +0,0 @@
|
||||
package com.lsp.view.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.AbstractSavedStateViewModelFactory
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.lsp.view.ui.fragment.adapter.PostAdapter
|
||||
import com.lsp.view.repository.network.PostRepository
|
||||
import androidx.savedstate.SavedStateRegistryOwner
|
||||
import com.lsp.view.YandViewApplication
|
||||
import com.lsp.view.bean.YandPost
|
||||
import com.lsp.view.repository.datasource.CollectDatabase
|
||||
import com.lsp.view.repository.datasource.CollectRepository
|
||||
import com.lsp.view.repository.datasource.CollectRepositoryImpl
|
||||
import com.lsp.view.repository.datasource.model.Collect
|
||||
import com.lsp.view.repository.exception.NetworkErrorException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainViewModel(private val repository: PostRepository, context: Context):ViewModel() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState:StateFlow<UiState>
|
||||
get() = _uiState.asStateFlow()
|
||||
private var fetchJob: Job? = null
|
||||
private val TAG = this::class.java.simpleName
|
||||
private val _toastMessage = MutableLiveData<String>()
|
||||
val toastMessage
|
||||
get() = _toastMessage as LiveData<String>
|
||||
|
||||
private val _postList = MutableLiveData<ArrayList<YandPost>>()
|
||||
val postList get() = _postList as LiveData<ArrayList<YandPost>>
|
||||
val adapter by lazy {
|
||||
fetchPostByRefresh()
|
||||
PostAdapter(context)
|
||||
}
|
||||
private val _collectList:MutableLiveData<List<Collect>> = MutableLiveData()
|
||||
val collectList:LiveData<List<Collect>>
|
||||
get() = _collectList
|
||||
|
||||
private val collectRepository: CollectRepository by lazy {
|
||||
CollectRepositoryImpl(CollectDatabase.getDatabase(context).collectDao())
|
||||
}
|
||||
|
||||
@Volatile private var isProcessing = false
|
||||
private val _tagsList = MutableLiveData<ArrayList<String>>()
|
||||
val tagsList get() = _tagsList as LiveData<ArrayList<String>>
|
||||
|
||||
|
||||
companion object {
|
||||
fun provideFactory(
|
||||
repository: PostRepository,
|
||||
context: Context,
|
||||
owner: SavedStateRegistryOwner,
|
||||
defaultArgs: Bundle? = null,
|
||||
|
||||
): AbstractSavedStateViewModelFactory =
|
||||
object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(
|
||||
key: String,
|
||||
modelClass: Class<T>,
|
||||
handle: SavedStateHandle
|
||||
): T {
|
||||
return MainViewModel(repository, context) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
init {
|
||||
//初始化写入
|
||||
val configSp = context.getSharedPreferences("com.lsp.view_preferences", 0)
|
||||
if (configSp.getString("source_name", null) == null) {
|
||||
configSp.edit().putString("source_name", "yande.re").apply()
|
||||
configSp.edit().putString("type", "0").apply()
|
||||
}
|
||||
|
||||
_uiState.update {
|
||||
it.apply {
|
||||
it.nowSourceName.postValue(configSp.getString("source_name",null))
|
||||
}
|
||||
|
||||
it.copy(isSafe = configSp.getBoolean("safe_mode",true))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun fetchNewPost() {
|
||||
fetchJob?.cancel()
|
||||
fetchJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
_uiState.value.isRefreshing.postValue(true)
|
||||
try {
|
||||
val newPosts = repository.fetchPostData(
|
||||
_uiState.value.nowSearchText.value,
|
||||
_uiState.value.nowPage
|
||||
)
|
||||
val currentPosts = _postList.value ?: arrayListOf()
|
||||
currentPosts.addAll(0,newPosts)
|
||||
_postList.postValue(currentPosts)
|
||||
} catch (e: NetworkErrorException) {
|
||||
postNewToast(e.message.toString())
|
||||
}
|
||||
_uiState.value.isRefreshing.postValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun fetchPostByRefresh(){
|
||||
_uiState.update {
|
||||
it.copy(nowPage = 1)
|
||||
}
|
||||
|
||||
fetchNewPost()
|
||||
}
|
||||
|
||||
fun fetchPostBySearch(searchTarget:String){
|
||||
_uiState.update {
|
||||
it.apply {
|
||||
it.nowSearchText.postValue(searchTarget)
|
||||
}
|
||||
}
|
||||
|
||||
fetchNewPost()
|
||||
}
|
||||
|
||||
fun fetchMore(){
|
||||
_uiState.value.nowPage++
|
||||
fetchNewPost()
|
||||
}
|
||||
|
||||
fun updateSafeMode(mode:Boolean){
|
||||
_uiState.update {
|
||||
it.copy(isSafe = mode)
|
||||
}
|
||||
fetchNewPost()
|
||||
}
|
||||
|
||||
fun updateNowSource(source:String){
|
||||
_uiState.value.nowSourceName.postValue(source)
|
||||
fetchPostByRefresh()
|
||||
}
|
||||
|
||||
fun getCollectList(){
|
||||
viewModelScope.launch {
|
||||
_collectList.postValue(collectRepository.getAllCollect())
|
||||
}
|
||||
}
|
||||
|
||||
fun addCollect(collect: Collect){
|
||||
if (!isProcessing){
|
||||
viewModelScope.launch {
|
||||
collectRepository.addNewCollect(collect)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeCollect(collect:Collect){
|
||||
|
||||
if (!isProcessing){
|
||||
viewModelScope.launch {
|
||||
collectRepository.removeCollect(collect)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
suspend fun getCollectByPostId(postId:String) = viewModelScope.async {
|
||||
val type = YandViewApplication.context?.getSharedPreferences("com.lsp.view_preferences",Context.MODE_PRIVATE)?.getString("source_name", "yande.re")
|
||||
collectRepository.getCollectByPostId(postId,type!!)
|
||||
}
|
||||
|
||||
fun postNewToast(content:String){
|
||||
_toastMessage.postValue(content)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.lsp.view.ui
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
||||
data class UiState(
|
||||
var showSearchBar:Boolean = false,
|
||||
val isRefreshing:MutableLiveData<Boolean> = MutableLiveData(),
|
||||
var nowSearchText:MutableLiveData<String> = MutableLiveData(""),
|
||||
val nowSourceName: MutableLiveData<String> = MutableLiveData(),
|
||||
val isSafe: Boolean = true, //安全模式
|
||||
var nowPage:Int = 1,
|
||||
)
|
||||
@@ -1,60 +0,0 @@
|
||||
package com.lsp.view.ui.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.ui.MainViewModel
|
||||
import com.lsp.view.repository.network.PostRepository
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
val TAG = javaClass.simpleName
|
||||
lateinit var viewModel: MainViewModel
|
||||
lateinit var bottomNav:BottomNavigationView
|
||||
val repository = PostRepository()
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
viewModel = MainViewModel.provideFactory(repository, this,this).create(MainViewModel::class.java)
|
||||
|
||||
bottomNav = findViewById(R.id.bottom_navigation)
|
||||
|
||||
viewModel.toastMessage.observe(this){
|
||||
Toast.makeText(this,it,Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
val navController = navHostFragment.navController
|
||||
bottomNav.setupWithNavController(navController)
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
//加载源改变
|
||||
val configSp = getSharedPreferences("com.lsp.view_preferences", 0)
|
||||
|
||||
val nowSourceName = configSp.getString("source_name", null)
|
||||
|
||||
if (nowSourceName != null && viewModel.uiState.value.nowSourceName.value != nowSourceName){
|
||||
viewModel.updateNowSource(nowSourceName)
|
||||
}
|
||||
|
||||
val nowMode = configSp.getBoolean("safe_mode", true)
|
||||
if (viewModel.uiState.value.isSafe != nowMode){
|
||||
viewModel.updateSafeMode(nowMode)
|
||||
Log.e(TAG,nowMode.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package com.lsp.view.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.AnimationUtils
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.lsp.view.ui.fragment.adapter.PostAdapter
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.ui.activity.MainActivity
|
||||
import com.lsp.view.bean.Post
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass.
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
class CollectFragment : Fragment() {
|
||||
private lateinit var activityContext: MainActivity
|
||||
private val collectAdapter by lazy {
|
||||
PostAdapter(activityContext)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
activityContext = requireActivity() as MainActivity
|
||||
|
||||
activityContext.viewModel.getCollectList()
|
||||
|
||||
activityContext.viewModel.collectList.observe(this){
|
||||
collectAdapter.pushNewData(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_collect, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
//刷新
|
||||
val refresh =
|
||||
view.findViewById<androidx.swiperefreshlayout.widget.SwipeRefreshLayout>(R.id.swipeRefreshLayout)
|
||||
|
||||
activityContext.viewModel.uiState.value.isRefreshing.observe(activityContext) {
|
||||
refresh.isRefreshing = it
|
||||
}
|
||||
|
||||
collectAdapter.setOnListItemClick(object : PostAdapter.OnListItemClick {
|
||||
override fun setOnListItemClick(post: Post) {
|
||||
ImageFragment.navigationToImageFragment(activityContext,post,view,R.id.action_collectFragment_to_imageFragment)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
view.findViewById<RecyclerView>(R.id.recyclerview).apply {
|
||||
val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||
this.layoutManager = layoutManager
|
||||
this.adapter = collectAdapter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (activityContext.bottomNav.visibility == View.GONE){
|
||||
val slideOutAnimation = AnimationUtils.loadAnimation(context, R.anim.slide_on_bottom)
|
||||
activityContext.bottomNav.startAnimation(slideOutAnimation)
|
||||
activityContext.bottomNav.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
package com.lsp.view.ui.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.widget.ImageView
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.Navigation
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.load.model.LazyHeaders
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.YandViewApplication
|
||||
import com.lsp.view.ui.activity.MainActivity
|
||||
import com.lsp.view.bean.Post
|
||||
import com.lsp.view.repository.datasource.model.Collect
|
||||
import com.lsp.view.repository.datasource.model.Collect.Companion.toCollect
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
class ImageFragment : Fragment() {
|
||||
private val post by lazy {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
arguments?.getParcelable("post",Post::class.java)
|
||||
}else{
|
||||
arguments?.getParcelable("post")
|
||||
}
|
||||
}
|
||||
@Volatile private var isCollect = false
|
||||
private val activityContext : MainActivity by lazy {
|
||||
requireActivity() as MainActivity
|
||||
}
|
||||
private lateinit var collectBtn:MenuItem
|
||||
private lateinit var collect:Collect
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_image, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val bottomAppBar = view.findViewById<BottomAppBar>(R.id.bottomAppBar)
|
||||
collectBtn = bottomAppBar.menu.findItem(R.id.collect_menu_btn)
|
||||
collectBtn.setIcon(R.drawable.ic_bashline_unfavorite_24)
|
||||
bottomAppBar.setOnMenuItemClickListener {
|
||||
when(it.itemId){
|
||||
R.id.share_menu_btn ->{
|
||||
post?.sampleUrl?.let { it1 -> share(it1,activityContext) }
|
||||
true
|
||||
}
|
||||
R.id.collect_menu_btn ->{
|
||||
if (!isCollect){
|
||||
collect = post!!.toCollect()
|
||||
collectIt(collect)
|
||||
}else{
|
||||
unCollectIt(collect)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
else -> {false}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
post?.postId?.let {
|
||||
val collectPost = activityContext.viewModel.getCollectByPostId(it)
|
||||
val result = collectPost.await()
|
||||
if (result != null){
|
||||
collect = result
|
||||
collectBtn.setIcon(R.drawable.ic_baseline_favorite_24)
|
||||
isCollect = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val downloadBtn = view.findViewById<FloatingActionButton>(R.id.download_btn)
|
||||
downloadBtn.setOnClickListener {
|
||||
lifecycleScope.launch {
|
||||
if (post!=null){
|
||||
download(post!!.fileUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (post!=null){
|
||||
val imageContent = view.findViewById<ImageView>(R.id.image_content)
|
||||
val glideUrl = GlideUrl(
|
||||
post!!.sampleUrl,
|
||||
LazyHeaders.Builder().addHeader("User-Agent", YandViewApplication.UA)
|
||||
.build()
|
||||
)
|
||||
Glide.with(this).load(glideUrl).into(imageContent)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun collectIt(collect: Collect){
|
||||
activityContext.viewModel.addCollect(collect)
|
||||
collectBtn.setIcon(R.drawable.ic_baseline_favorite_24)
|
||||
isCollect = true
|
||||
}
|
||||
|
||||
private fun unCollectIt(collect:Collect){
|
||||
activityContext.viewModel.removeCollect(collect)
|
||||
collectBtn.setIcon(R.drawable.ic_bashline_unfavorite_24)
|
||||
isCollect = false
|
||||
}
|
||||
|
||||
private fun download(fileUrl: String){
|
||||
|
||||
}
|
||||
|
||||
private fun share(url:String,context: Context){
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val bitmap = Glide.with(context).asBitmap().load(url).submit().get()
|
||||
val path = File("${context.cacheDir}/image")
|
||||
val split = url.split("/")
|
||||
val fileName = split[split.size - 1]
|
||||
if (!path.exists())
|
||||
path.mkdirs()
|
||||
|
||||
|
||||
var file = File("${context.cacheDir}/image/$fileName")
|
||||
val downloadFile =
|
||||
File("${Environment.getExternalStorageDirectory()}/${Environment.DIRECTORY_PICTURES}/LspMake/$fileName")
|
||||
|
||||
if (downloadFile.exists()){
|
||||
file = downloadFile
|
||||
}else if (!file.exists()) {
|
||||
file.outputStream().apply {
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, this)
|
||||
}
|
||||
}
|
||||
val imageUri = FileProvider.getUriForFile(
|
||||
context,
|
||||
"com.lsp.view.fileprovider",
|
||||
file
|
||||
|
||||
)
|
||||
context.grantUriPermission(
|
||||
"com.lsp.view",
|
||||
imageUri,
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
)
|
||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||
shareIntent.type = "image/*"
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri)
|
||||
shareIntent.putExtra(Intent.EXTRA_TITLE,fileName)
|
||||
val intent = Intent.createChooser(shareIntent, R.string.title_share.toString())
|
||||
val resInfoList: List<ResolveInfo> = if (Build.VERSION.SDK_INT < 33) {
|
||||
context.packageManager
|
||||
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||
} else {
|
||||
context.packageManager.queryIntentActivities(
|
||||
intent,
|
||||
PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong())
|
||||
)
|
||||
}
|
||||
for (resolveInfo in resInfoList) {
|
||||
val packageName = resolveInfo.activityInfo.packageName
|
||||
context.grantUriPermission(
|
||||
packageName,
|
||||
imageUri,
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
companion object{
|
||||
fun navigationToImageFragment(context:MainActivity ,post:Post,view:View,fragmentId:Int){
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable("post",post)
|
||||
val tags = post.tags?.split(",")?.toList()
|
||||
|
||||
context.viewModel.tagsList.value?.apply {
|
||||
clear()
|
||||
tags?.let { addAll(it) }
|
||||
}
|
||||
|
||||
Navigation.findNavController(view).navigate(fragmentId,bundle)
|
||||
val slideOutAnimation = AnimationUtils.loadAnimation(context,
|
||||
R.anim.slide_out_bottom
|
||||
)
|
||||
context.bottomNav.startAnimation(slideOutAnimation)
|
||||
context.bottomNav.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
package com.lsp.view.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.google.android.material.search.SearchBar
|
||||
import com.google.android.material.search.SearchView
|
||||
import com.lsp.view.ui.fragment.adapter.PostAdapter
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.ui.activity.MainActivity
|
||||
import com.lsp.view.bean.Post
|
||||
import com.lsp.view.ui.MainViewModel
|
||||
|
||||
class PostListFragment:Fragment() {
|
||||
private val viewModel: MainViewModel by lazy {
|
||||
ViewModelProvider(requireActivity(),
|
||||
MainViewModel.provideFactory(activityContext.repository,requireContext(),this)).get(
|
||||
MainViewModel::class.java)
|
||||
}
|
||||
private lateinit var activityContext: MainActivity
|
||||
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_list, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
activityContext = requireActivity() as MainActivity
|
||||
val searchBar = view.findViewById<SearchBar>(R.id.search_bar)
|
||||
|
||||
val searchView = view.findViewById<SearchView>(R.id.search_view)
|
||||
searchView.editText.setOnEditorActionListener { v, actionId, event ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
viewModel.fetchPostBySearch(searchView.text.toString())
|
||||
searchBar.setText(searchView.text)
|
||||
searchView.hide()
|
||||
}
|
||||
|
||||
return@setOnEditorActionListener false
|
||||
}
|
||||
|
||||
viewModel.uiState.value.nowSearchText.observe(requireActivity()){
|
||||
searchView.setText(it)
|
||||
searchBar.setText(it)
|
||||
}
|
||||
|
||||
//刷新
|
||||
val refresh =
|
||||
view.findViewById<androidx.swiperefreshlayout.widget.SwipeRefreshLayout>(R.id.swipeRefreshLayout)
|
||||
viewModel.uiState.value.isRefreshing.observe(activityContext) {
|
||||
refresh.isRefreshing = it
|
||||
}
|
||||
refresh.setOnRefreshListener {
|
||||
viewModel.fetchPostByRefresh()
|
||||
}
|
||||
|
||||
viewModel.postList.observe(activityContext){
|
||||
viewModel.adapter.pushNewData(it)
|
||||
}
|
||||
|
||||
viewModel.adapter.apply {
|
||||
setLoadMoreListener(object : PostAdapter.OnScrollToBottom {
|
||||
override fun event(position: Int) {
|
||||
viewModel.fetchMore()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
view.findViewById<RecyclerView>(R.id.recyclerview).apply {
|
||||
val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||
this.layoutManager = layoutManager
|
||||
this.adapter = viewModel.adapter
|
||||
}
|
||||
|
||||
viewModel.adapter.setOnListItemClick(object : PostAdapter.OnListItemClick {
|
||||
override fun setOnListItemClick(post: Post) {
|
||||
ImageFragment.navigationToImageFragment(activityContext,post,view,R.id.action_postListFragment_to_imageFragment)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (activityContext.bottomNav.visibility == View.GONE){
|
||||
val slideOutAnimation = AnimationUtils.loadAnimation(context, R.anim.slide_on_bottom)
|
||||
activityContext.bottomNav.startAnimation(slideOutAnimation)
|
||||
activityContext.bottomNav.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.lsp.view.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.lsp.view.R
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package com.lsp.view.ui.fragment.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.load.model.LazyHeaders
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.YandViewApplication
|
||||
import com.lsp.view.bean.Post
|
||||
|
||||
|
||||
class PostAdapter(val context: Context,private val postList: ArrayList<Post> = ArrayList()):
|
||||
RecyclerView.Adapter<PostAdapter.ViewHolder>() {
|
||||
val TAG = this::class.java.simpleName
|
||||
private var inBottom:Boolean = false//当前列表是否在底部
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val picImage: ImageView = view.findViewById(R.id.image)
|
||||
|
||||
}
|
||||
|
||||
fun pushNewData(list: List<Post>) {
|
||||
if (inBottom) {
|
||||
//在底部,则追加数据
|
||||
val pos = postList.size
|
||||
postList.addAll(list)
|
||||
notifyItemRangeInserted(pos - 1, list.size)
|
||||
} else {
|
||||
//不在则刷新数据
|
||||
val oldSize = postList.size
|
||||
postList.clear()
|
||||
notifyItemRangeRemoved(0, oldSize)
|
||||
postList.addAll(list)
|
||||
notifyItemRangeInserted(0, list.size)
|
||||
}
|
||||
|
||||
inBottom = false//加入新数据后不在底部,若仍在底部说明无更多数据,也不必处理
|
||||
|
||||
}
|
||||
|
||||
|
||||
private lateinit var mOnListItemClick: OnListItemClick
|
||||
interface OnListItemClick {
|
||||
fun setOnListItemClick(post:Post)
|
||||
}
|
||||
fun setOnListItemClick(mOnListItemClick: OnListItemClick) {
|
||||
this.mOnListItemClick = mOnListItemClick
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.img_item_layout, parent, false)
|
||||
val viewHolder = ViewHolder(view)
|
||||
|
||||
viewHolder.picImage.setOnClickListener {
|
||||
val position = viewHolder.adapterPosition
|
||||
mOnListItemClick.setOnListItemClick(postList[position])
|
||||
}
|
||||
|
||||
|
||||
return viewHolder
|
||||
}
|
||||
|
||||
private lateinit var mScrollToBottom: OnScrollToBottom
|
||||
|
||||
interface OnScrollToBottom {
|
||||
fun event(position: Int)
|
||||
}
|
||||
|
||||
fun setLoadMoreListener(mLoadMoreListener: OnScrollToBottom) {
|
||||
this.mScrollToBottom = mLoadMoreListener
|
||||
}
|
||||
|
||||
private fun preLoad(p:Int){
|
||||
if (p%20==0){
|
||||
//执行预加载
|
||||
val last:Int = if (postList.size-p<20){
|
||||
postList.size-1
|
||||
}else{
|
||||
p+19
|
||||
}
|
||||
for(index in p..last){
|
||||
if (p>6) {
|
||||
val source: String = postList[index].sampleUrl
|
||||
val glideUrl = GlideUrl(
|
||||
source,
|
||||
LazyHeaders.Builder().addHeader("User-Agent", YandViewApplication.UA)
|
||||
.build()
|
||||
)
|
||||
Glide.with(context).download(glideUrl).preload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
preLoad(position)
|
||||
|
||||
val post = postList[position]
|
||||
|
||||
val source: String = post.sampleUrl
|
||||
|
||||
val height = postList[position].sampleHeight
|
||||
val width = postList[position].sampleWidth
|
||||
|
||||
//图片过长则缩减高度以保证显示完整
|
||||
if (width > height){
|
||||
holder.picImage.layoutParams.height = height / 2
|
||||
}else {
|
||||
holder.picImage.layoutParams.height = height
|
||||
}
|
||||
|
||||
|
||||
val glideUrl = GlideUrl(
|
||||
source,
|
||||
LazyHeaders.Builder().addHeader("User-Agent", YandViewApplication.UA)
|
||||
.build()
|
||||
)
|
||||
Glide.with(context).load(glideUrl).into(holder.picImage)
|
||||
|
||||
if (position == postList.size - 1 && postList.size > 6 ) {
|
||||
//到达底部
|
||||
inBottom = true
|
||||
if (this::mScrollToBottom.isInitialized) {
|
||||
mScrollToBottom.event(position)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return postList.size
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.lsp.view.ui.fragment.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.lsp.view.R
|
||||
|
||||
class TagsAdapter(private val tagList:List<String>):RecyclerView.Adapter<TagsAdapter.ViewHolder>() {
|
||||
inner class ViewHolder(view:View):RecyclerView.ViewHolder(view) {
|
||||
val tagItem = view.findViewById<TextView>(R.id.tag)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view =
|
||||
LayoutInflater.from(parent.context).inflate(R.layout.tags_item_layout, parent, false)
|
||||
val viewHolder = ViewHolder(view)
|
||||
|
||||
return viewHolder
|
||||
}
|
||||
|
||||
override fun getItemCount() = tagList.size
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.tagItem.text = tagList[position]
|
||||
}
|
||||
}
|
||||
+1
-4
@@ -1,9 +1,8 @@
|
||||
package com.lsp.view
|
||||
package moe.uni.view
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import android.content.Context
|
||||
import com.google.android.material.color.DynamicColors
|
||||
|
||||
class YandViewApplication : Application(), DefaultLifecycleObserver {
|
||||
|
||||
@@ -11,8 +10,6 @@ class YandViewApplication : Application(), DefaultLifecycleObserver {
|
||||
override fun onCreate() {
|
||||
super<Application>.onCreate()
|
||||
context = applicationContext
|
||||
|
||||
DynamicColors.applyToActivitiesIfAvailable(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.bean
|
||||
package moe.uni.view.bean
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.bean
|
||||
package moe.uni.view.bean
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.common
|
||||
package moe.uni.view.common
|
||||
|
||||
class Config(val safeMode:Boolean,val source:String) {
|
||||
companion object{
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.common
|
||||
package moe.uni.view.common
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
@@ -13,7 +13,7 @@ import androidx.core.content.FileProvider
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import coil.ImageLoader
|
||||
import coil.request.ImageRequest
|
||||
import com.lsp.view.R
|
||||
import moe.uni.view.R
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -95,7 +95,7 @@ suspend fun getImageInfo(url: String, context: Context): ImageInfo {
|
||||
}
|
||||
val imageUri = FileProvider.getUriForFile(
|
||||
context,
|
||||
"com.lsp.view.fileprovider",
|
||||
"moe.uni.view.fileprovider",
|
||||
file
|
||||
)
|
||||
return ImageInfo(path = file.path, name = fileName, uri = imageUri)
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.common
|
||||
package moe.uni.view.common
|
||||
|
||||
object PreKV {
|
||||
const val SOURCE_NAME = "source_name"
|
||||
@@ -6,5 +6,5 @@ object PreKV {
|
||||
}
|
||||
|
||||
object Pre{
|
||||
const val NAME = "com.lsp.view_preferences"
|
||||
const val NAME = "moe.uni.view_preferences"
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.lsp.view.common
|
||||
package moe.uni.view.common
|
||||
|
||||
import android.content.Context
|
||||
import com.lsp.view.YandViewApplication
|
||||
import moe.uni.view.YandViewApplication
|
||||
|
||||
object PreUtils {
|
||||
private val PRE = YandViewApplication.context!!.getSharedPreferences(Pre.NAME,Context.MODE_PRIVATE)
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package com.lsp.view.repository.datasource
|
||||
package moe.uni.view.repository.datasource
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.lsp.view.repository.datasource.dao.CollectDao
|
||||
import com.lsp.view.repository.datasource.model.Collect
|
||||
import moe.uni.view.repository.datasource.dao.CollectDao
|
||||
import moe.uni.view.repository.datasource.model.Collect
|
||||
|
||||
@Database(entities = [Collect::class], version = 1,exportSchema = false)
|
||||
abstract class CollectDatabase: RoomDatabase(){
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lsp.view.repository.datasource
|
||||
package moe.uni.view.repository.datasource
|
||||
|
||||
import com.lsp.view.repository.datasource.model.Collect
|
||||
import moe.uni.view.repository.datasource.model.Collect
|
||||
|
||||
interface CollectRepository {
|
||||
suspend fun addNewCollect(collect: Collect)
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.lsp.view.repository.datasource
|
||||
package moe.uni.view.repository.datasource
|
||||
|
||||
import com.lsp.view.repository.datasource.dao.CollectDao
|
||||
import com.lsp.view.repository.datasource.model.Collect
|
||||
import moe.uni.view.repository.datasource.dao.CollectDao
|
||||
import moe.uni.view.repository.datasource.model.Collect
|
||||
|
||||
class CollectRepositoryImpl(private val collectDao:CollectDao):CollectRepository {
|
||||
override suspend fun addNewCollect(collect: Collect) {
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package com.lsp.view.repository.datasource.dao
|
||||
package moe.uni.view.repository.datasource.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.lsp.view.repository.datasource.model.Collect
|
||||
import moe.uni.view.repository.datasource.model.Collect
|
||||
|
||||
@Dao
|
||||
interface CollectDao {
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
package com.lsp.view.repository.datasource.model
|
||||
package moe.uni.view.repository.datasource.model
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.lsp.view.YandViewApplication
|
||||
import com.lsp.view.bean.Post
|
||||
import moe.uni.view.YandViewApplication
|
||||
import moe.uni.view.bean.Post
|
||||
|
||||
@Entity(tableName = "collect")
|
||||
data class Collect(
|
||||
@@ -28,7 +28,7 @@ data class Collect(
|
||||
sampleWeight:Int,
|
||||
tags:String?
|
||||
): this(0, postId, sampleUrl, rating, fileUrl, sampleHeight, sampleWeight,
|
||||
YandViewApplication.context?.getSharedPreferences("com.lsp.view_preferences",Context.MODE_PRIVATE)?.getString("source_name", "yande.re")!!,tags)
|
||||
YandViewApplication.context?.getSharedPreferences("moe.uni.view_preferences",Context.MODE_PRIVATE)?.getString("source_name", "yande.re")!!,tags)
|
||||
companion object{
|
||||
fun Post.toCollect():Collect = Collect(this.postId,this.sampleUrl,this.rating,this.fileUrl,this.sampleHeight,this.sampleWidth ,this.tags)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.repository.exception
|
||||
package moe.uni.view.repository.exception
|
||||
|
||||
import android.util.Log
|
||||
|
||||
+1
-3
@@ -1,6 +1,4 @@
|
||||
package com.lsp.view.repository.exception
|
||||
|
||||
import okhttp3.ResponseBody
|
||||
package moe.uni.view.repository.exception
|
||||
|
||||
class NetworkErrorException(override val message: String?) : LoggerException(message) {
|
||||
}
|
||||
+1
-3
@@ -1,6 +1,4 @@
|
||||
package com.lsp.view.repository.exception
|
||||
|
||||
import java.lang.Exception
|
||||
package moe.uni.view.repository.exception
|
||||
|
||||
class UnableConstructObjectException(override val message: String?):LoggerException(message) {
|
||||
}
|
||||
+5
-10
@@ -1,14 +1,9 @@
|
||||
package com.lsp.view.repository.network
|
||||
package moe.uni.view.repository.network
|
||||
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.YandViewApplication
|
||||
import com.lsp.view.repository.exception.UnableConstructObjectException
|
||||
import com.lsp.view.repository.network.api.PostApi
|
||||
import com.lsp.view.repository.network.api.PostApiImpl
|
||||
import com.lsp.view.bean.YandPost
|
||||
import com.lsp.view.common.Config
|
||||
import com.lsp.view.common.Pre
|
||||
import com.lsp.view.common.PreKV
|
||||
import moe.uni.view.repository.network.api.PostApi
|
||||
import moe.uni.view.repository.network.api.PostApiImpl
|
||||
import moe.uni.view.bean.YandPost
|
||||
import moe.uni.view.common.Config
|
||||
|
||||
class PostDataSource {
|
||||
companion object{
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.lsp.view.repository.network
|
||||
package moe.uni.view.repository.network
|
||||
|
||||
import com.lsp.view.bean.YandPost
|
||||
import com.lsp.view.common.Config
|
||||
import moe.uni.view.bean.YandPost
|
||||
import moe.uni.view.common.Config
|
||||
|
||||
|
||||
class PostRepository {
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package com.lsp.view.repository.network.api
|
||||
package moe.uni.view.repository.network.api
|
||||
|
||||
import com.lsp.view.repository.network.Load
|
||||
import com.lsp.view.bean.Post
|
||||
import com.lsp.view.bean.YandPost
|
||||
import com.lsp.view.repository.exception.NetworkErrorException
|
||||
import moe.uni.view.repository.network.Load
|
||||
import moe.uni.view.bean.Post
|
||||
import moe.uni.view.bean.YandPost
|
||||
import moe.uni.view.repository.exception.NetworkErrorException
|
||||
import retrofit2.Call
|
||||
|
||||
interface PostApi {
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package com.lsp.view.repository.network.api
|
||||
package moe.uni.view.repository.network.api
|
||||
|
||||
import com.lsp.view.repository.network.Load
|
||||
import com.lsp.view.repository.network.retrofit.PostService
|
||||
import com.lsp.view.repository.network.retrofit.ServiceCreator
|
||||
import com.lsp.view.bean.YandPost
|
||||
import moe.uni.view.repository.network.Load
|
||||
import moe.uni.view.repository.network.retrofit.PostService
|
||||
import moe.uni.view.repository.network.retrofit.ServiceCreator
|
||||
import moe.uni.view.bean.YandPost
|
||||
import retrofit2.Call
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.lsp.view.repository.network.retrofit
|
||||
package moe.uni.view.repository.network.retrofit
|
||||
|
||||
import com.lsp.view.bean.YandPost
|
||||
import moe.uni.view.bean.YandPost
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.repository.network.retrofit
|
||||
package moe.uni.view.repository.network.retrofit
|
||||
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package com.lsp.view.service
|
||||
package moe.uni.view.service
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.media.MediaScannerConnection
|
||||
import android.os.*
|
||||
import com.lsp.view.repository.network.retrofit.ServiceCreator
|
||||
import moe.uni.view.repository.network.retrofit.ServiceCreator
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose
|
||||
package moe.uni.view.ui.compose
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
@@ -14,14 +14,14 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.lsp.view.ui.compose.theme.LspViewTheme
|
||||
import moe.uni.view.ui.compose.theme.LspViewTheme
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.lsp.view.service.DownloadService
|
||||
import com.lsp.view.ui.compose.screen.DetailScreen
|
||||
import com.lsp.view.ui.compose.screen.PostListScreen
|
||||
import moe.uni.view.service.DownloadService
|
||||
import moe.uni.view.ui.compose.screen.DetailScreen
|
||||
import moe.uni.view.ui.compose.screen.PostListScreen
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package com.lsp.view.ui.compose
|
||||
package moe.uni.view.ui.compose
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.lsp.view.bean.Post
|
||||
import moe.uni.view.bean.Post
|
||||
|
||||
data class PostUiState(
|
||||
var refresh:MutableState<Boolean> = mutableStateOf(true),
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
package com.lsp.view.ui.compose
|
||||
package moe.uni.view.ui.compose
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.lsp.view.bean.YandPost
|
||||
import com.lsp.view.repository.exception.NetworkErrorException
|
||||
import com.lsp.view.repository.network.PostRepository
|
||||
import com.lsp.view.service.Result
|
||||
import moe.uni.view.bean.YandPost
|
||||
import moe.uni.view.repository.exception.NetworkErrorException
|
||||
import moe.uni.view.repository.network.PostRepository
|
||||
import moe.uni.view.service.Result
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
+7
-6
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose.screen
|
||||
package moe.uni.view.ui.compose.screen
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.background
|
||||
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Share
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
@@ -29,10 +30,10 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.navigation.NavController
|
||||
import coil.compose.AsyncImage
|
||||
import com.lsp.view.R
|
||||
import com.lsp.view.common.setWallpaper
|
||||
import com.lsp.view.common.share
|
||||
import com.lsp.view.ui.compose.PostViewModel
|
||||
import moe.uni.view.R
|
||||
import moe.uni.view.common.setWallpaper
|
||||
import moe.uni.view.common.share
|
||||
import moe.uni.view.ui.compose.PostViewModel
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -77,7 +78,7 @@ fun DetailScreen(navController: NavController, viewModel: PostViewModel) {
|
||||
title = {},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { navController.popBackStack() }) {
|
||||
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = R.string.description_back.toString())
|
||||
Icon(imageVector = Icons.AutoMirrored.Default.ArrowBack, contentDescription = R.string.description_back.toString())
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose.screen
|
||||
package moe.uni.view.ui.compose.screen
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
@@ -53,11 +53,11 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.compose.SubcomposeAsyncImageContent
|
||||
import com.lsp.view.bean.Post
|
||||
import com.lsp.view.common.Config
|
||||
import com.lsp.view.ui.compose.NAV_ROUTE_DETAIL_SCREEN
|
||||
import com.lsp.view.ui.compose.PostViewModel
|
||||
import com.lsp.view.ui.compose.widget.SearchBar
|
||||
import moe.uni.view.bean.Post
|
||||
import moe.uni.view.common.Config
|
||||
import moe.uni.view.ui.compose.NAV_ROUTE_DETAIL_SCREEN
|
||||
import moe.uni.view.ui.compose.PostViewModel
|
||||
import moe.uni.view.ui.compose.widget.SearchBar
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose.theme
|
||||
package moe.uni.view.ui.compose.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose.theme
|
||||
package moe.uni.view.ui.compose.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose.theme
|
||||
package moe.uni.view.ui.compose.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.lsp.view.ui.compose.widget
|
||||
package moe.uni.view.ui.compose.widget
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="100%p" android:toYDelta="0%p"
|
||||
android:duration="400"/>
|
||||
</set>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="0%p" android:toYDelta="100%p"
|
||||
android:duration="400"/>
|
||||
</set>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.activity.MainActivity">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_graph" />
|
||||
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:layout_gravity="bottom"
|
||||
android:id="@+id/bottom_navigation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:menu="@menu/nav_menu" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?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.CollectFragment">
|
||||
|
||||
<include layout="@layout/post_list_layout"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,38 +0,0 @@
|
||||
<?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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".ui.fragment.ImageFragment">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.chrisbanes.photoview.PhotoView
|
||||
android:id="@+id/image_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/bottomAppBar"
|
||||
style="@style/Widget.Material3.BottomAppBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:menu="@menu/image_bottom_menu" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/download_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_anchor="@id/bottomAppBar"
|
||||
app:srcCompat="@drawable/baseline_file_download_24"
|
||||
android:contentDescription="@string/description_download" />
|
||||
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/post_list_layout"/>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.material.search.SearchBar
|
||||
android:id="@+id/search_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.google.android.material.search.SearchView
|
||||
android:id="@+id/search_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_anchor="@id/search_bar">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/search_tip"
|
||||
android:visibility="gone"/>
|
||||
</com.google.android.material.search.SearchView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:elevation="20dp"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:cardCornerRadius="4dp"
|
||||
android:layout_margin="5dp"
|
||||
style="?attr/materialCardViewElevatedStyle"
|
||||
android:layout_height="wrap_content">
|
||||
<FrameLayout
|
||||
android:id="@+id/item_pic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:id="@+id/image"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="MissingConstraints">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/recyclerview"/>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:fitsSystemWindows="true"
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:id="@+id/toolbar"
|
||||
/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:layout_margin="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/tag"/>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item android:contentDescription="@string/description_share"
|
||||
android:id="@+id/share_menu_btn"
|
||||
android:title="@string/title_share"
|
||||
android:icon="@drawable/ic_twotone_share_24"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item android:id="@+id/collect_menu_btn"
|
||||
android:title="@string/title_collect"
|
||||
android:icon="@drawable/ic_baseline_favorite_24"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
|
||||
</menu>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/postListFragment"
|
||||
android:icon="@drawable/ic_baseline_insert_photo_24"
|
||||
android:title="@string/item_gallery"/>
|
||||
<item
|
||||
android:id="@+id/collectFragment"
|
||||
android:icon="@drawable/ic_baseline_favorite_24"
|
||||
android:title="@string/item_collect"/>
|
||||
<item
|
||||
android:id="@+id/settingsFragment"
|
||||
android:icon="@drawable/baseline_settings_24"
|
||||
android:title="@string/item_settings"/>
|
||||
</group>
|
||||
</menu>
|
||||
@@ -1,44 +0,0 @@
|
||||
<?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/postListFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/postListFragment"
|
||||
android:name="com.lsp.view.ui.fragment.PostListFragment"
|
||||
android:label="PostListFragment" >
|
||||
<action
|
||||
android:id="@+id/action_postListFragment_to_imageFragment"
|
||||
app:destination="@id/imageFragment"
|
||||
app:enterAnim="@anim/slide_on_bottom"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/slide_out_bottom" >
|
||||
</action>
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/imageFragment"
|
||||
android:name="com.lsp.view.ui.fragment.ImageFragment"
|
||||
android:label="fragment_pic"
|
||||
tools:layout="@layout/fragment_image" >
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/collectFragment"
|
||||
android:name="com.lsp.view.ui.fragment.CollectFragment"
|
||||
android:label="fragment_collect"
|
||||
tools:layout="@layout/fragment_collect" >
|
||||
<action
|
||||
android:id="@+id/action_collectFragment_to_imageFragment"
|
||||
app:destination="@id/imageFragment"
|
||||
app:enterAnim="@anim/slide_on_bottom"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/slide_out_bottom"/>
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/settingsFragment"
|
||||
android:name="com.lsp.view.ui.fragment.SettingsFragment"
|
||||
android:label="SettingsFragment" />
|
||||
</navigation>
|
||||
+2
-2
@@ -6,9 +6,9 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.3.1'
|
||||
classpath 'com.android.tools.build:gradle:8.3.2'
|
||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10'
|
||||
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.5"
|
||||
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
include ':app'
|
||||
rootProject.name = "LspView"
|
||||
rootProject.name = "YandView"
|
||||
Reference in New Issue
Block a user