You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中点击按钮动态创建LinearLayout布局的实现

实现方案

1. 重构布局文件

先把需要重复的产品行抽成独立布局item_product.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:background="@drawable/background_round"
    android:orientation="vertical"
    android:padding="5dp"
    android:layout_marginBottom="10dp">

    <!-- 产品选择栏 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">
        <AutoCompleteTextView
            android:id="@+id/tv_product"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:gravity="left"
            android:inputType="text"
            android:hint="Enter Product"/>

        <Button
            android:id="@+id/btn_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="删除"
            android:textColor="@color/white"
            android:background="@color/red"/>
    </LinearLayout>

    <!-- 数量、价格、规格栏 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".5"
            android:orientation="vertical">
            <EditText
                android:id="@+id/prod_qty"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Enter Quantity"
                android:gravity="left"
                android:inputType="number"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".5"
            android:orientation="vertical">
            <EditText
                android:id="@+id/prod_price"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:editable="false"
                android:focusable="false"
                android:focusableInTouchMode="false"
                android:hint="Prod Price"
                android:gravity="left"
                android:inputType="none"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".5"
            android:orientation="vertical">
            <EditText
                android:id="@+id/prod_specs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:editable="false"
                android:focusable="false"
                android:focusableInTouchMode="false"
                android:hint="Prod Specs"
                android:gravity="left"
                android:inputType="none"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

修改原Fragment布局fragment_product.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"
    android:orientation="vertical"
    android:padding="10dp">

    <!-- 动态产品行容器 -->
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <LinearLayout
            android:id="@+id/container_products"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"/>
    </ScrollView>

    <!-- 添加新产品按钮 -->
    <Button
        android:id="@+id/btn_add_product"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add New Product"
        android:textColor="@color/white"
        android:layout_marginTop="10dp"/>
</LinearLayout>

2. 创建产品实体类

存储从JSON读取的产品信息:

public class Product {
    private String name;
    private String price;
    private String specs;

    public Product(String name, String price, String specs) {
        this.name = name;
        this.price = price;
        this.specs = specs;
    }

    public String getName() { return name; }
    public String getPrice() { return price; }
    public String getSpecs() { return specs; }
}

3. 读取本地JSON文件

假设products.json放在assets文件夹下,内容示例:

[
    {"name":"Product A", "price":"100", "specs":"Size M"},
    {"name":"Product B", "price":"200", "specs":"Size L"},
    {"name":"Product C", "price":"150", "specs":"Size S"}
]

实现读取解析逻辑:

private List<Product> loadProductsFromJson() {
    List<Product> productList = new ArrayList<>();
    try {
        InputStream is = getActivity().getAssets().open("products.json");
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        String json = new String(buffer, StandardCharsets.UTF_8);

        JSONArray jsonArray = new JSONArray(json);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObj = jsonArray.getJSONObject(i);
            String name = jsonObj.getString("name");
            String price = jsonObj.getString("price");
            String specs = jsonObj.getString("specs");
            productList.add(new Product(name, price, specs));
        }
    } catch (IOException | JSONException e) {
        e.printStackTrace();
    }
    return productList;
}

4. Fragment核心逻辑

实现动态添加/删除布局、产品选择自动填充功能:

public class ProductFragment extends Fragment {
    private LinearLayout containerProducts;
    private List<Product> productList;
    private ArrayAdapter<String> productAdapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_product, container, false);
        containerProducts = view.findViewById(R.id.container_products);
        Button btnAdd = view.findViewById(R.id.btn_add_product);

        // 加载产品数据并初始化适配器
        productList = loadProductsFromJson();
        List<String> productNames = new ArrayList<>();
        for (Product p : productList) {
            productNames.add(p.getName());
        }
        productAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, productNames);

        // 默认添加一行产品
        addProductRow();

        // 添加按钮点击事件
        btnAdd.setOnClickListener(v -> addProductRow());

        return view;
    }

    // 动态添加产品行
    private void addProductRow() {
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        View productRow = inflater.inflate(R.layout.item_product, containerProducts, false);

        // 获取行内控件
        AutoCompleteTextView tvProduct = productRow.findViewById(R.id.tv_product);
        EditText etPrice = productRow.findViewById(R.id.prod_price);
        EditText etSpecs = productRow.findViewById(R.id.prod_specs);
        Button btnDelete = productRow.findViewById(R.id.btn_delete);

        // 设置产品选择适配器
        tvProduct.setAdapter(productAdapter);

        // 选中产品后自动填充价格和规格
        tvProduct.setOnItemClickListener((parent, view, position, id) -> {
            String selectedName = (String) parent.getItemAtPosition(position);
            for (Product p : productList) {
                if (p.getName().equals(selectedName)) {
                    etPrice.setText(p.getPrice());
                    etSpecs.setText(p.getSpecs());
                    break;
                }
            }
        });

        // 删除当前行
        btnDelete.setOnClickListener(v -> containerProducts.removeView(productRow));

        containerProducts.addView(productRow);
    }

    // 读取本地JSON方法(同步骤3)
    private List<Product> loadProductsFromJson() {
        // ... 实现代码 ...
    }
}

关键说明

  • 将重复布局抽成独立item,避免冗余代码,方便动态生成
  • 使用LayoutInflater加载布局,复用XML中定义的样式和属性
  • 每行单独设置监听,确保删除、产品选择逻辑互不干扰
  • 本地JSON文件放在assets目录,通过AssetManager读取解析

内容的提问来源于stack exchange,提问作者Moeez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:24:10