【问题标题】:Saving dynamically created button android保存动态创建的按钮android
【发布时间】:2015-03-17 21:53:35
【问题描述】:

我正在尝试保存我在单独的活动中动态创建的按钮,但我似乎无法让它工作。这是我在 CreateButton.java 中尝试过的:

    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

public static int generateViewId() {
    for (;;) {
        final int result = sNextGeneratedId.get();
        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
        int newValue = result + 1;
        if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
        if (sNextGeneratedId.compareAndSet(result, newValue)) {
            return result;
        }
    }
}

public void Submit (View view) {
        Intent myIntent = new Intent(CreateNewClass.this, MainActivity.class);
        EditText mEdit   = (EditText)findViewById(R.id.class_name);
        String name = mEdit.getText().toString();

        mEdit   = (EditText)findViewById(R.id.class_semester);
        String semester = mEdit.getText().toString();

        mEdit   = (EditText)findViewById(R.id.class_year);
        String year = mEdit.getText().toString();

        Button myButton = new Button(this);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            myButton.setId(generateViewId());
        }
        else {
            myButton.setId(Button.generateViewId());
        }

        myButton.setText(name + " " + semester + " " + year);

        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout)findViewById(R.id.main_screen);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
                (LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        ll.addView(myButton, layoutParams);

        startActivity(myIntent);
    }

这是我的 activity_main 的 .xml:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_screen"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/select" />

    <Button
        android:layout_height="wrap_content"
        android:clickable="true"
        android:autoLink="web"
        android:layout_width="match_parent"
        android:id="@+id/button_so"
        android:text="@string/Google"
        android:linksClickable="true"
        android:onClick="goToGoogle"/>


    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:text="@string/newClass"
        android:autoLink="web"
        android:clickable="true"
        android:id="@+id/button_su"
        android:onClick="goToCreate"/>
</LinearLayout>

它在 mainActivity 上动态创建按钮并导航到它,但我无法保存按钮,它立即返回到两个原始按钮。

非常感谢任何帮助,我是新手,我只是想学习一些这些东西。谢谢!

【问题讨论】:

    标签: java android button save dynamically-generated


    【解决方案1】:

    那是因为您首先使用setContentView 设置视图,它基本上只显示您在当前活动中膨胀的布局。 之后,您将启动一个新 Activity,它会自行启动一个完全独立的 View,因此仍会显示默认按钮。

    如果要设置文本并在实际 Activity 中添加 Button,最好将 String 作为 Intent Extra 传递。

    所以你的submit 方法应该是这样的:

    //by the way you shouldn't start method names with upper case
    public void submit (View view) {
            Intent myIntent = new Intent(CreateNewClass.this, MainActivity.class);
            EditText mEdit   = (EditText)findViewById(R.id.class_name);
            String name = mEdit.getText().toString();
    
            mEdit   = (EditText)findViewById(R.id.class_semester);
            String semester = mEdit.getText().toString();
    
            mEdit   = (EditText)findViewById(R.id.class_year);
            String year = mEdit.getText().toString();
    
            String buttonText = name + " " + semester + " " + year;
    
            myIntent.putExtra("button_text", buttonText);
    
            startActivity(myIntent);
        }
    

    然后在您的MainActivity 中,您可以通过将以下代码粘贴到onCreate 方法中来放置按钮。

    Intent intent = getIntent();
    String buttonText = intent.getStringExtra("button_text");
    
    //activity could also be started without providing the extra
    if(buttonText != null){
        Button button = new Button(this);
        button.setText(buttonText);
        LinearLayout ll = (LinearLayout)findViewById(R.id.main_screen);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
          (LinearLayout.LayoutParams.WRAP_CONTENT, 
          LinearLayout.LayoutParams.WRAP_CONTENT);
        ll.addView(button, layoutParams);
    }
    

    编辑:

    好的,既然你试图实现的目标与我想的有点不同,你应该尝试其他方法。

    您正试图从第二个 Activity 中获取 Result,因此在这里使用 startActivityForResult()(请参阅 documentation)方法将是完美的。 我假设您的应用程序使用 MainActivity 作为第一个显示的 Activity。

    不是通过发出startActivity() 来启动第二个活动,而是使用startActivityForResult() 提供任何常量作为请求代码。 然后,在您的 submit 方法中,您可以删除 startActivity(myIntent) 行,而是将以下代码放在那里:

    setResult(Activity.RESULT_OK, myIntent);
    finish();
    

    在您的 MainActivity 中,您现在可以使用以下实现覆盖 onActivityResult 方法:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //you specified the request code before, when launching the second activity
        if(requestCode == ADD_USER_REQUEST){
            if(resultCode == Activity.RESULT_OK){
                String buttonText = data.getStringExtra("button_text");
                if(buttonText != null){
                    Button button = new Button(this);
                    button.setText(buttonText);
                    LinearLayout ll = (LinearLayout)findViewById(R.id.main_screen);
                    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
                      (LinearLayout.LayoutParams.WRAP_CONTENT, 
                      LinearLayout.LayoutParams.WRAP_CONTENT);
                    ll.addView(button, layoutParams);
    
                    //here comes the part that saves the button strings persistently
                    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                    Set<String> buttonSet = prefs.getStringSet("saved_buttons",null);
                    if(buttonSet == null){
                        buttonSet = new HashSet<String>();
                    }
                    buttonSet.add(buttonText);
                    prefs.edit.putStringSet("saved_buttons", buttonSet).commit();
                }
    
            }
        }
    

    最后,当 Activity 重新启动时,您需要重建旧布局。把下面的代码放在MainActivity.onCreate里面,删除Intent Extra的东西。

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    Set<String> buttonSet = prefs.getStringSet("saved_buttons", null);
    if(buttonSet != null){
        LinearLayout ll = (LinearLayout)findViewById(R.id.main_screen);
        for(String buttonText : buttonSet){
            Button button = new Button(this);
            button.setText(buttonText);    
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
              (LinearLayout.LayoutParams.WRAP_CONTENT, 
              LinearLayout.LayoutParams.WRAP_CONTENT);
            ll.addView(button, layoutParams);
        }
    }
    

    【讨论】:

    • 非常感谢,这可行,但我希望能够使用任意数量的按钮,而不仅仅是一个。这似乎只是在原始屏幕上添加了一个按钮,如果我尝试添加另一个按钮,它只会更改该按钮的文本,而不是添加第四个按钮
    • 实际上它并没有覆盖上一个按钮,但是旧的按钮并没有保存在任何地方。您是否需要保存它们,以便在应用程序重新启动后可以访问它们?还是只要显示 Activity 就需要它们?您要添加的所有按钮的所有字符串是否同时可用?
    • 啊,是的,我有点明白,只是措辞不正确。我肯定会尝试保存按钮,以便在重新启动后可以访问它们。我一次只有一个按钮可用的字符串。所以理论上我会从主屏幕上的一个按钮开始,添加按钮。我会在主屏幕上按添加按钮,在第二个屏幕上填写名称,然后有 2 个按钮,添加和新创建的按钮。然后按添加并再次执行将产生第三个...如果有比我想的更简单的方法,请随时告诉我,我对它很陌生
    • 我想我知道你现在想做什么了。查看我的编辑
    • 这正是我想要的。 startActivityForResult 非常适合它,我很确定我理解它足以在未来自己实现它。非常感谢您,答案非常有用且具有描述性!
    猜你喜欢
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    相关资源
    最近更新 更多