Detailed use of addView method in Android ViewGroup

Reprinted from: https://blog.csdn.net/qdjdeveloper/article/details/82794727

In daily development, we will involve many architectures such as MVC, MVP, MVVM, etc. If our project itself uses MVP or MVVM architecture, then the code redundancy in Activity and Fragment may be relatively small, but if the design architecture of the project itself It is MVC so that we can also use some other methods to decompose the code redundancy in our Activity and Fragment. Yes, as the title says, use the addView method in ViewGroup to achieve this. Next, we will demonstrate how it is. It's actually very simple.

Here we create a new project to demonstrate that the project name is AddView! ! !

Let’s take a picture to see what we are going to do:

 

It’s the interface above. When you see it, you think it’s too simple. Don’t worry and read it down slowly. It’s relatively simple here, but it’s just a demonstration of ideas. You can understand the reason. Let’s implement it.

First, let's create a BaseCardView code as follows:

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

Next we will implement the 3 buttons we saw

The first one: 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) {
    }
}

Seeing this, everyone should understand why we should write a BaseCardView class first. Here our HeaderCardView  inherits BaseCardView and implements the abstract methods in BaseCardView

Post the header_card_view.xml code, here we write it relatively simple, to illustrate the truth, in fact, the complex interface is the same:

<?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>

Then the code in MiddleCardView and FooterCardView is similar to this, so we don’t need to paste the code one by one, then we will assemble it in FirstActivity

The FirstActivity code is as follows:

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

The corresponding code in activity_first is as follows:

<?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>

I believe that everyone here should understand our realization idea. If the interface is more complicated, we can borrow this idea to realize it. Refine an interface and realize it through small modules to achieve code reuse and maintainability.

The incoming of data, let's look at how to incoming data:

Here we still use HeaderCardView to demonstrate:

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

As you can see, it is actually relatively simple. We define the initViewWithData() function to pass data. Here we simply pass a Sring string. You can pass the specific value according to the actual needs of the project. Next, we only need to Just pass the corresponding value in the class that calls HeaderCardView. For example, let's demonstrate in 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());
        }
    }
}

The running procedure is as follows:

 

       You can see that the value we set has been displayed. For example, if we use a certain module in both interfaces in our daily development, is it easy for us to implement it? Just load our CardView in the corresponding position using addView. Well, although the example here is relatively simple, it provides a way to simplify the complex interface. If you encounter a more complex interface during development, you can borrow this idea to split it to achieve maintainability and reusability. Speaking of reuse, let's look at the convenience of reuse. Here we create SecondActivity as follows:

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

Here we reuse the HeaderCardView. Is it very convenient? Share it here today

Guess you like

Origin blog.csdn.net/qq_37381177/article/details/111592575