当前位置: 首页 > 工具软件 > Clock View > 使用案例 >

Android MVP设计架构:Model层数据传递到View层

仇经武
2023-12-01

一个常见的场景:处于UI的View层点击了下载的Button按钮,然后转入到Presenter层,此时当然会在Presenter层里面触发Model层的下载任务代码模块。但是,View层UI控件需要实时显示下载进度怎么办?
要知道只有Model层才真正知道下载进度,Presenter层对进度一无所知。对于这种情况有两种方法把
需要在Presenter层的函数里面,当在调用Model层的下载请求时候实现一个回调函数(假设它叫做Callback),然后在Presenter层的匿名Callback内部类实现里面实时调用View的进度更新即可。如代码:

架构建模:

package zhangphil.demo;

public interface Model<T, R> {
    R request(T t, Callback callback);
}
package zhangphil.demo;

public interface View<T> {
    void progress(T t);
}
package zhangphil.demo;

public interface Presenter<T> {
    void action(T t);

    void progress(int i);
}
package zhangphil.demo;

public interface Callback<T,R> {
    R call(T t);
}

模型实现:

package zhangphil.demo;

import android.os.SystemClock;
import java.util.concurrent.CompletableFuture;

public class LoadModel implements Model<String, Object> {
    private Presenter presenter;

    public LoadModel(Presenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public Object request(String s, final Callback callback) {
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <= 100; i++) {
                    SystemClock.sleep(100);

                    if (callback != null)
                        callback.call(i);
                }
            }
        });

        return null;
    }
}

 

package zhangphil.demo;

public interface LoadView<T> extends View<Integer> {
    void status(T t);
}

 

package zhangphil.demo;

public class LoadPresenter implements Presenter<String> {
    private LoadView view;
    private Model model;

    public LoadPresenter(LoadView view) {
        this.view = view;
        model = new LoadModel(this);
    }

    @Override
    public void action(String s) {
        model.request(s, new Callback<Integer, Object>() {
            @Override
            public Object call(Integer i) {
                updateProgress(i);
                return null;
            }
        });
    }

    @Override
    public void progress(int i) {

    }

    private void updateProgress(int i) {
        view.progress(i);

        if (i > 0 && i < 100) {
            view.status("下载中...");
        }

        if (i == 100) {
            view.status("下载完成");
        }
    }
}

 

测试:

package zhangphil.demo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements LoadView<String> {
    private TextView progress,status;
    private Button button;

    private Presenter presenter;

    private AppCompatActivity activity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = this;

        setContentView(R.layout.activity_main);

        progress = findViewById(R.id.progress);
        button = findViewById(R.id.button);
        status=findViewById(R.id.status);

        presenter = new LoadPresenter(this);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.action("https://zhangphil.blog.csdn.net/");
            }
        });
    }

    @Override
    public void status(final String s) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                status.setText(s);
            }
        });
    }

    @Override
    public void progress(final Integer i) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                progress.setText(i + " %");
            }
        });
    }
}

 

 

另外一种方案,不使用Callback回调,直接在Model层调用Presenter层预设的更新函数,在此函数里面进一步触发View的更新,如:

package zhangphil.demo;

public interface Model<T, R> {
    R request(T t);
}
package zhangphil.demo;

public interface View<T> {
    void progress(T t);
}
package zhangphil.demo;

public interface Presenter<T> {
    void action(T t);

    void progress(int i);
}

 

框架模型实现:

package zhangphil.demo;

import android.os.SystemClock;
import java.util.concurrent.CompletableFuture;

public class LoadModel implements Model<String, Object> {
    private Presenter presenter;

    public LoadModel(Presenter presenter) {
        this.presenter = presenter;
    }

    /**
     * 模拟下载。
     *
     * @param s
     * @return
     */
    @Override
    public Object request(String s) {
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <= 100; i++) {
                    SystemClock.sleep(100);

                    presenter.progress(i);
                }
            }
        });

        return null;
    }
}

 

package zhangphil.demo;

public interface LoadView<T> extends View<Integer> {
    void status(T t);
}
package zhangphil.demo;

public class LoadPresenter implements Presenter<String> {
    private LoadView view;
    private Model model;

    public LoadPresenter(LoadView view) {
        this.view = view;
        model = new LoadModel(this);
    }

    @Override
    public void action(String s) {
        model.request(s);
    }

    @Override
    public void progress(int i) {
        updateProgress(i);
    }

    private void updateProgress(int i) {
        view.progress(i);

        if (i > 0 && i < 100) {
            view.status("下载中...");
        }

        if (i == 100) {
            view.status("下载完成");
        }
    }
}

 

测试:

package zhangphil.demo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements LoadView<String> {
    private TextView progress, status;
    private Button button;

    private Presenter presenter;

    private AppCompatActivity activity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = this;

        setContentView(R.layout.activity_main);

        progress = findViewById(R.id.progress);
        button = findViewById(R.id.button);
        status = findViewById(R.id.status);

        presenter = new LoadPresenter(this);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.action("https://zhangphil.blog.csdn.net/");
            }
        });
    }

    @Override
    public void status(final String s) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                status.setText(s);
            }
        });
    }

    @Override
    public void progress(final Integer i) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                progress.setText(i + " %");
            }
        });
    }
}


 

 类似资料: