一文教你如何使用Databinding写一个关注功能

目录
  • 前言
  • 目标
  • Modle
  • Presenter

前言

但是没有合理的架构,大家写出来的代码很可能是一大堆的复制粘贴。比如十几个页面,都有这个关注按钮。然后,你是不是也要写十几个地方呢 然后修改的时候是不是也要修改十几个地方 我们是否考虑过一下几个问题?

  • 可复用性 (是否重复代码和逻辑过多?)
  • 可扩展性 (比如我这里是关注的人,传userId,下个地方又是文章 articleId)
  • 可读性 冗余代码过多,势必要影响到可读性。

然后再看下自己写的代码,是否会面临上面的几个问题呢?是否有一种优雅的方式。帮我们一劳永逸。我这里给出一个解决方案是 使用Databinding ,如果对databinding使用不熟悉的,建议先去熟悉一下databinding用法

目标

我们要实现的目标是,希望能让关注这快的业务逻辑实现最大程度复用,在所有有关注按钮布局的页面,只需要引入一个同一个vm。实现关注和非关注状态逻辑的切换

Modle

下面以关注人来做为示例:

要有两种状态,实体bean要继承自BaseObservable。配合databing实现mvvm效果,属性需要定义为@Bindable,当属性发生变化的时候,调用notifyPropertyChanged(属性ID)

public class User extends BaseObservable implements Serializable {
    public boolean hasFollow;//是否关注,是和否
    @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="已关注" />
    </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 {
    //关注/取消关注一个用户

    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);
                    }
                });
    }

}

综上已经实现了简单的用户关注功能。activity不需要做任何事情。

到此这篇关于一文教你如何使用Databinding写一个关注功能的文章就介绍到这了,更多相关Databinding写功能内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android开发Jetpack组件DataBinding用例详解

    目录 简介 使用方式 1. build.gradle 中添加 kapt,并启用dataBinding 2.修改布局文件,添加 layout 和 data 标签 3.使用 DataBindingUtil 绑定布局 4.布局的 data 标签中添加数据变量,并使用其参数 5.BindingAdapter的使用 简介 DataBinding 是 Jetpack 组件之一,适用于 MVVM 模式开发,也是Google官方推荐使用的组件之一.使用DataBinding可以很容易的达到视图与逻辑分离,直接在

  • Android DataBinding手把手入门教程

    1.在build.gradle(Module)里引入依赖,然后重构(sync Now): android { ...... dataBinding{ enabled true } } 2.找到想要改为dataBinding视图的页面,alt+enter弹出如下: 并选择Convert to data binding layout自动转换. 转换之后效果应和下图类似: 可以看到页面出现了新的Layout和data的空标签.(data 就是用来存放数据的) 3.接下来到对应的Activity里,声明

  • DataBinding onClick的七种点击方式

    最近在学习DataBinding的使用,中间遇到了不少的坑,记录以下,帮助以后学习DataBinding的朋友. 有一个 ViewModel 类,有一个 xml,xml 绑定了 ViewModel . 1. @{click} //xml: <Button android:layout_width="match_parent" android:layout_height="48dp" android:onClick="@{click}" /&

  • Winform项目中TextBox控件DataBindings属性

    DataBindings属性是很多控件都有的属性,作用有2方面.一方面是用于与数据库的数据进行绑定,进行数据显示.另一方面用于与控件或类的对象进行数据绑定.这里主要关注后者.主要用法是将某个对象的某个属性与指定对象的指定属性进行关联. Label.TextBox等都包含DataBindings属性,其类型为ControlBindingsCollection,是Binding类的集合.Binding类代表某对象属性值和某控件属性值之间的简单绑定.如可以将TextBox的Text属性值绑定到Labe

  • Android DataBinding的官方双向绑定示例

    在Android Studio 2.1 Preview 3之后,官方开始支持双向绑定了. 可惜目前Google并没有在Data Binding指南里面加入这个教程,并且在整个互联网之中只有这篇文章介绍了如何使用反向绑定. 在阅读一下文章之前,我假设你已经知道如何正向绑定. 回顾一下Data Binding 在正向绑定中,我们在Layout里面的绑定表达式是这样的: <layout ...> <data> <variable type="com.example.mya

  • android使用DataBinding来设置空状态

    写在前面 在平时的开发之中,我们需要对于数据加载的情况进行展示: 空数据 网络异常 加载中等等情况 现在设置页面状态的方式有多种,由于笔者近期一直在使用databinding,而数据绑定通过改变模型来展示view的方式和状态页的设置也满契合的. 所以这里就讲讲使用databinding来设置android中的各种状态页.很简单,先看看效果 首先 在app的build.gradle文件中开启databinding android{ ... dataBinding { enabled = true

  • 在Android中如何使用DataBinding详解(Kotlin)

    前言 本问主要介绍DataBinding在Android App中的使用方法.数据绑定是将"提供器"的数据源与"消费者"绑定并使其同步的一种通用技术. 1. Android应用程序使用数据绑定 1.1 介绍DataBinding Android通过DataBinding提供了编写声明型布局的支持.这样可以最大程度简化布局和逻辑相关联的代码. 数据绑定要求修改文件,外层需要包裹一个layout布局.主要通过@{} 或 @={}语法把布局中的元素和表达式的引用写入到属性

  • 一文教你如何使用Databinding写一个关注功能

    目录 前言 目标 Modle Presenter 前言 但是没有合理的架构,大家写出来的代码很可能是一大堆的复制粘贴.比如十几个页面,都有这个关注按钮.然后,你是不是也要写十几个地方呢 然后修改的时候是不是也要修改十几个地方 我们是否考虑过一下几个问题? 可复用性 (是否重复代码和逻辑过多?) 可扩展性 (比如我这里是关注的人,传userId,下个地方又是文章 articleId) 可读性 冗余代码过多,势必要影响到可读性. 然后再看下自己写的代码,是否会面临上面的几个问题呢?是否有一种优雅的方

  • vuejs手把手教你写一个完整的购物车实例代码

    由于我们公司是主营业务是海淘,所以每个项目都是类似淘宝天猫之类的商城,那么购物车就是一个重点开发功能模块.介于之前我都是用jq来写购物车的,这次就用vuejs来写一个购物车.下面我就从全选,数量控制器,运费,商品金额计算等方法来演示一下一个能用在实际场景的购物车是怎么做出来的以及记录一下这次用vuejs踩过的坑. 1.一层数据结构-全选 下面这段代码和vuejs官网里面checkbox绑定很像.不明白的可以直接上vuejs官网看看. <!DOCTYPE html> <html lang=

  • 写一个漂亮Rakefile的方法

    Rake 我就不再介绍了,Ruby 的 Make ,许多方面都比 Make 要更好用一些.和 Makefile 不同的是,Rakefile 本身其实就是一段 Ruby 代码,这样的好处有很多,一方面在 Rake 里面就可以很直接地做任何 Ruby 能做的事了,另一方面由于 Ruby 对 DSL 支持良好,所以 Rakefile 通常看起来也并不那么"代码". 不过,代码始终是代码,Makefile 尚且可以写得很乱,Rakefile 要写乱就更容易了,幸运地是,Rake 提供了一些功能

  • 用函数模板,写一个简单高效的 JSON 查询器的方法介绍

    JSON可谓是JavaScript的亮点,它能用优雅简练的代码实现Object和Array的初始化.同样是基于文本的数据定义,它比符号分隔更有语义,比XML更简洁.因此越来越多的JS开发中,使用它作为数据的传输和储存. JS数组内置了不少有用的方法,方便我们对数据的查询和筛选.例如我们有一堆数据: 复制代码 代码如下: var heros = [        // 名============攻=====防=======力量====敏捷=====智力====        {name:'冰室女巫

  • node通过npm写一个cli命令行工具

    前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要新建一些页面,逻辑样式等文件,每次都手动new一个,然后复制一些基本代码进去非常的麻烦,所以就有了这篇文章.接下来就让po主为大家一步一步演示怎么做一个npm命令行插件. 注册npm账户 发布npm插件,首先肯定要有个npm帐号了,过程就不啰嗦了,走你. npm官网 有了账号后,我们通过npm in

  • Windows下写一个文件备份脚本(专用备份的)

    今天一个意外,我写的大半个月的日记加密文件受损,无法恢复.于是决定写一个专用备份的脚本文件. 主要思想就是在当前目录backup下根据当天的日期创建一个文件夹,然后将文件复制到该文件夹下. 脚本文件如下: 复制代码 代码如下: echo off echo ********开始备份日志文件******** set ymd=%date:~0,4%%date:~5,2%%date:~8,2% set backup-dir=backupnotebook-%ymd% echo 备份目录:%backup-d

  • 使用Python写一个贪吃蛇游戏实例代码

    我在程序中加入了分数显示,三种特殊食物,将贪吃蛇的游戏逻辑写到了SnakeGame的类中,而不是在Snake类中. 特殊食物: 1.绿色:普通,吃了增加体型 2.红色:吃了减少体型 3.金色:吃了回到最初体型 4.变色食物:吃了会根据食物颜色改变蛇的颜色 #coding=UTF-8 from Tkinter import * from random import randint import tkMessageBox class Grid(object): def __init__(self,

  • 使用Python的Bottle框架写一个简单的服务接口的示例

    是不是有这么一个场景,对外提供一堆数据或者是要返回给用户一个结果.但是不想把内部的一些数据和逻辑暴露给对方...简单点来说,就是想以服务的方式对外提供一个接口.对于这种有很多处理方式,RPC,搭建一个web服务啥的....但是这些毕竟都太重量级了,操作起来很麻烦.我这里给出的一种非常easy的方式来处理.使用bottle解决问题. 需求: 检查一个zookeeper服务中的某些节点是否存在,如果存在返回OK,不存在则给出不存的节点信息.要求返回的信息是和pyunit的结果信息一致. 实现环境:

  • js下写一个事件队列操作函数

    前两天在网上看到这一系列的文章<写一个JavaScript异步调用框架1,2,3,4,5,6>. 异步操作可能会产生你不希望的事件触发顺序.这个问题以前也遇到过,当时没想太多,也就是直接多层嵌套(在ajax返回以后嵌套下一个事件)来解决. 认真的看了一遍.看的头昏,不得不说我可能基础并不好,在大局上的掌握也不好.d反正我是觉得很难理解,也不觉得它的调用时够方便的. 如果是这么调用: var chain = Async.go(0); chain .next(function(){setTimeo

  • 用Python写一个无界面的2048小游戏

    以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定用python写一个2048,由于没学过python里面的界面编程,所以写了一个极其简单的无界面2048.游戏2048的原理和实现都不难,正好可以拿来练手,要是不知道这游戏的话,可以去网上查一下,或者下载一个到手机来玩一下,我就不在说其原理.我知道不放图的话大家一点兴趣都没,下面首先放一张游戏成型图,然后我们在来讲如何一步步用最基础的知识来实现. 一.生成4*4的矩阵 游戏的第一步便是生成一个4*4的矩

随机推荐