網(wǎng)站首頁 編程語言 正文
Android開發(fā)使用Databinding實(shí)現(xiàn)關(guān)注功能mvvp_Android
作者:DavidMC ? 更新時(shí)間: 2022-11-05 編程語言正文
說到關(guān)注功能,可能很多小伙伴要說了。誰不會(huì)寫
但是沒有合理的架構(gòu),大家寫出來的代碼很可能是一大堆的復(fù)制粘貼。比如十幾個(gè)頁面,都有這個(gè)關(guān)注按鈕。然后,你是不是也要寫十幾個(gè)地方呢 然后修改的時(shí)候是不是也要修改十幾個(gè)地方 我們是否考慮過一下幾個(gè)問題?
- ?可復(fù)用性 (是否重復(fù)代碼和邏輯過多?)
- ?可擴(kuò)展性 (比如我這里是關(guān)注的人,傳userId,下個(gè)地方又是文章 articleId)
- ?可讀性 冗余代碼過多,勢(shì)必要影響到可讀性。
然后再看下自己寫的代碼,是否會(huì)面臨上面的幾個(gè)問題呢?是否有一種優(yōu)雅的方式。幫我們一勞永逸。我這里給出一個(gè)解決方案是 使用Databinding ,如果對(duì)databinding使用不熟悉的,建議先去熟悉一下databinding用法
目標(biāo)
我們要實(shí)現(xiàn)的目標(biāo)是,希望能讓關(guān)注這快的業(yè)務(wù)邏輯實(shí)現(xiàn)最大程度復(fù)用,在所有有關(guān)注按鈕布局的頁面,只需要引入一個(gè)同一個(gè)vm。實(shí)現(xiàn)關(guān)注和非關(guān)注狀態(tài)邏輯的切換
Modle
下面以關(guān)注人來做為示例
要有兩種狀態(tài),實(shí)體bean要繼承自BaseObservable。配合databing實(shí)現(xiàn)mvvm效果,屬性需要定義為@Bindable,當(dāng)屬性發(fā)生變化的時(shí)候,調(diào)用notifyPropertyChanged(屬性ID)
public class User extends BaseObservable implements Serializable {
public boolean hasFollow;//是否關(guān)注,是和否
@Bindable
public boolean isHasFollow() {
return hasFollow;
}
public void setHasFollow(boolean hasFollow) {
this.hasFollow = hasFollow;
notifyPropertyChanged(com.mooc.ppjoke.BR._all);
}
}
頁面布局如下
<?xml version="1.0" encoding="utf-8"?> <layout 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"> <data> <variable name="feed" type="com.mooc.ppjoke.model.Feed" /> <variable name="leftMargin" type="java.lang.Integer" /> <variable name="fullscreen" type="java.lang.Boolean" /> <import type="com.mooc.ppjoke.utils.TimeUtils" /> <import type="com.mooc.ppjoke.ui.InteractionPresenter"></import> <variable name="owner" type="androidx.lifecycle.LifecycleOwner" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/author_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/transparent" android:orientation="vertical" android:paddingLeft="@{leftMargin}" android:paddingTop="@dimen/dp_3" android:paddingBottom="@dimen/dp_3"> <com.mooc.ppjoke.view.PPImageView android:id="@+id/author_avatar" android:layout_width="@dimen/dp_40" android:layout_height="@dimen/dp_40" android:layout_marginTop="@dimen/dp_1" app:image_url="@{feed.author.avatar}" app:isCircle="@{true}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" tools:src="@drawable/icon_splash_text"></com.mooc.ppjoke.view.PPImageView> <TextView android:id="@+id/author_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="@dimen/dp_3" android:text="@{feed.author.name}" android:textColor="@{fullscreen?@color/color_white:@color/color_000}" android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintLeft_toRightOf="@+id/author_avatar" app:layout_constraintTop_toTopOf="parent" tools:text="Title"></TextView> <TextView android:id="@+id/create_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="@dimen/dp_2" android:text="@{TimeUtils.calculate(feed.createTime)}" android:textColor="@{fullscreen?@color/color_white:@color/color_000}" android:textSize="@dimen/sp_12" android:textStyle="normal" app:layout_constraintLeft_toRightOf="@+id/author_avatar" app:layout_constraintTop_toBottomOf="@+id/author_name" tools:text="3天前"></TextView> <com.google.android.material.button.MaterialButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="@dimen/dp_16" android:backgroundTint="@{fullscreen?@color/transparent:@color/color_theme}" android:gravity="center" android:onClick="@{()->InteractionPresenter.toggleFollowUser(owner,feed)}" android:paddingLeft="@dimen/dp_16" android:paddingTop="@dimen/dp_5" android:paddingRight="@dimen/dp_16" android:paddingBottom="@dimen/dp_5" android:text="@{feed.author.hasFollow?@string/has_follow:@string/unfollow}" android:textColor="@color/color_white" android:textSize="@dimen/sp_14" app:backgroundTint="@color/color_theme" app:cornerRadius="@dimen/dp_13" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:strokeColor="@{fullscreen?@color/color_white:@color/transparent}" app:strokeWidth="1dp" tools:text="已關(guān)注" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
顯示效果
Presenter
package com.mooc.ppjoke.ui;
import android.app.Application;
import android.content.Context;
import android.content.DialogInterface;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.arch.core.executor.ArchTaskExecutor;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mooc.libcommon.extention.LiveDataBus;
import com.mooc.libcommon.global.AppGlobals;
import com.mooc.libnetwork.ApiResponse;
import com.mooc.libnetwork.ApiService;
import com.mooc.libnetwork.JsonCallback;
import com.mooc.ppjoke.model.Comment;
import com.mooc.ppjoke.model.Feed;
import com.mooc.ppjoke.model.TagList;
import com.mooc.ppjoke.model.User;
import com.mooc.ppjoke.ui.login.UserManager;
import com.mooc.ppjoke.ui.share.ShareDialog;
import org.jetbrains.annotations.NotNull;
import java.util.Date;
public class InteractionPresenter {
//關(guān)注/取消關(guān)注一個(gè)用戶
private static void toggleFollowUser(LifecycleOwner owner,User user) {
ApiService.get("/ugc/toggleUserFollow")
.addParam("followUserId", UserManager.get().getUserId())
.addParam("userId", feed.author.userId)
.execute(new JsonCallback<JSONObject>() {
@Override
public void onSuccess(ApiResponse<JSONObject> response) {
if (response.body != null) {
boolean hasFollow = response.body.getBooleanValue("hasLiked");
user.setHasFollow(hasFollow);
LiveDataBus.get().with(DATA_FROM_INTERACTION)
.postValue(feed);
}
}
@Override
public void onError(ApiResponse<JSONObject> response) {
showToast(response.message);
}
});
}
}
綜上已經(jīng)實(shí)現(xiàn)了簡(jiǎn)單的用戶關(guān)注功能。activity不需要做任何事情。
原文鏈接:https://juejin.cn/post/7142678611810582558
相關(guān)推薦
- 2022-05-18 Python學(xué)習(xí)之異常中的finally使用詳解_python
- 2023-01-13 Pytorch中關(guān)于BatchNorm2d的參數(shù)解釋_python
- 2023-05-09 Linux?解壓縮文件到指定目錄_linux shell
- 2023-03-22 利用tkinter改變下拉列表(Combobox)的選項(xiàng)值_python
- 2022-10-15 C語言循環(huán)結(jié)構(gòu)深入刨析_C 語言
- 2022-08-14 PyTorch中torch.utils.data.DataLoader簡(jiǎn)單介紹與使用方法_pytho
- 2022-04-15 C語言各種操作符透徹理解上篇_C 語言
- 2022-07-13 Android?Studio實(shí)現(xiàn)簡(jiǎn)單繪圖板_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支