diff --git a/app/build.gradle b/app/build.gradle index 7ee5a23..99ce7b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdkVersion = 33 + compileSdkVersion = 34 defaultConfig { applicationId "com.lsp.view" minSdkVersion 29 - targetSdkVersion 33 + targetSdkVersion 34 versionCode 221022 versionName "1.2.7" @@ -33,7 +33,7 @@ android { } dependencies { - implementation("com.google.android.material:material:1.5.0") + implementation("com.google.android.material:material:1.10.0") implementation 'jp.wasabeef:recyclerview-animators:4.0.2' implementation "androidx.drawerlayout:drawerlayout:1.1.1" implementation 'com.github.chrisbanes:PhotoView:2.3.0' diff --git a/app/src/main/java/com/lsp/view/activity/main/MainActivity.kt b/app/src/main/java/com/lsp/view/activity/main/MainActivity.kt index 442c3c0..3415ccc 100644 --- a/app/src/main/java/com/lsp/view/activity/main/MainActivity.kt +++ b/app/src/main/java/com/lsp/view/activity/main/MainActivity.kt @@ -1,34 +1,20 @@ package com.lsp.view.activity.main -import android.animation.Animator -import android.animation.AnimatorListenerAdapter -import android.content.Intent -import android.os.* +import android.os.Bundle import android.util.Log -import android.view.Menu -import android.view.MenuItem -import android.view.View import android.view.inputmethod.EditorInfo -import android.widget.EditText import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.widget.Toolbar -import androidx.core.view.GravityCompat -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat.Type.ime -import androidx.drawerlayout.widget.DrawerLayout import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.StaggeredGridLayoutManager -import com.google.android.material.navigation.NavigationView +import com.google.android.material.search.SearchBar +import com.google.android.material.search.SearchView import com.google.android.material.snackbar.Snackbar -import com.lsp.view.YandViewApplication import com.lsp.view.R -import com.lsp.view.activity.favtag.FavTagActivity -import com.lsp.view.activity.setting.SettingsActivity +import com.lsp.view.YandViewApplication import com.lsp.view.model.MainViewModel class MainActivity : AppCompatActivity() { - private lateinit var search: EditText private var shortAnnotationDuration: Int = 0 private var username: String? = "" val TAG = javaClass.simpleName @@ -38,11 +24,13 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - - val toolbar = findViewById(R.id.toolbar) - setSupportActionBar(toolbar) - viewModel = MainViewModel.provideFactory((application as YandViewApplication).repository, this,this).create(MainViewModel::class.java) + + val adapter by lazy { + viewModel.fetchPostByRefresh() + PostAdapter(this) + } + //刷新 val refresh = findViewById(R.id.swipeRefreshLayout) @@ -53,14 +41,26 @@ class MainActivity : AppCompatActivity() { viewModel.errorMessage.observe(this){ Snackbar.make(refresh,it,Snackbar.LENGTH_SHORT).show() } + viewModel.postList.observe(this){ - search = findViewById(R.id.search) - shortAnnotationDuration = resources.getInteger(android.R.integer.config_shortAnimTime) - - search.setOnEditorActionListener { content, actionId, _ -> - if (actionId == EditorInfo.IME_ACTION_SEARCH) { - viewModel.fetchPostBySearch(content.text.toString()) + if (adapter.isAppendData){ + adapter.appendDate(it) + }else{ + adapter.pushNewData(it) } + } + + shortAnnotationDuration = resources.getInteger(android.R.integer.config_shortAnimTime) + val searchBar = findViewById(R.id.search_bar) + val searchView = findViewById(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 } @@ -70,31 +70,28 @@ class MainActivity : AppCompatActivity() { viewModel.uiState.value.nowSearchText.value = stringExtra } viewModel.uiState.value.nowSearchText.observe(this){ - search.setText(it) + searchView.setText(it) + searchBar.setText(it) } -// val appbar = findViewById(R.id.appbar) -// val nowHeight = appbar.layoutParams.height -// appbar.layoutParams.height = (application as YandViewApplication).statusBarHeight()+nowHeight - refresh.setOnRefreshListener { viewModel.fetchPostByRefresh() } - viewModel.adapter.apply { + adapter.apply { setLoadMoreListener(object :PostAdapter.OnScrollToBottom{ override fun event(position: Int) { + adapter.isAppendData = true//设置数据状态为追加数据 viewModel.fetchMore() } - }) } findViewById(R.id.recyclerview).apply { val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) this.layoutManager = layoutManager - this.adapter = viewModel.adapter + this.adapter = adapter } @@ -108,39 +105,6 @@ class MainActivity : AppCompatActivity() { val sp = getSharedPreferences("username", 0) username = sp.getString("username", null) - val nav = findViewById(R.id.nav) - - //加载导航栏列表 - nav.setCheckedItem(R.id.photo) - //设置侧边栏点击逻辑 - nav.setNavigationItemSelectedListener { - val drawerLayout = findViewById(R.id.drawerLayout) - when (it.itemId) { - //画廊 - R.id.photo -> { - viewModel.fetchPostByRefresh() - drawerLayout.closeDrawers() - true - } - //设置 - R.id.setting -> { - val intent = Intent(this, SettingsActivity::class.java) - startActivity(intent) - drawerLayout.closeDrawers() - false - - } - R.id.taglist -> { - val intent = Intent(this, FavTagActivity::class.java) - startActivity(intent) - drawerLayout.closeDrawers() - false - } - else -> false - } - } - - } override fun onResume() { @@ -163,74 +127,4 @@ class MainActivity : AppCompatActivity() { } - //隐藏搜索栏 - private fun hiddenSearchBar() { - supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_baseline_menu_24) - search.animate() - .alpha(0f) - .setDuration(shortAnnotationDuration.toLong()) - .setListener(object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator) { - search.visibility = View.GONE - } - }) - hideIm() - viewModel.uiState.value.switchShowSearchBar() - } - - //现实搜索栏 - private fun showSearchBar() { - supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_baseline_arrow_back_24) - search.apply { - alpha = 0f - visibility = View.VISIBLE - animate() - .alpha(1f) - .setDuration(shortAnnotationDuration.toLong()) - .setListener(null) - } - viewModel.uiState.value.switchShowSearchBar() - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - android.R.id.home -> { - if (viewModel.uiState.value.showSearchBar){ - hiddenSearchBar() - }else { - val drawerLayout = findViewById(R.id.drawerLayout) - drawerLayout.openDrawer(GravityCompat.START) - } - } - R.id.search_nav -> { - if (viewModel.uiState.value.showSearchBar) { - viewModel.fetchPostByRefresh() - hideIm() - - } - - if (search.visibility == View.GONE) { - showSearchBar() - } - } - } - return true - } - - - private fun hideIm() { - WindowCompat.getInsetsController(this.window,window.decorView).hide(ime()) - } - - - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.toolbar_menu, menu) - return true - } - - - - - - } \ No newline at end of file diff --git a/app/src/main/java/com/lsp/view/activity/main/PostAdapter.kt b/app/src/main/java/com/lsp/view/activity/main/PostAdapter.kt index 490742f..105beab 100644 --- a/app/src/main/java/com/lsp/view/activity/main/PostAdapter.kt +++ b/app/src/main/java/com/lsp/view/activity/main/PostAdapter.kt @@ -14,13 +14,11 @@ import com.lsp.view.activity.pic.PicActivity import com.lsp.view.repository.bean.YandPost -class PostAdapter(val context: Context): +class PostAdapter(val context: Context,private val postList: ArrayList = ArrayList()): RecyclerView.Adapter() { val TAG = this::class.java.simpleName private val UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" - - private var postList = ArrayList() - + var isAppendData = false//数据追加标志 inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val picImage: ImageView = view.findViewById(R.id.picImgae) @@ -39,6 +37,7 @@ class PostAdapter(val context: Context): val pos = postList.size postList.addAll(list) notifyItemRangeInserted(pos-1, list.size) + isAppendData = false } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { diff --git a/app/src/main/java/com/lsp/view/model/MainViewModel.kt b/app/src/main/java/com/lsp/view/model/MainViewModel.kt index 73c837d..a8c28e3 100644 --- a/app/src/main/java/com/lsp/view/model/MainViewModel.kt +++ b/app/src/main/java/com/lsp/view/model/MainViewModel.kt @@ -11,6 +11,8 @@ import androidx.lifecycle.viewModelScope import com.lsp.view.activity.main.PostAdapter import com.lsp.view.repository.PostRepository import androidx.savedstate.SavedStateRegistryOwner +import com.lsp.view.repository.bean.Post +import com.lsp.view.repository.bean.YandPost import com.lsp.view.repository.exception.NetworkErrorException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -25,12 +27,14 @@ class MainViewModel(private val repository: PostRepository,context: Context):Vie val uiState:StateFlow get() = _uiState.asStateFlow() private var fetchJob: Job? = null - val adapter = PostAdapter(context) private val TAG = this::class.java.simpleName private val _errorMessage = MutableLiveData() val errorMessage get() = _errorMessage as LiveData + private val _postList = MutableLiveData>() + val postList get() = _postList as LiveData> + companion object { fun provideFactory( @@ -77,19 +81,11 @@ class MainViewModel(private val repository: PostRepository,context: Context):Vie fetchJob = viewModelScope.launch(Dispatchers.IO) { _uiState.value.isRefreshing.postValue(true) try { - val postList = repository.fetchPostData( + _postList.postValue(repository.fetchPostData( _uiState.value.nowSearchText.value, _uiState.value.isSafe, _uiState.value.nowPage - ) - - launch(Dispatchers.Main) { - if (append){ - adapter.appendDate(postList) - }else{ - adapter.pushNewData(postList) - } - } + )) }catch (e:NetworkErrorException){ _errorMessage.postValue(e.message.toString()) diff --git a/app/src/main/java/com/lsp/view/repository/PostRepository.kt b/app/src/main/java/com/lsp/view/repository/PostRepository.kt index 74c27da..78572ac 100644 --- a/app/src/main/java/com/lsp/view/repository/PostRepository.kt +++ b/app/src/main/java/com/lsp/view/repository/PostRepository.kt @@ -7,7 +7,7 @@ class PostRepository { private val dataSource = PostDataSource() //获取post - suspend fun fetchPostData(searchTarget :String?,safe:Boolean,page:Int): List { + suspend fun fetchPostData(searchTarget :String?,safe:Boolean,page:Int): ArrayList { var target = searchTarget var isNum = true @@ -26,7 +26,7 @@ class PostRepository { val dataList = dataSource.fetchNewPost(load) return if (safe){ - dataList.filter { it.rating == "s" } + ArrayList(dataList.filter { it.rating == "s" }) }else{ dataList } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c2f5f94..5c0eb4d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,6 +1,5 @@ - - - - + + + - + android:layout_height="wrap_content"> + + - - - + + + - - - - - - - - - - - - +