In Android Studio, developing in Java, I have the following (a somewhat minimized version of what I'm trying to do).
package com.example.japanesequiz;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
String[] hiragana = {"あ", "か"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button generate = findViewById(R.id.generate);
TextView questionText = findViewById(R.id.question_text);
RadioGroup radioGroup = new RadioGroup(this);
MainActivity ma_inst = this;
generate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Random rand = new Random();
int hir_index = rand.nextInt(2);
questionText.setText(hiragana[hir_index]);
RadioButton rb1 = new RadioButton(ma_inst);
rb1.setId(View.generateViewId());
rb1.setText("Ah");
radioGroup.addView(rb1);
RadioButton rb2 = new RadioButton(ma_inst);
rb2.setId(View.generateViewId());
rb2.setText("Ka");
radioGroup.addView(rb2);
}
});
}
}
The basic idea is that I want to have the main screen initially mostly blank, but with a button at the bottom. When tapped, it eventually show some text and a radio button group. (I haven't yet fully built out the rest, of course.)
But at this stage what I expect when I launch the app is to see the mostly blank screen, and maybe if I tap the button it will generate some text and options (that then do nothing, further implementation to come).
But the app never launches. Instead, Graddle finishes building, I get a terminal saying that it's launching the app, but it hangs and times out.
If I had to guess -- and this is a guess because I'm very new to Android development -- there is some issue with grabbing the this
instance and then using it in the OnClickListener
. I'm not certain what the issue is, but it's the only thing I see here that looks fishy. Also, I'm not sure how else one is supposed to add objects to the current activity from inside of the anonymous class passed into the OnClickListener
since, there, a reference to this
then refers to the anonymous inner class.
I know that it is possible to use a lambda instead, and that probably resolves the issue, but I want to really understand what's going on here, since it seems like it might be conceptually important for later development.
My question: If I have correctly understood this much, then how does a lambda get around this issue? If I've not correctly understood then I'd appreciate any insight, thanks!
CodePudding user response:
There are many questions in one question. First, let me try to answer your title question: "How to get context inside a mouse click listener":
There are many ways, but you can consider this one (your click lisener's onClick has the signature void onClick(View view)
, hence you have access to view.
view.getContext()
Next, nothing wrong with these though you better migrate to view binding https://developer.android.com/topic/libraries/view-binding as butterknife is deprecated officially
Button generate = findViewById(R.id.generate);
TextView questionText = findViewById(R.id.question_text);
Next, you don't really need this trick in order to get activity in your lambda:
MainActivity ma_inst = this;
Instead and if really needed, you can always do Context context = MainActivity.this;
Lastly, I think the issue the app never launches
roots into something else not related with title question you posted, unfortunately.