feat: Use material search view & recyclerview adapter handler is activity
This commit is contained in:
+3
-3
@@ -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'
|
||||
|
||||
@@ -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<Toolbar>(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<androidx.swiperefreshlayout.widget.SwipeRefreshLayout>(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<SearchBar>(R.id.search_bar)
|
||||
val searchView = 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
|
||||
}
|
||||
|
||||
@@ -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<AppBarLayout>(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<RecyclerView>(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<NavigationView>(R.id.nav)
|
||||
|
||||
//加载导航栏列表
|
||||
nav.setCheckedItem(R.id.photo)
|
||||
//设置侧边栏点击逻辑
|
||||
nav.setNavigationItemSelectedListener {
|
||||
val drawerLayout = findViewById<DrawerLayout>(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<DrawerLayout>(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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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<YandPost> = ArrayList()):
|
||||
RecyclerView.Adapter<PostAdapter.ViewHolder>() {
|
||||
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<YandPost>()
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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<UiState>
|
||||
get() = _uiState.asStateFlow()
|
||||
private var fetchJob: Job? = null
|
||||
val adapter = PostAdapter(context)
|
||||
private val TAG = this::class.java.simpleName
|
||||
private val _errorMessage = MutableLiveData<String>()
|
||||
val errorMessage
|
||||
get() = _errorMessage as LiveData<String>
|
||||
|
||||
private val _postList = MutableLiveData<ArrayList<YandPost>>()
|
||||
val postList get() = _postList as LiveData<ArrayList<YandPost>>
|
||||
|
||||
|
||||
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())
|
||||
|
||||
@@ -7,7 +7,7 @@ class PostRepository {
|
||||
private val dataSource = PostDataSource()
|
||||
|
||||
//获取post
|
||||
suspend fun fetchPostData(searchTarget :String?,safe:Boolean,page:Int): List<YandPost> {
|
||||
suspend fun fetchPostData(searchTarget :String?,safe:Boolean,page:Int): ArrayList<YandPost> {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
android:id="@+id/drawerLayout"
|
||||
<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"
|
||||
@@ -8,63 +7,39 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activity.main.MainActivity">
|
||||
|
||||
<RelativeLayout
|
||||
|
||||
android:id="@+id/rl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activity.main.MainActivity">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<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>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
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>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:menu="@menu/toolbar_menu"
|
||||
android:id="@+id/toolbar"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
||||
>
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textSize="20sp"
|
||||
android:id="@+id/search"
|
||||
android:imeOptions="actionSearch"
|
||||
android:singleLine="true"
|
||||
android:visibility="gone" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
<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>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<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>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/nav"
|
||||
android:layout_gravity="start"
|
||||
app:menu="@menu/nav_menu"
|
||||
app:headerLayout="@layout/nav_header"
|
||||
/>
|
||||
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user