问题
First of all sorry if this post may seem a duplicate but I am very new to Android programming and posting this question only when I am still not able to get a satisfactory answer for use of getActivity.
Theoretically I understand the use of getActivity() from the several posts here but I am confused how it is working in my code.
I have a class MainActivity from which I am creating a dialog onclick of a checkbox. I have another class TaxDialog where the dialog is implemented. On click of Yes/No buttons I am calling methods define in MainActivity class. Below are the codes:
MainActivty
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements View.OnClickListener, View.OnFocusChangeListener {
// onCheck of checkbox showNoticeDialog is called
public void showNoticeDialog() {
// Create an instance of the dialog fragment and show it
Log.i("MyActivity", "Inside showNoticeDialog");
DialogFragment dialog = new TaxDialog();
Bundle args = new Bundle();
args.putString("title", "Test");
args.putString("message", "Test Message");
dialog.setArguments(args);
dialog.show(getSupportFragmentManager(), "dialog");
}
public void doPositiveClick(){
Log.i("MyActivity", "Inside +ve");
}
public void doNegativeClick(){
Log.i("MyActivity", "Inside -ve");
}
}
TaxDialog
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
public class TaxDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle args = getArguments();
String title = args.getString("title");
String message = args.getString("message");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
Log.i("MyActivity", "Expected fault area.");
((MainActivity) getActivity()).doPositiveClick();
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
((MainActivity) getActivity()).doNegativeClick();
}
});
builder.create();
return builder.create();
}
}
Here I want to understand how below line works
((MainActivity) getActivity()).doPositiveClick();
and also please make me aware of other ways of doing the same thing (something like MainActivity.this.getActivity() or something else).
Thanks a lot.
EDIT
Thanks everyone. Probably I framed the question incorrectly. My only doubt was how getActivity() returns the Activity reference. Now I understand.
回答1:
Lets split it up:
getActivity()
can be used in a Fragment for getting the parentActivity
of theFragment
(basically the Activity that displayed the Fragment).((MainActivity) getActivity())
additionally casts the result ofgetActivity()
to MainActivity. Usually, you just know thatgetActivity()
returns an object of typeActivity
, but using this cast, you tell the compiler that you are sure the object is a specific subclass ofActivity
, namelyMainActivity
. You need to do that in your case, becausedoPositiveClick()
is only implemented inMainActivity
, and not inActivity
, so you have to assure the compiler the object is aMainActivity
, and it will respond to the methoddoPositiveClick()
.doPositiveClick()
simply calls that method on theMainActivity
object that is returned bygetActivity()
.
回答2:
The approach you are using is not the best way to accomplish what you want to do. Android have a good support for listeners, and for communicating with fragments. So, lets see how to communicate fragment->activity direction.
First, you need to make your MainActivity a listener from what happens on a dialog, so the best way to do this is implementing DialogInterface.OnClickListener on your MainActivity and override the onClick(DialogInterface dialog, int which) method, this method will be called from your fragmen. So until now everything is done in your MainActivity.
Now, in your fragment, you have to override the onAttach(Activity activity) method, this is the first method called when the fragment is built and this method comes with our parent Activity, inside this method initialize the listener of your fragment (your MainActivity).
Your fragment should look like this:
private DialogInterface.OnClickListener listener;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle args = getArguments();
String title = args.getString("title");
String message = args.getString("message");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Calling our MainActivity Listener with a positive answer
listener.onClick(getDialog(), 1);
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Calling our MainActivity Listener with a negative answer
listener.onClick(getDialog(), 0);
}
});
builder.create();
return builder.create();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof DialogInterface.OnClickListener) {
listener = (DialogInterface.OnClickListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet DialogInterface.OnClickListener");
}
}
And your main activity onClick() method should look like this:
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
//Do your negative thing
break;
case 1:
//Do your positive thing
break;
}
Toast.makeText(this, "You clicked "+ which, Toast.LENGTH_SHORT).show();
}
This is the best approach to do what you want to do, forget about "hard" cast your MainActivity class. Hope it helps you!
回答3:
I believe you can jsut do
this.doPsitiveClick();
((MainActivity)getActivity()) is just getting the current active activity and casting that to be MainActivity..
回答4:
When you use fragments
it is only way to get context. As above, you are using DialogFragment
and in OnClickListener
there is need of context.
- getActivity() is user-defined.
public final Activity getActivity()
- Return the Activity this fragment is currently associated with.
For your code, in TaxDialog
which is extending DialogFragment
need a context to create AlertDialog
with AlertDialog.Builder
. So here, getActivity()
as a parameter in AlertDialog.Builder
is passing as context
which tells to AlertDialog
Fragment that by which activity it is attached to.
来源:https://stackoverflow.com/questions/21712234/use-of-getactivity