“onRadioButtonClicked”方法不适用于“onCreate”方法实现的单选按钮

Posted

技术标签:

【中文标题】“onRadioButtonClicked”方法不适用于“onCreate”方法实现的单选按钮【英文标题】:"onRadioButtonClicked" method not working for radio button implemented by "onCreate" method 【发布时间】:2019-02-13 06:03:46 【问题描述】:

我尝试在“onCreateMethod”上填充 RadioGroup 的 RadioButtons,而不是使用 XML,因为我的目的是从某种数据库或其他具有随机性的业务对象模型中获取它。单选按钮很好,但是当我单击它们时没有任何反应,否则当我在 XML 活动文件中创建时,不是日志消息,也不是测试吐司。顺便说一句,正如我所说,我需要通过代码创建按钮,谢谢,这是我在 android 中的第一步。

我的活动 XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/quiz"
android:layout_
android:layout_
android:orientation="vertical">
</LinearLayout>

我的代码:

public class ListaAlunosActivity extends AppCompatActivity 


    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lista_alunos);

        LinearLayout questoesQuiz = (LinearLayout) findViewById(R.id.quiz);
        // Log.d(TAG,"Populate List View; Displaying Data in the List View");

        ArrayList<String> dataList = new ArrayList<>(Arrays.asList("sup1", "sup2", "sup3"));
        RadioGroup listaDeQuestoes = new RadioGroup(this);
        listaDeQuestoes.setOrientation(RadioGroup.VERTICAL);
        RadioGroup.LayoutParams lp;

        for (int i = 0; i < dataList.size(); i++) 
            RadioButton botao = new RadioButton(this);
            botao.setText(dataList.get(i));
            lp = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT, RadioGroup.LayoutParams.MATCH_PARENT);
            listaDeQuestoes.addView(botao, lp);
        
        questoesQuiz.addView(listaDeQuestoes);
    


    public void onRadioButtonClicked(View view) 

        boolean checked = ((RadioButton) view).isChecked();


        final String TAG = "MyActivity";


        Log.v("On clicked working", "clicado");

        int id = view.getId();


        Toast toast2 = Toast.makeText(this, "toast working", Toast.LENGTH_LONG);
        toast2.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
        toast2.show();
  

按钮没问题!

【问题讨论】:

【参考方案1】:

使用onClick 查找选定的单选按钮不是最好的解决方案,但因为您想使用onClick,我将向您展示如何在对代码进行最少更改的情况下做到这一点。对您的代码进行以下三项更改:

public class ListaAlunosActivity extends AppCompatActivity 
        implements View.OnClickListener // <------ 1. implement OnClickListener

protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lista_alunos);

        LinearLayout questoesQuiz = (LinearLayout) findViewById(R.id.quiz);
        // Log.d(TAG,"Populate List View; Displaying Data in the List View");

        ArrayList<String> dataList = new ArrayList<>(Arrays.asList("sup1", "sup2", "sup3"));
        RadioGroup listaDeQuestoes = new RadioGroup(this);
        listaDeQuestoes.setOrientation(RadioGroup.VERTICAL);
        RadioGroup.LayoutParams lp;

        for (int i = 0; i < dataList.size(); i++) 
            RadioButton botao = new RadioButton(this);
            botao.setOnClickListener(this);//  <---------- 2.add this line
            botao.setText(dataList.get(i));
            lp = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT, RadioGroup.LayoutParams.MATCH_PARENT);
            listaDeQuestoes.addView(botao, lp);
        
        questoesQuiz.addView(listaDeQuestoes);
    
@Override
public abstract void onClick (View v) //<-------- 3. override onClick
   boolean checked = ((RadioButton) v).isChecked();


        final String TAG = "MyActivity";


        Log.v("On clicked working", "clicado");

        int id = v.getId();// your radio buttons have no id thus use title instead of id:
        String title = ((RadioButton) v).getText();


        Toast toast2 = Toast.makeText(this, "toast working", Toast.LENGTH_LONG);
        toast2.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
        toast2.show();

【讨论】:

这三件事你可能是对的。但我相信 OP 使用一般的 onClick 方法也会对您的代码有问题。用户可以点击Activity 的任意位置并触发onClick 方法。在这种情况下,返回的View "v" 不一定是RadioButton。除了这个代码((RadioButton) view).isChecked(); 不能工作 @Barns 我没有将thisActivity 设置为根布局或任何其他视图的侦听器,我只是将thisActivity 设置为单选按钮的侦听器,因此单击单选按钮以外的任何位置都会不触发此侦听器的onClickonClickview 参数始终为RadioButton 您关于onClick() 的观点仅指向RadioButton 我承认。但是,我坚持我的说法,((RadioButton) view).isChecked(); 不能工作......“视图”没有定义!定义了“v”,但没有定义“view”。 @Barns 正如我所说,我复制粘贴了问题,只添加了三个更改。这个 v 或视图非常微妙,只是在 ide 中显示为语法错误 @Barns 代码中可能有更大的错误,但我专注于主要问题【参考方案2】:

如果您仔细观察,您的 onRadioButtonClicked 只是一个永远不会调用的方法。现在你要做的是让 Activity 实现 RadioGroup.OnCheckedChangeListener。在 onCheckedChanged 方法中,执行 Toast 即可。这是代码。

public class ListaAlunosActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener 


protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_lista_alnus);

    LinearLayout questoesQuiz = (LinearLayout) findViewById(R.id.quiz);
    // Log.d(TAG,"Populate List View; Displaying Data in the List View");

    ArrayList<String> dataList = new ArrayList<>(Arrays.asList("sup1", "sup2", "sup3"));
    RadioGroup listaDeQuestoes = new RadioGroup(this);
    listaDeQuestoes.setOrientation(RadioGroup.VERTICAL);
    RadioGroup.LayoutParams lp;

    for (int i = 0; i < dataList.size(); i++) 
        RadioButton botao = new RadioButton(this);
        botao.setId(i);
        botao.setText(dataList.get(i));
        lp = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT, RadioGroup.LayoutParams.MATCH_PARENT);
        listaDeQuestoes.addView(botao, lp);
    
    questoesQuiz.addView(listaDeQuestoes);

    listaDeQuestoes.setOnCheckedChangeListener(this);




@Override
public void onCheckedChanged(RadioGroup group, int checkedId) 
    Toast toast2 = Toast.makeText(this, "toast working for id "+ checkedId, Toast.LENGTH_LONG);
    toast2.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
    toast2.show();


我做到了,效果很好

【讨论】:

【参考方案3】:

不完全确定您的代码的用途,但我会使用 setOnCheckedChangeListener 而不是 onClick。

类似的东西

    listaDeQuestoes.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
    
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) 
            final String TAG = "MyActivity"; // not used?

            Log.v("On clicked working", "clicado");

            // Note checkedId is +1 when accessing the arraylist so needs to be decremented to get a list item
            Toast toast2 = Toast.makeText(ListaAlunosActivity.this, "toast working clicked (" + checkedId + ") [" + dataList.get(checkedId - 1) + "]", Toast.LENGTH_LONG);
            toast2.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
            toast2.show();
        
    );

Toast 正在工作,我展示了如何确定单击了哪个按钮以及如何使用它访问数据数组(如果需要)。

【讨论】:

【参考方案4】:

正如 BAHMAN 指出的那样,主要原因是您没有设置任何侦听器。然而。在按钮本身上设置监听器并不是一个好主意。最好设置在广播组上。最好在布局文件中包含布局元素。这使它们更容易修改和理解。

个人偏好的另一件事:我更喜欢将侦听器实现为设置它的匿名类。类实现侦听器的解决方案使得大型类更难阅读,因为寻找侦听器可能很烦人。如果监听器非常复杂,或者它可能被多次使用,我可能会例外。

我还清理了一些代码。在我做的地方添加了评论

不管怎样,我会这样写代码:

主要活动布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/quiz"
    android:layout_
    android:layout_
    android:orientation="vertical">

    <RadioGroup
        android:id="@+id/radio_button_list"
        android:layout_
        android:layout_ />
</LinearLayout>

主要活动代码:

public class ListaAlunosActivity extends AppCompatActivity 
    // I put your tag at the top of the class so it's more useful
    public static final String TAG = "ListaAlunosActivity"; 

    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lista_alunos);

        // You didn't really need an arraylist here for this static content.
        // I just made it an array
        String[] dataList = "sup1", "sup2", "sup3"; 

        // Get this from your layout instead of adding it manually.
        // It's a cleaner way to set up the layout that makes the
        // code more maintainable
        RadioGroup listaDeQuestoes = findViewById(R.id.radio_button_list);

        // I changed this to a for each loop because it's a little cleaner
        for (String name : dataList)
            RadioButton botao = new RadioButton(this);
            botao.setText(name);
            listaDeQuestoes.addView(botao);
        

        // This is the code that will react to the new radio button being selected 
        listaDeQuestoes.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() 
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) 
                // Either way we do it, we need to grab the view to get the name
                RadioButton buttonView = group.findViewById(checkedId);

                // You can use this code to get the index if you need it
                int checkedIndex = group.indexOfChild(buttonView);

                // And you can use either of these methods to get the name:
                String buttonNameFromView = buttonView.getText().toString();
                String buttonNameFromDataSource = dataList[checkedIndex];

                String output = "Button with Id: " + checkedId + " and Name: " + buttonNameFromView + " was clicked";

                Log.v(TAG, output);

                Toast toast = Toast.makeText(ListaAlunosActivity.this, output, Toast.LENGTH_LONG);
                // I set gravity to just center here.  This is the same as center_vertical | center_horizontal.  Personally, I wouldn't set it at all.
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
            
        );
    

【讨论】:

我同意您的解决方案比使用 onClick 更好,但您还应该更改 onCreate 方法以将 id 添加到每个 RadioButton 否则您不知道在 @987654326 上选中了哪个单选按钮@。特别是您的这行答案是错误的:dataList[checkedId] 啊,是的,已编辑。谢谢!不过,他不需要显式添加 ID。这对于静态列表更有用。新代码将确保我们从 Id 中获得正确的索引。或者,如果他有一本字典之类的东西,他可以用它作为一个 ID。但它似乎通常比它的价值更麻烦。或者他可以只检查视图的名称。

以上是关于“onRadioButtonClicked”方法不适用于“onCreate”方法实现的单选按钮的主要内容,如果未能解决你的问题,请参考以下文章

javascript对象不支持的属性或方法

方法重载和覆盖不一样

IE浏览器运行脚本显示“对象不支持此属性或方法”

网页显示不全的解决方法

不允许的方法 (POST):/profiles/flash/ 不允许的方法:/profiles/flash/

“方法不允许 请求的 URL 不允许该方法。”