Skip to content

Commit

Permalink
1. 修改item布局。2. 新增收藏、取消收藏功能
Browse files Browse the repository at this point in the history
  • Loading branch information
lelelongwang committed Jun 16, 2021
1 parent f66f880 commit 8858e06
Show file tree
Hide file tree
Showing 30 changed files with 313 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@ import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.longjunhao.wanjetpack.R
import com.longjunhao.wanjetpack.adapter.HomeArticleAdapter.ArticleViewHolder
import com.longjunhao.wanjetpack.data.ApiArticle
import com.longjunhao.wanjetpack.databinding.ListItemArticleBinding
import com.longjunhao.wanjetpack.viewmodels.HomeArticleViewModel

/**
* .ArticleAdapter
*
* @author Admitor
* @date 2021/05/21
*/
class HomeArticleAdapter : PagingDataAdapter<ApiArticle, ArticleViewHolder>(ArticleDiffCallback()) {
class HomeArticleAdapter(
private val viewModel: HomeArticleViewModel,
private val viewLifecycleOwner: LifecycleOwner
) : PagingDataAdapter<ApiArticle, ArticleViewHolder>(ArticleDiffCallback()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
return ArticleViewHolder(
Expand All @@ -33,11 +41,37 @@ class HomeArticleAdapter : PagingDataAdapter<ApiArticle, ArticleViewHolder>(Arti
val article = getItem(position)
if (article != null) {
holder.bind(article)
holder.binding.favorite.setOnClickListener { view ->
//todo 如果不执行observe,不会执行网络请求,必须加上observe操作,why?
//todo HomeArticleAdapter、ProjectAdapter、WechatAdapter、WendaAdapter共用的部分,是不是可以提取到BaseAdapter中呢?
if (article.collect) {
viewModel.unCollect(article.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
article.collect = false
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_border_24)
Snackbar.make(view, "取消收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
//todo 这是通过网络返回发现没有登录,是否需要多加个条件:新增Boolean类型的isLogin保存在SharedPreferences中呢?
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
} else {
viewModel.collect(article.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
article.collect = true
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_24)
Snackbar.make(view, "收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
}
}
}
}

class ArticleViewHolder(
private val binding: ListItemArticleBinding
val binding: ListItemArticleBinding
) : RecyclerView.ViewHolder(binding.root) {
init {
binding.setClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@ import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.longjunhao.wanjetpack.R
import com.longjunhao.wanjetpack.databinding.ListItemProjectBinding
import com.longjunhao.wanjetpack.adapter.ProjectAdapter.ProjectViewHolder
import com.longjunhao.wanjetpack.data.ApiArticle
import com.longjunhao.wanjetpack.viewmodels.ProjectViewModel

/**
* .ProjectAdapter
*
* @author Admitor
* @date 2021/05/31
*/
class ProjectAdapter : PagingDataAdapter<ApiArticle, ProjectViewHolder>(ProjectDiffCallback()) {
class ProjectAdapter(
private val viewModel: ProjectViewModel,
private val viewLifecycleOwner: LifecycleOwner
) : PagingDataAdapter<ApiArticle, ProjectViewHolder>(ProjectDiffCallback()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProjectViewHolder {
return ProjectViewHolder(
Expand All @@ -33,11 +41,34 @@ class ProjectAdapter : PagingDataAdapter<ApiArticle, ProjectViewHolder>(ProjectD
val item = getItem(position)
if (item != null) {
holder.bind(item)
holder.binding.favorite.setOnClickListener { view ->
if (item.collect) {
viewModel.unCollect(item.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
item.collect = false
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_border_24)
Snackbar.make(view, "取消收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
} else {
viewModel.collect(item.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
item.collect = true
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_24)
Snackbar.make(view, "收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
}
}
}
}

class ProjectViewHolder(
private val binding: ListItemProjectBinding
val binding: ListItemProjectBinding
): RecyclerView.ViewHolder(binding.root){
init {
binding.setClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@ import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.longjunhao.wanjetpack.R
import com.longjunhao.wanjetpack.adapter.WechatAdapter.WechatViewHolder
import com.longjunhao.wanjetpack.data.ApiArticle
import com.longjunhao.wanjetpack.databinding.ListItemWechatBinding
import com.longjunhao.wanjetpack.viewmodels.WechatArticleViewModel

/**
* .WechatAdapter
*
* @author Admitor
* @date 2021/05/28
*/
class WechatAdapter : PagingDataAdapter<ApiArticle, WechatViewHolder>(WechatDiffCallback()) {
class WechatAdapter(
private val viewModel: WechatArticleViewModel,
private val viewLifecycleOwner: LifecycleOwner
) : PagingDataAdapter<ApiArticle, WechatViewHolder>(WechatDiffCallback()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WechatViewHolder {
return WechatViewHolder(
Expand All @@ -33,11 +41,34 @@ class WechatAdapter : PagingDataAdapter<ApiArticle, WechatViewHolder>(WechatDiff
val wechat = getItem(position)
if (wechat != null) {
holder.bind(wechat)
holder.binding.favorite.setOnClickListener { view ->
if (wechat.collect) {
viewModel.unCollect(wechat.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
wechat.collect = false
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_border_24)
Snackbar.make(view, "取消收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
} else {
viewModel.collect(wechat.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
wechat.collect = true
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_24)
Snackbar.make(view, "收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
}
}
}
}

class WechatViewHolder(
private val binding: ListItemWechatBinding
val binding: ListItemWechatBinding
) : RecyclerView.ViewHolder(binding.root) {
init {
binding.setClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@ import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.longjunhao.wanjetpack.R
import com.longjunhao.wanjetpack.adapter.WendaAdapter.WendaViewHolder
import com.longjunhao.wanjetpack.data.ApiArticle
import com.longjunhao.wanjetpack.databinding.ListItemWendaBinding
import com.longjunhao.wanjetpack.viewmodels.WendaViewModel

/**
* .WendaAdapter
*
* @author Admitor
* @date 2021/05/25
*/
class WendaAdapter : PagingDataAdapter<ApiArticle, WendaViewHolder>(WendaDiffCallback()) {
class WendaAdapter(
private val viewModel: WendaViewModel,
private val viewLifecycleOwner: LifecycleOwner
) : PagingDataAdapter<ApiArticle, WendaViewHolder>(WendaDiffCallback()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WendaViewHolder {
return WendaViewHolder(
Expand All @@ -33,11 +41,34 @@ class WendaAdapter : PagingDataAdapter<ApiArticle, WendaViewHolder>(WendaDiffCal
val wenda = getItem(position)
if (wenda != null) {
holder.bind(wenda)
holder.binding.favorite.setOnClickListener { view ->
if (wenda.collect) {
viewModel.unCollect(wenda.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
wenda.collect = false
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_border_24)
Snackbar.make(view, "取消收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
} else {
viewModel.collect(wenda.id).observe(viewLifecycleOwner, Observer {
if (it.errorCode == 0) {
wenda.collect = true
holder.binding.favorite.setImageResource(R.drawable.ic_favorite_24)
Snackbar.make(view, "收藏成功", Snackbar.LENGTH_LONG).show()
} else if (it.errorCode == -1001) {
Snackbar.make(view, "请先登录账号,待实现", Snackbar.LENGTH_LONG).show()
}
})
}
}
}
}

class WendaViewHolder(
private val binding: ListItemWendaBinding
val binding: ListItemWendaBinding
) : RecyclerView.ViewHolder(binding.root) {
init {
binding.setClickListener {
Expand Down
28 changes: 27 additions & 1 deletion app/src/main/java/com/longjunhao/wanjetpack/api/WanJetpackApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,39 @@ interface WanJetpackApi {
fun logout(): LiveData<ApiResponse<User>>

/**
* 获取收藏列表,请求后的json和 获取首页文章列表一样
* 获取收藏列表,请求后的json和 获取首页文章列表几乎一样。但是我的收藏获取的ApiArticle中没有"collect"字符串
*/
@GET("lg/collect/list/{page}/json")
suspend fun getCollection(
@Path("page") page: Int
): WanJetResponse<ApiPage<ApiArticle>>

/**
* 收藏站内文章:
* 1. 如果id已经收藏,还可以继续收藏(可能收藏时间不一样,待确认)。如果是错误的id,也能收藏成功,但是在登录成功返
* 回的json的collectIds是不存在错误的id的
* 2. 收藏返回的json为{"data":null,"errorCode":0,"errorMsg":""},故返回值中的ApiArticle是随便写的
*
* todo 还有一种常见没有实现:收藏站外文章
*/
@POST("lg/collect/{id}/json")
fun collect(
@Path("id") id: Int
): LiveData<ApiResponse<ApiArticle>>

/**
* 文章列表 取消收藏:
* 1. 不管id是否在收藏列表,都可以取消收藏成功。即存在的id可以重复取消成功,不存在的id也可以取消成功
* 2. 取消收藏返回的json为{"data":null,"errorCode":0,"errorMsg":""},故返回值中的ApiArticle是随便写的
*
* todo 还有一种常见没有实现:我的收藏页面(该页面包含自己录入的内容)取消收藏
* todo 网站、网址的收藏、编辑、删除没有实现
*/
@POST("lg/uncollect_originId/{id}/json")
fun unCollect(
@Path("id") id: Int
): LiveData<ApiResponse<ApiArticle>>


companion object {
private const val BASE_URL = "https://www.wanandroid.com/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import com.google.gson.annotations.SerializedName
*/
data class ApiArticle(
@field:SerializedName("author") val author: String,
@field:SerializedName("shareUser") val shareUser: String,
/**
* 注意 collect 是 var 类型
*/
@field:SerializedName("collect") var collect: Boolean,
@field:SerializedName("desc") val desc: String,
@field:SerializedName("envelopePic") val envelopePic: String,
@field:SerializedName("title") val title: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,12 @@ class WanJetpackRepository @Inject constructor(
).flow
}

fun collect(id: Int): LiveData<ApiResponse<ApiArticle>> {
return api.collect(id)
}

fun unCollect(id: Int): LiveData<ApiResponse<ApiArticle>> {
return api.unCollect(id)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class HomeArticleFragment : Fragment() {
val binding = FragmentHomeArticleBinding.inflate(inflater,container,false)
context ?: return binding.root

val adapter = HomeArticleAdapter()
val adapter = HomeArticleAdapter(viewModel, viewLifecycleOwner)
binding.articleList.adapter = adapter
subscribeUi(adapter)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class WendaFragment : Fragment() {
val binding = FragmentWendaBinding.inflate(inflater,container,false)
context ?: return binding.root

val adapter = WendaAdapter()
val adapter = WendaAdapter(viewModel, viewLifecycleOwner)
binding.articleList.adapter = adapter
subscribeUi(adapter)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ProjectFragment : Fragment() {
binding = FragmentProjectBinding.inflate(inflater, container, false)

val categoryAdapter = ProjectCategoryAdapter(viewModel)
val projectAdapter = ProjectAdapter()
val projectAdapter = ProjectAdapter(viewModel, viewLifecycleOwner)
binding.projectCategoryList.adapter = categoryAdapter
binding.projectList.adapter = projectAdapter
subscribeUi(categoryAdapter, projectAdapter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class WechatArticleFragment : Fragment() {
savedInstanceState: Bundle?
): View {
val binding = FragmentWechatArticleBinding.inflate(inflater,container,false)
val adapter = WechatAdapter()
val adapter = WechatAdapter(viewModel, viewLifecycleOwner)
binding.articleList.adapter = adapter
subscribeUi(adapter)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,14 @@ class HomeArticleViewModel @Inject constructor(
currentArticleResult = newResult
return newResult
}

/**
* todo :和adapter一样,重复的部分应该可以写在baseViewModel中
*/
fun collect(id: Int) = repository.collect(id)

/**
* todo :和adapter一样,重复的部分应该可以写在baseViewModel中
*/
fun unCollect(id: Int) = repository.unCollect(id)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ class ProjectViewModel @Inject constructor(
currentSearchResult = newResult
return newResult
}

fun collect(id: Int) = repository.collect(id)

fun unCollect(id: Int) = repository.unCollect(id)
}
Loading

0 comments on commit 8858e06

Please sign in to comment.