質問

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.

役に立ちましたか?

解決

Lets split it up:

  • getActivity() can be used in a Fragment for getting the parent Activity of the Fragment (basically the Activity that displayed the Fragment).

  • ((MainActivity) getActivity()) additionally casts the result of getActivity() to MainActivity. Usually, you just know that getActivity() returns an object of type Activity, but using this cast, you tell the compiler that you are sure the object is a specific subclass of Activity, namely MainActivity. You need to do that in your case, because doPositiveClick() is only implemented in MainActivity, and not in Activity, so you have to assure the compiler the object is a MainActivity, and it will respond to the method doPositiveClick().

  • doPositiveClick() simply calls that method on the MainActivity object that is returned by getActivity().

他のヒント

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!

I believe you can jsut do

  this.doPsitiveClick();

((MainActivity)getActivity()) is just getting the current active activity and casting that to be MainActivity..

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top