初学MVP

一直听群里的人说MVP模式去开发app 自己也搜藏了几篇文章 但一直没事件去学习,正好这两天有空闲的时间就尝试写个demo出来看看。概念信的东西我就不写了 网上的文章对于MVP的概念大致都是一样的。对于新东西 我一般是通过先写出个demo 以后在运用的过程再去学习此东西里面的详细内容。
建立MVP 项目 一般需要 建立 view(界面逻辑),model(业务逻辑),presenter(调度)这几个包名。当然项目离不开 bean(实体数据) 基本上这几个包名就能组成 一个基本的MVP框架了 其它的包名根据自己的需要建立

此次demo我采用的rxjava和retrofit来完成线程调度和网络请求 既然是新的不错的东西 为什么不用呢。
最后我的工程结构为
这里写图片描述
首先从 看看api包里的LoginApi 里面是retrofit的网络请求 非常简单 强烈建议大家使用retrofit 我是看这篇文章学习的
https://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653577186&idx=1&sn=1a5f6369faeb22b4b68ea39f25020d28&scene=1&srcid=0605oJ1NiiihvcW5jF8iy3n6&key=f5c31ae61525f82e38a1a943febc987278275256a5df936f1119c6514ebc78df82fc229de80607e2372e4c0f1451e4db&ascene=0&uin=Mjc3OTU3Nzk1&devicetype=iMac+MacBookPro10%2C1+OSX+OSX+10.10.5+build%2814F1808%29&version=11020201&pass_ticket=Yfzg8hN3fuLjjXoQDSG%2BBKWgRxryyVOFVwGFzsu7nB%2FgSZp9gdXJS%2FudxKZSNLan

public interface LoginApi {

    @POST("testMvp.aspx")
    @FormUrlEncoded
    Observable<Response<User>> login(@Field("do") String action, @Field("user_info") String userInfo);

}

base里面封装着基本所有界面和所有业务都需要的方法 这几个类基本不需要做任何修改只需要拷贝到下一个工程 当然你也可以根据需要在里面扩展你想要的方法 关于封装 我借鉴的是
https://github.com/183619962/MVPTest

public class BaseModel {
    //retrofit请求数据的管理类
    public RetrofitManager retrofitManager;

    public BaseModel() {
        //初始化retrofit
        retrofitManager = RetrofitManager.builder();
    }
}
public class BasePresenter <T extends IBaseView,V> implements IBasePresenter, Observer<V> {

    public IBaseView iView;

    /**
     * 构造方法
     *
     * @param view 具体业务的接口对象
     */
    public BasePresenter(T view) {
        this.iView = view;
    }

    @Override
    public void onResume() {

    }

    @Override
    public void onDestroy() {

    }


    @Override
    public void onCompleted() {
        iView.hideProgress();
    }

    @Override
    public void onError(Throwable e) {
        iView.loadDataError(e);
        iView.hideProgress();
    }

    @Override
    public void onNext(V t) {
        iView.loadDataSuccess(t);
    }
}
public interface IBasePresenter {
    /**
     * 开始<br>
     * 用于做一些初始化的操作
     */
    void onResume();

    /**
     * 销毁<br>
     * 用于做一些销毁、回收等类型的操作
     */
    void onDestroy();
}
public interface IBaseView<T> {
    /**
     * 显示提示消息
     *
     * @param msg
     */
    void toast(String msg);

    /**
     * 显示进度
     *
     * @param progress
     */
    void showProgress(int progress);

    /**
     * 隐藏进度
     */
    void hideProgress();

    /**
     * 请求成功
     * @param data
     */
    void loadDataSuccess(T data);

    /**
     * 请求错误
     * @param throwable
     */
    void loadDataError(Throwable throwable);

    /**
     * 开始加载
     */
    void startLoading();
}

好了 前面的基本工作都做完了 界面该实现真正的功能了
我实现的是登陆功能
我先实现登陆功能的逻辑 也就是先实现LoginModel
首先登陆之前需要初始化 登陆请求接口 然后才是传递参数实现登陆 基本上就这个两点 那么转换成代码就是

public class LoginModel extends BaseModel {


    private Context context;
    private LoginApi loginApi;

    /**
     * 初始化登陆请求接口
     * @param context
     */
    public LoginModel(Context context) {
        this.context = context;
        loginApi = retrofitManager.getLoginApi();
    }

    /**
     * 实现登陆
     * @param userName
     * @param pwd
     * @param observer
     */
    public void login(String userName, String pwd, final Observer observer) {
        String userInfo = "{\"name\":\"" + userName + "\"," +
                "\"pwd\":\"" + pwd + "\"" +
                "}";
        loginApi.login("login",userInfo).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Response<User>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                observer.onError(e);
            }

            @Override
            public void onNext(final Response<User> jsonObjectResponse) {
                /**
                 * 延迟一下再返回结果 这样能看到 登陆的动画 可以不用延时直接返回
                 */
                 new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (jsonObjectResponse.code() == 200) {
                            observer.onNext(jsonObjectResponse.body());
                            observer.onCompleted();
                        } else {
                            onError(new Throwable("网络错误"));
                        }
                    }
                },3000);

            }
        });
    }
}

然后实现VIEW
写之前根据逻辑来分析需要哪些方法 登陆的话 需要 用户名和用户密码 这两个是必须的 接下来可以有 清除密码 清除用户名 等 不必须的方法可以用有可以没有 根据上面的分析可以写出以下代码

/**
* 封装好登陆view方法 让activity(也就是view)去实现它
*/
public interface ILoginView extends IBaseView<User>{

    /**
     * 获取用户名
     * @return
     */
    String getUserName();

    /**
     * 获取用户密码
     * @return
     */
    String getPwd();

    /**
     * 清除用户名
     */
    void clearnUserName();

    /**
     * 清除用户密码
     */
    void clearnPwd();

}

接下来就是presenter实现调度了
presenter 首先它需要从view(也就是activity)成拿到数据 然后再把数据交给model(也就是业务层去处理) model处理完业务逻辑 返回数据给 presenter 再有presenter 反馈给 view(activity) 根据这个思路 我们需要定义一个LoginModel 和一个IView

public class LoginPresenter extends BasePresenter<ILoginView,User> {


    private LoginModel loginModel;
    private Context context;

    /**
     * 构造方法
     *
     * @param view 具体业务的接口对象
     */
    public LoginPresenter(ILoginView view,Context context) {
        super(view);
        this.context = context;
        loginModel = new LoginModel(context);
    }

    /**
     * 登陆
     * @param userName
     * @param pwd
     */
    public void login(String userName,String pwd) {
        onResume();
        iView.startLoading();
        iView.showProgress(0);
        loginModel.login(userName,pwd,this);
    }
}

注意此处为什么没有定义IView 是因为BasePresenter里已经定义好了一个IBaseView(可以看看上面的 BasePresenter的定义)
子类继承父类的public IBaseView 自然就存在了 当LoginPresenter被初始化时就会初始化IView

最后一步
真正的view(activity)
初始化activity上的控件 控件有 Edittext userName; Edittext pwd; Button login;
view 和presenter进行交互 view把数据交给presenter
[ 然后presenter把数据交给model,model处理数据(登陆服务器 登陆成分返回数据给presenter presenter 反馈给activity 登陆失败model返回给presenter ,presenter反馈给activity) ] 中括号里的不走 由前面我们定义好的逻辑自动实现

public class LoginActivity extends BaseActivity implements ILoginView {

    @BindView(R.id.editText)
    EditText userName;
    @BindView(R.id.editText2)
    EditText pwd;
    @BindView(R.id.button)
    Button login;
    @BindView(R.id.loginNotice)
    RelativeLayout loginNotice;
    private LoginPresenter loginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState,R.layout.activity_login);
        loginPresenter = new LoginPresenter(this, this);
    }


    @Override
    public String getUserName() {
        return userName.getText().toString();
    }

    @Override
    public String getPwd() {
        return pwd.getText().toString();
    }

    @Override
    public void clearnUserName() {

    }

    @Override
    public void clearnPwd() {

    }

    @Override
    public void toast(String msg) {

    }

    @Override
    public void showProgress(int progress) {
        loginNotice.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        loginNotice.setVisibility(View.GONE);
    }

    /**
     * 请求成功
     *
     * @param data
     */
    @Override
    public void loadDataSuccess(User data) {
        if (data.isMessageStatus()) {
            Toast.makeText(LoginActivity.this, "登陆成功!", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(LoginActivity.this, "登陆失败!" + data.getMessage(), Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * 请求错误
     *
     * @param throwable
     */
    @Override
    public void loadDataError(Throwable throwable) {
        throwable.printStackTrace();
        Toast.makeText(LoginActivity.this, "登陆失败!", Toast.LENGTH_SHORT).show();
    }

    /**
     * 开始加载
     */
    @Override
    public void startLoading() {
        Log.e(TAG,"开始登陆");
    }

    @OnClick(R.id.button)
    public void onClick() {
        loginPresenter.login(getUserName(), getPwd());
    }
}

好了一个mvp的登陆功能就完成 实现更多的功能只需要 按照上面的步骤实现 model 实现IView 实现 presenter 再通过view(activity) 进行调度就行了
本文采用的是 butterknife 有更好的 dragger2 和databinding 深度解耦

此篇文章 我只是从我学习的角度写出来的 有写错的地方请给出意见 如果是大神请飘过

下载前可以先看下教程 https://pan.quark.cn/s/a426667488ae 标题“仿淘宝jquery图片左右切换带数字”揭示了这是一个关于运用jQuery技术完成的图片轮播机制,其特色在于具备淘宝在线平台普遍存在的图片切换表现,并且在整个切换环节中会展示当前图片的序列号。 此类功能一般应用于电子商务平台的产品呈现环节,使用户可以便捷地查看多张商品的照片。 说明中的“NULL”表示未提供进一步的信息,但我们可以借助标题来揣摩若干核心的技术要点。 在构建此类功能时,开发者通常会借助以下技术手段:1. **jQuery库**:jQuery是一个应用广泛的JavaScript框架,它简化了HTML文档的遍历、事件管理、动画效果以及Ajax通信。 在此项目中,jQuery将负责处理用户的点击动作(实现左右切换),并且制造流畅的过渡效果。 2. **图片轮播扩展工具**:开发者或许会采用现成的jQuery扩展,例如Slick、Bootstrap Carousel或个性化的轮播函数,以达成图片切换的功能。 这些扩展能够辅助迅速构建功能完善的轮播模块。 3. **即时数字呈现**:展示当前图片的序列号,这需要通过JavaScript或jQuery来追踪并调整。 每当图片切换时,相应的数字也会同步更新。 4. **CSS美化**:为了达成淘宝图片切换的视觉效果,可能需要设计特定的CSS样式,涵盖图片的排列方式、过渡效果、点状指示器等。 CSS3的动画和过渡特性(如`transition`和`animation`)在此过程中扮演关键角色。 5. **事件监测**:运用jQuery的`.on()`方法来监测用户的操作,比如点击左右控制按钮或自动按时间间隔切换。 根据用户的交互,触发相应的函数来执行...
垃圾实例分割数据集 一、基础信息 • 数据集名称:垃圾实例分割数据集 • 图片数量: 训练集:7,000张图片 验证集:426张图片 测试集:644张图片 • 训练集:7,000张图片 • 验证集:426张图片 • 测试集:644张图片 • 分类类别: 垃圾(Sampah) • 垃圾(Sampah) • 标注格式:YOLO格式,包含实例分割的多边形点坐标,适用于实例分割任务。 • 数据格式:图片文件 二、适用场景 • 智能垃圾检测系统开发:数据集支持实例分割任务,帮助构建能够自动识别和分割图像中垃圾区域的AI模型,适用于智能清洁机器人、自动垃圾桶等应用。 • 环境监控与管理:集成到监控系统中,用于实时检测公共区域的垃圾堆积,辅助环境清洁和治理决策。 • 计算机视觉研究:支持实例分割算法的研究和优化,特别是在垃圾识别领域,促进AI在环保方面的创新。 • 教育与实践:可用于高校或培训机构的AI课程,作为实例分割技术的实践数据集,帮助学生理解计算机视觉应用。 三、数据集优势 • 精确的实例分割标注:每个垃圾实例都使用详细的多边形点进行标注,确保分割边界准确,提升模型训练效果。 • 数据多样性:包含多种垃圾物品实例,覆盖不同场景,增强模型的泛化能力和鲁棒性。 • 格式兼容性强:YOLO标注格式易于与主流深度学习框架集成,如YOLO系列、PyTorch等,方便研究人员和开发者使用。 • 实际应用价值:直接针对现实世界的垃圾管理需求,为自动化环保解决方案提供可靠数据支持,具有重要的社会意义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值