Inside OnClickListener I cannot access a lot of things - how to approach?

JavaAndroid

Java Problem Overview


Inside an OnClickListener I cannot access most variables "outside" of the scope, like this:

findViewById(R.id.Button01).setOnClickListener(new OnClickListener()
        {
        	@Override
			public void onClick(View v)
			{
        		Intent mainApps = new Intent(Intent.ACTION_MAIN);
        		mainApps.addCategory(Intent.CATEGORY_LAUNCHER);
        		List<ActivityInfo> activities = this.getPackageManager().queryIntentActivities(mainApps, 0);
        		/*
        		Intent intent = new Intent("com.sygic.drive/com.sygic/drive/.SygicDriveActivity");
            	startActivity(intent);*/
			}
        	
        });

in this example I need to get the PacketManager, and I cannot get it since I do not have the Context available inside the OnClickListener.

I could make a static reference outside, and use it inside, but is that correct? Seems odd to have to do that all the time?

Java Solutions


Solution 1 - Java

Replace this in your code with MyActivity.this where MyActivity is the class name of your Activity subclass.

Explanation: You are creating an anonymous inner class when you use this part of your code:
new OnClickListener() {
Anonymous inner classes have a reference to the instance of the class they are created in. It looks like you are creating it inside an Activity subclass because findViewById is an Activity method. Activity's are a Context, so all you need to do is use the reference to it that you have automatically.

Solution 2 - Java

You could also implement the OnClickListener interface in your class and avoid the need for an anonymous inner class. Then you would set the on click listener like this:

findViewById(R.id.Button01).setOnClickListener(this);

If you have multiple buttons using one listener, you can use a switch statement with view.getId() (which corresponds to the view's id in R.id) to distinguish between them.

Solution 3 - Java

There are a few things you can do, you can create an inner class that implements the onClickListener and pass the necessary arguments into the constructor of the class. I still don't find that the cleanest approach. I usually just create another method to perform my action. So in the onClick(View v) I would do something like this.

onClick(View v){doMyAction(myParams)}

private void doMyAction(Object params){//do stuff}

And just pass the needed params from the listener method to the method outside the listener.

Solution 4 - Java

Change the Intent constructor in use to Intent(context, classname) and use getApplicationContext() in your innerclass. Solved my problem anyway.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTedView Question on Stackoverflow
Solution 1 - JavaLance NanekView Answer on Stackoverflow
Solution 2 - JavaAl.View Answer on Stackoverflow
Solution 3 - JavabroschbView Answer on Stackoverflow
Solution 4 - JavaWayneSplatterView Answer on Stackoverflow