Android ViewGroup 中 addView 方法使用详解

转载自:https://blog.csdn.net/qdjdeveloper/article/details/82794727

在日常开发中 我们会涉及到很多架构 例如 MVC  MVP MVVM 等等,如果我们的项目本身就是用 MVP 或 MVVM 架构, 那么 Activity 和 Fragment 中的代码冗余可能会相对小一些 但是如果项目的设计架构本身就是 MVC 这样我们还可以用其他的一些方法来分解我们 Activity 和 Fragment 中的代码冗余,对,就像标题中说的,利用 ViewGroup 中的 addView 方法来实现 接下来我们就来演示一下具体是如何来做到的,其实非常简单。

这里我们新建一个工程来演示 工程名就为 AddView 吧!!!

先上一张图来看看我们要做的东西:

就是上面的界面  大家看到这里觉得这也太简单了 别着急 慢慢再往下看,这里的是比较简单,但这里只是用来做思想演示,道理大家明白就可以,下面我们来实现

首先我们来创建一个 BaseCardView 代码如下:

public abstract class BaseCardView {
    
    private Context mContext;
    private View mView;
    
    /**
     * 创建 card 不添加到 rootView 中
     *
     * @param root 需要添加的 rootView,不可以为空
     */

    public BaseCardView(Context context, @NonNull ViewGroup root) {
        this(context, root, false);
    }

    /**
     * 创建 card
     *
     * @param root 需要添加的 rootView,不可以为空
     * @param attachToRoot 是否添加到 rootView
     */
    public BaseCardView(Context context, @NonNull ViewGroup root, boolean attachToRoot) {
        mContext = context;
        createView(context, root, attachToRoot);
    }


    private void createView(Context context, ViewGroup root, boolean attachToRoot) {
        mView = LayoutInflater.from(context).inflate(onBindLayoutId(), root, attachToRoot);
        onViewCreated(mView);
    }
    
    protected abstract int onBindLayoutId();

    protected abstract void onViewCreated(View view);

    public View getView() {
        return mView;
    }
    
    protected Context getContext() {
        return mContext;
    }
}

接下来我们来实现我们看到的 3 个按钮

第一个:HeaderCardView:

public class HeaderCardView extends BaseCardView {
    
    public HeaderCardView(Context context, @NonNull ViewGroup root) {
        super(context, root);
    }

    @Override
    protected int onBindLayoutId() {
        return R.layout.header_card_view;
    }

    @Override
    protected void onViewCreated(View view) {
    }
}

看到这里,大家应该明白我们为什么要先写一个 BaseCardView 类  这里我们 HeaderCardView 继承 BaseCardView 并实现 BaseCardView 中的抽象方法

贴出 header_card_view.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="wrap_content"
    android:layout_marginTop="20dp"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="HeaderView"
        android:textSize="20dp" />
</LinearLayout>

然后 MiddleCardView 和 FooterCardView 中的代码和这个类似,就不再一一贴代码,接下来我们在 FirstActivity 中进行组装

FirstActivity 代码如下:

public class FirstActivity extends AppCompatActivity {
    
    //引入需要组装的 CardView
    private HeaderCardView headerCardView;
    private MiddleCardView middleCardView;
    private FooterCardView footerCardView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    /**
     * 初始化 View
     */
    private void initView() {
        LinearLayout mContainer = findViewById(R.id.ll_container);
        addView(mContainer);
    }

    /**
     * 添加 View
     * @param mContainer
     */

    private void addView(LinearLayout mContainer) {
        addHerderCardView(mContainer);
        addMiddleCardView(mContainer);
        addFooterCardView(mContainer);
    }

    /**
     * 添加 HerderCardView
     * @param mContainer
     */
    private void addHerderCardView(LinearLayout mContainer) {
        if (headerCardView == null) {
            headerCardView = new HeaderCardView(this, mContainer);
            headerCardView.initViewWithData("你好");
            mContainer.addView(headerCardView.getView());
        }
    }
    
    /**
     * 添加 MiddleCardView
     * @param mContainer
     */
    private void addMiddleCardView(LinearLayout mContainer) {
        if (middleCardView == null) {
            middleCardView = new MiddleCardView(this, mContainer);
            mContainer.addView(middleCardView.getView());
        }
    }
    
    /**
     * 添加 FooterCardView
     * @param mContainer
     */
    private void addFooterCardView(LinearLayout mContainer) {
        if (footerCardView == null) {
            footerCardView = new FooterCardView(this, mContainer);
            mContainer.addView(footerCardView.getView());
        }
    }
}

对应 activity_first 中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".FirstActivity">

    <LinearLayout
        android:id="@+id/ll_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />

</LinearLayout>

相信看到这里大家应该看明白了我们的实现思路,如果界面比较复杂我们就可以借用此思想来实现,把一个界面细化,通过小模块来实现  达到代码的复用和可维护。

数据的传入,接下来我们来看数据如何传入:

这里我们仍然用 HeaderCardView 来做演示 :

public class HeaderCardView extends BaseCardView {
    
    private Button btn;

    public HeaderCardView(Context context, @NonNull ViewGroup root) {
        super(context, root);
    }
    
    @Override
    protected int onBindLayoutId() {
        return R.layout.header_card_view;
    }

    @Override
    protected void onViewCreated(View view) {
        btn = view.findViewById(R.id.btn);
    }

    public void initViewWithData(String data) {
        btn.setText(data);
    }
}

大家看到,其实是比较简单的  我们定义了 initViewWithData() 函数 用来传递数据 这里我们只简单的来传递一个 Sring 字符串,大家可以根据项目实际需要来传具体的值,接下来我们只需要在调用 HeaderCardView 的类中传递相应的值即可,例如我们在FirstActivity 中做一下演示:

public class FirstActivity extends AppCompatActivity {
    
    private HeaderCardView headerCardView;
    private MiddleCardView middleCardView;
    private FooterCardView footerCardView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    
    private void initView() {
        LinearLayout mContainer = findViewById(R.id.ll_container);
        addView(mContainer);
    }
    
    private void addView(LinearLayout mContainer) {
        addHerderCardView(mContainer);
        addMiddleCardView(mContainer);
        addFooterCardView(mContainer);
    }

    private void addHerderCardView(LinearLayout mContainer) {
        if (headerCardView == null) {
            headerCardView = new HeaderCardView(this, mContainer);
            headerCardView.initViewWithData("你好");
            mContainer.addView(headerCardView.getView());
        }
    }
    
    private void addMiddleCardView(LinearLayout mContainer) {
        if (middleCardView == null) {
            middleCardView = new MiddleCardView(this, mContainer);
            mContainer.addView(middleCardView.getView());
        }
    }
    
    private void addFooterCardView(LinearLayout mContainer) {
        if (footerCardView == null) {
            footerCardView = new FooterCardView(this, mContainer);
            mContainer.addView(footerCardView.getView());
        }
    }
}

运行程序如下:

       大家看到我们设置的值已经显示出来,例如我们在日常开发中如果两个界面都用到某一个模块 是不是我们很容易就能实现,只需在对应位置把我们的 CardView 使用 addView 加载进去就好,这里的例子虽然比较简单,但是提供了一种把复杂界面简单化的思想,大家如果在开发中遇到比较复杂的界面 可以借用此思想进行拆分,达到可维护以及可复用性,说到复用我们具体看下复用的方便性,这里我们创建 SecondActivity 如下:

public class SecondActivity extends AppCompatActivity {

    private HeaderCardView headerCardView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        initView();
    }

    private void initView() {
        LinearLayout mContainer = findViewById(R.id.ll_container);
        addView(mContainer);
    }

    private void addView(LinearLayout mContainer) {
        addHerderCardView(mContainer);
    }
    
    private void addHerderCardView(LinearLayout mContainer) {
        if (headerCardView == null) {
            headerCardView = new HeaderCardView(this, mContainer);
            mContainer.addView(headerCardView.getView());
        }
    }
}

这里我们对 HeaderCardView 进行了复用  是不是就显得非常方便,今天就分享到这里

猜你喜欢

转载自blog.csdn.net/qq_37381177/article/details/111592575