【问题标题】:Add a dynamic button to the view and save it permanently将动态按钮添加到视图并永久保存
【发布时间】:2021-06-30 16:21:43
【问题描述】:

我有一个带有这种视图的片段:

XML:

<?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:tag="general"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#343535"
    android:orientation="vertical"
    tools:context=".fragments.GeneralFragment">

    <Button
        android:id="@+id/hello"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:onClick="onClick"
        android:text="@string/hello" />

    <Button
        android:id="@+id/observed"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:onClick="onClick"
        android:text="@string/observed" />

    <Button
        android:id="@+id/thanks"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:onClick="onClick"
        android:text="@string/thanks" />

</LinearLayout>

有 3 个按钮。每当您单击其中一个时,都会显示其文本。

现在我想动态添加另一个按钮。应该加在@+id/hello之前。

我试过了

LinearLayout root = (LinearLayout) view.findViewById(R.id.root);
root.addView();

但它看起来完全错误,因为缺少一些参数。

例如,新按钮应该是这样的:

XML:

<Button
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:gravity="center_vertical"
    android:onClick="onClick"
    android:text="I am a dynamic text" />

此按钮应永久保存在应用中。我该怎么做?

更新

我正在使用一个对话框,所以这是类:

@SuppressLint("ValidFragment")
public class Dialog extends DialogFragment {
    private final int _layout;
    private TextInputEditText _customTextField;

    @SuppressLint("ValidFragment")
    public Dialog(int layout) {
        _layout = layout;
    }

    public interface ICustomTts {
        void customTts(String input, Activity activity);
    }
    public ICustomTts iCustomTts;

    public interface  ITarget {
        void getTarget(String input);
    }
    public ITarget iTarget;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        final View view =  inflater.inflate(_layout, container, false);

        // Display fragment_custom
        if (_layout == R.layout.fragment_custom) {
            _customTextField = view.findViewById(R.id.customTextField);
            Button _customBtn = view.findViewById(R.id.customCta);
            _customBtn.setOnClickListener(new View.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onClick(View view) {
                    Log.d(TAG, "onClick: Clicked on CTA of custom");
                    String input = _customTextField.getText().toString();
                    if (!input.equals("")) {
                        iCustomTts.customTts(input, getActivity());
                        _dismiss();
                    }
                }
            });
            MaterialCheckBox customeSave = view.findViewById(R.id.customSave);
            customeSave.setOnClickListener(new View.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "customeSave was clicked!");
                    LinearLayout root = view.findViewById(R.id.root);
                    Button button = new Button(getContext());
                    float heightInPixel = 60 * getResources().getDisplayMetrics().density;
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) heightInPixel);
                    params.gravity = Gravity.CENTER;
                    button.setText("I am a dynamic text");
                    button.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            // Do the stuff on the click
                        }
                    });

                    root.addView(button, 0);
                }
            });
        }

        // Display fragment_target
        if (_layout == R.layout.fragment_target) {
            _customTextField = view.findViewById(R.id.targetTextField);
            Button _customBtn = view.findViewById(R.id.targetCta);
            _customBtn.setOnClickListener(new View.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onClick(View view) {
                    Log.d(TAG, "onClick: Clicked on CTA of target");
                    String input = _customTextField.getText().toString();
                    if (!input.equals("")) {
                        iTarget.getTarget(input);
                        _dismiss();
                    }
                }
            });
        }
        return view;
    }

    /**
     * Dismissing the dialog
     */
    private void _dismiss() {
        this.dismiss();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            if (_layout == R.layout.fragment_custom) {
                iCustomTts = (ICustomTts) getActivity();
            }
            else if (_layout == R.layout.fragment_target) {
                iTarget = (ITarget) getActivity();
            }
        }
        catch (ClassCastException e) {
            Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage());
        }
    }
}

【问题讨论】:

    标签: java android android-layout button android-dialogfragment


    【解决方案1】:

    您需要使用addView()的两个参数版本来确定LinearLayout内按钮的顺序(索引):

    LinearLayout root = view.findViewById(R.id.root);
    Button button = new Button(requireContext());
    float heightInPixel = 60 * getResources().getDisplayMetrics().density;
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) heightInPixel);
    params.gravity = Gravity.CENTER;
    button.setText("I am a dynamic text");
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Do the stuff on the click
        }
    });
    
    root.addView(button, 0);
    

    【讨论】:

    • 谢谢。 view.requireContext() 给了我错误无法在“视图”中解析方法“requireContext”。相反,我用view.getContext() 尝试过,但是当我运行我的应用程序时,我收到了这个错误:Attempt to invoke virtual method 'void android.widget.LinearLayout.addView(android.view.View, int)' on a空对象引用
    • 我在扩展 DialogFragment 的类中使用您的代码。会不会是这个原因?
    • 抱歉只用 requireContext 或 getContext
    • 正如我所说,我已经使用了 getContext() 但随后出现错误:尝试调用虚拟方法 'void android.widget.LinearLayout.addView(android.view.View, int )' 在空对象引用上
    • @Reza 你能提供这个定制的DialogFragment 的骨架吗.. 特别是你膨胀布局的部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多