Android developer, Just some random facts

It's time throw some light to some of Android common usage classes, under the hood have you wondered, why does fragment have a getLayoutInflater method?, Well it turns out that is actually not very interesting to see the usage in the Fragment class more that it is in the DialogFragment.

Did you know that……?

Fragments have a method getLayoutInflater(Bundle savedInstanceState), this is a regular public method but the savedInstanceState is never use in the fragment class, in fact what this only does retrieve the layout inflater from the activity associated. So why is it there? Well is actually public in the documentation since it's a hack use by the DialogFragment before creating it's view. 

/*** @hide Hack so that DialogFragment can make its Dialog before creating
* its views, and the view construction can use the dialog's context for
* inflation.  Maybe this should become a public API. Note sure.
*/

public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {

    return mActivity.getLayoutInflater();

}

Now we see that there is nothing interesting in the method above except the comment pointing that the real deal is in DialogFragment class:



 /** @hide */
    @Override
    public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
        if (!mShowsDialog) {
            return super.getLayoutInflater(savedInstanceState);
        }

        mDialog = onCreateDialog(savedInstanceState);
        switch (mStyle) {
            case STYLE_NO_INPUT:
                mDialog.getWindow().addFlags(
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                // fall through...
            case STYLE_NO_FRAME:
            case STYLE_NO_TITLE:
                mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        }
        if (mDialog != null) {
            return (LayoutInflater)mDialog.getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
        }
        return (LayoutInflater)mActivity.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
    }

See how the context for the layout inflater get into action to play an important role for calling the infate system service.

Real scenario problem?

Well no too long ago we release the 0.6 version of Pozool but before ready we dicover a small bug when trying to dismiss a DialogFragment. Like this:

case R.id.button_cancel:
			intent = new Intent(B.action.cancel_pay);
			if (getActivity() != null)
				getActivity().sendBroadcast(intent);
			
			if (getDialog() != null) {
				dismiss();
			}
			
			break;

The problem was not the fact of dismissing, instead it only ocurre when a particular action was invoked. This action added view to display details like this:


LinearLayout detailTotalView = createDetailView(getString(R.string.total), textTotal.getText().toString(), totalDetailView);
totalDetailView.addView(detailSubtotalView);

And the createDetailView it was something like this



private LinearLayout createDetailView(String textName, String detail, ViewGroup root) {
		LinearLayout detailView = (LinearLayout) getLayoutInflater(null).inflate(R.layout.detail_total, root, false);
		((TextView) detailView.findViewById(R.id.textName)).setText(textName);
		((TextView) detailView.findViewById(R.id.textPrice)).setText(detail);

		return detailView;
	}

The problem has it's root in the fact that when the getLayoutInflater is called, the onCreateDialog method is called, returning another instance of mDialog. This was not good news for us it meant that the dialog was never going to be dismiss because the reference has changed. The solution is to use instead of getLayoutInflater(), call the activity and use


private LinearLayout createDetailView(String textName, String detail, ViewGroup root) {
		LinearLayout detailView = (LinearLayout) getActivity().getLayoutInflater().inflate(R.layout.detail_total, root, false);
		((TextView) detailView.findViewById(R.id.textName)).setText(textName);
		((TextView) detailView.findViewById(R.id.textPrice)).setText(detail);

		return detailView;
	}

See piece of cake, we can now release!.

Facebook icon Twitter icon LinkedIn icon e-mail icon