Android找工作系列之MVC模式

以来来自百度百科对于MVC的解释:

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

我一般把MVC称为Model层,View层和Controller层,为什么要称之为 "层"呢?因为Model也好,View也好,Controller也好,都不是简单的一个类或者说仅仅只是指某个东西叫Model,View,Controller,这样子就是肤浅了。我把Model描述为 " 数据的来源 ",例如数据可以从网络请求中获取,也可以从文件中获取,也可以从本地数据库中获取,等等,它一种来源方式。View描述为展示数据的方式,在Android中可以用xml文件编写,也可以用代码来编写,而Controller则描述为View和Model交互的地方。

我们来看一个MVC模式的应用:

以下代码摘自:https://blog.csdn.net/m0_37715455/article/details/81877868

①建立一个实体类(比如水果这类,添加其相应的属性)作为ListView适配器的配置类型

Fruit.java

package activitytest.example.wan.listviewtest;
/**
 * Created by wan on 2018/8/19.
 */
public class Fruit {
    private String name;//水果名
    private int imageID;//对应的图片id
    public Fruit(String name,int imageID){
        this.name = name;
        this.imageID = imageID;
    }
    public String getName(){
        return name;
    }
    public int getImageID(){
        return imageID;
    }
}

②用ListView的子项指定一个我们自定义的布局

 fruit_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="100dp"
        android:layout_height="100dp" />
    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp" />
</LinearLayout>

③创建一个自定义适配器,继承ArrayAdapter,将泛型指定为Fruit类

public class FruitAdapter extends ArrayAdapter<Fruit> {
 
    private int resourceID;
    public FruitAdapter(Context context, int textViewResourceId,List<Fruit>objects){
        super(context,textViewResourceId,objects);
        resourceID = textViewResourceId;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Fruit fruit = getItem(position);//获得当前项fruit实例
        //动态加载布局文件
        View view = LayoutInflater.from(getContext()).inflate(resourceID,parent,false);
        //找实例
        ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
        TextView fruitName =(TextView)view.findViewById(R.id.fruit_name);
        //设置显示图片和文字
        fruitImage.setImageResource(fruit.getImageID());
        fruitName.setText(fruit.getName());
        //返回布局
        return view;
    }
}

④修改MainActivity代码

public class MainActivity extends AppCompatActivity {
    //定义个容器
    private List<Fruit> fruitList = new ArrayList<>();
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();//初始化传入数据,函数的调用
 
        FruitAdapter adapter = new FruitAdapter(MainActivity.this,
                R.layout.fruit_item,fruitList);
        //上下文、新写的布局id、要配置的数据(ArrayList类型)
        //创建了FruitAdapter对象,并将它作为适配器传递给ListView
 
        ListView listView =(ListView)findViewById(R.id.list_view);
        listView.setAdapter(adapter);//将构造好的适配器对象传递进去
    }
    private void initFruits(){
            Fruit apple = new Fruit("Apple",R.drawable.apple);
            fruitList.add(apple);
            Fruit banana = new Fruit("Banana",R.drawable.banana);
            fruitList.add(banana);
            Fruit orange = new Fruit("Orange",R.drawable.orange);
            fruitList.add(orange);
            Fruit watermelon = new Fruit("Watermelon",R.drawable.watermelon);
            fruitList.add(watermelon);
            Fruit pear = new Fruit("Pear",R.drawable.pear);
            fruitList.add(pear);
            Fruit grape = new Fruit("Grape",R.drawable.grape);
            fruitList.add(grape);
            Fruit pineapple = new Fruit("Pineapple",R.drawable.pineapple);
            fruitList.add(pineapple);
            Fruit strewbarry = new Fruit("Strawberry",R.drawable.strawberry);
            fruitList.add(strewbarry);
            Fruit cherry = new Fruit("Cherry",R.drawable.cherry);
            fruitList.add(cherry);
            Fruit mango = new Fruit("Mango",R.drawable.mango);
            fruitList.add(mango);
    }
}

来进行详解下:

View层:

很明显 fruit_item.xml是View层,用来展示视图。Fruit这个类是Model层吗?并不是,我更愿意称之为ViewData,为什么这么说?因为 Fruit的所有字段都是fruit_item.xml需要展示的数据,所以我把 fruit_item.xml与Fruit这个类一起称之为View层。

FruitAdapter是Controller吗?乍看之下,很像。其实并不是,它的作用是把ViewData和fruit_item.xml匹配起来,仅仅只是把ViewData的字段塞进fruit_item.xml而已,所以把Fruit,fruit_item.xml,FruitAdapter一起称之为View层。

Model层:

那么Model层哪一个呢?我说过了,Model描述为数据来源,是Model层在MainActivity中initFruits()方法,它创建了很多的Fruit对象,并放置于List数组中,所有说咯,这些数据,可以从文件中来,也可以从本地数据库中来,当然更可以从网络请求中来,所以很常见的是我们从网络请求,本地,数据库等获取来的数据和Fruit的字段可能并不一样,需要转换,比如网络请求中会获取大量无用的数据,或者字段也和Fruit的字段也不一样,需要转换下。如果我们从网络请求中获取数据,我们需要写Post请求;从文件中获取,我们需要写读取文件的类;所以我更愿意把数据的来源成为Model层。

Controller层:

那么Controller层是哪个呢?是MainActivity,我说过了Controler是Model层和View层交互的地方,想想看,VIew层的数据在哪里装配?在MainActivity装配,如果ListView需要设置事件监听,在哪里设置?listview.setOnItemClickListener在MainActivity中设置。

比如点击了listview的其中一个item需要重新获取数据,是不是也在MainActivity中交互?

总结:

View层的需要显示数据ViewData?从哪里来?Controller层会使用Model层来获取到所需数据。

View层所输入事件,例如listview.setOnItemClickListener,谁去相应?Controller层会去相应,执行操作。

再啰嗦几句:

往小了说:View层可以不用xml写,也可以用代码写,或者h5来写,View层也不一定就是固定的,Controller层也是一样,可以替换,Model层也是一样的,如上图可以有多个数据来源。

往大了说:View层不一定就在本地,这话说得有点绕,比如说现在不是前后端分离吗?web有自己的服务,后端也有自己的服务,web界面上点击了一个视图,会发送一个请求给后端,后端处理完自己的逻辑,返回数据,然后更新视图。那么前端就是view层;后端+json格式数据就是controller层,后端通过json格式数据来控制前端view层界面展示。这样子,view层即可以是web前端,也可以是android,ios等用来展示数据,json格式

这样子,才可以达到MVC分离的目的。

猜你喜欢

转载自www.cnblogs.com/hbolin/p/11025169.html
今日推荐