Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package androidx.fragment.app;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentSender;
     23 import android.os.Bundle;
     24 import android.os.Handler;
     25 import android.view.LayoutInflater;
     26 import android.view.View;
     27 
     28 import androidx.annotation.NonNull;
     29 import androidx.annotation.Nullable;
     30 import androidx.core.app.ActivityCompat;
     31 import androidx.core.util.Preconditions;
     32 
     33 import java.io.FileDescriptor;
     34 import java.io.PrintWriter;
     35 
     36 /**
     37  * Integration points with the Fragment host.
     38  * <p>
     39  * Fragments may be hosted by any object; such as an {@link Activity}. In order to
     40  * host fragments, implement {@link FragmentHostCallback}, overriding the methods
     41  * applicable to the host.
     42  */
     43 public abstract class FragmentHostCallback<E> extends FragmentContainer {
     44     @Nullable private final Activity mActivity;
     45     @NonNull private final Context mContext;
     46     @NonNull private final Handler mHandler;
     47     private final int mWindowAnimations;
     48     final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
     49 
     50     public FragmentHostCallback(@NonNull Context context, @NonNull Handler handler,
     51             int windowAnimations) {
     52         this(context instanceof Activity ? (Activity) context : null, context, handler,
     53                 windowAnimations);
     54     }
     55 
     56     FragmentHostCallback(@NonNull FragmentActivity activity) {
     57         this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
     58     }
     59 
     60     FragmentHostCallback(@Nullable Activity activity, @NonNull Context context,
     61             @NonNull Handler handler, int windowAnimations) {
     62         mActivity = activity;
     63         mContext = Preconditions.checkNotNull(context, "context == null");
     64         mHandler = Preconditions.checkNotNull(handler, "handler == null");
     65         mWindowAnimations = windowAnimations;
     66     }
     67 
     68     /**
     69      * Print internal state into the given stream.
     70      *
     71      * @param prefix Desired prefix to prepend at each line of output.
     72      * @param fd The raw file descriptor that the dump is being sent to.
     73      * @param writer The PrintWriter to which you should dump your state. This will be closed
     74      *                  for you after you return.
     75      * @param args additional arguments to the dump request.
     76      */
     77     public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
     78     }
     79 
     80     /**
     81      * Return {@code true} if the fragment's state needs to be saved.
     82      */
     83     public boolean onShouldSaveFragmentState(Fragment fragment) {
     84         return true;
     85     }
     86 
     87     /**
     88      * Return a {@link LayoutInflater}.
     89      * See {@link Activity#getLayoutInflater()}.
     90      */
     91     @NonNull
     92     public LayoutInflater onGetLayoutInflater() {
     93         return LayoutInflater.from(mContext);
     94     }
     95 
     96     /**
     97      * Return the object that's currently hosting the fragment. If a {@link Fragment}
     98      * is hosted by a {@link FragmentActivity}, the object returned here should be
     99      * the same object returned from {@link Fragment#getActivity()}.
    100      */
    101     @Nullable
    102     public abstract E onGetHost();
    103 
    104     /**
    105      * Invalidates the activity's options menu.
    106      * See {@link FragmentActivity#supportInvalidateOptionsMenu()}
    107      */
    108     public void onSupportInvalidateOptionsMenu() {
    109     }
    110 
    111     /**
    112      * Starts a new {@link Activity} from the given fragment.
    113      * See {@link FragmentActivity#startActivityForResult(Intent, int)}.
    114      */
    115     public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
    116         onStartActivityFromFragment(fragment, intent, requestCode, null);
    117     }
    118 
    119     /**
    120      * Starts a new {@link Activity} from the given fragment.
    121      * See {@link FragmentActivity#startActivityForResult(Intent, int, Bundle)}.
    122      */
    123     public void onStartActivityFromFragment(
    124             Fragment fragment, Intent intent, int requestCode, @Nullable Bundle options) {
    125         if (requestCode != -1) {
    126             throw new IllegalStateException(
    127                     "Starting activity with a requestCode requires a FragmentActivity host");
    128         }
    129         mContext.startActivity(intent);
    130     }
    131 
    132     /**
    133      * Starts a new {@link IntentSender} from the given fragment.
    134      * See {@link Activity#startIntentSender(IntentSender, Intent, int, int, int, Bundle)}.
    135      */
    136     public void onStartIntentSenderFromFragment(Fragment fragment, IntentSender intent,
    137             int requestCode, @Nullable Intent fillInIntent, int flagsMask, int flagsValues,
    138             int extraFlags, Bundle options) throws IntentSender.SendIntentException {
    139         if (requestCode != -1) {
    140             throw new IllegalStateException(
    141                     "Starting intent sender with a requestCode requires a FragmentActivity host");
    142         }
    143         ActivityCompat.startIntentSenderForResult(mActivity, intent, requestCode, fillInIntent,
    144                 flagsMask, flagsValues, extraFlags, options);
    145     }
    146 
    147     /**
    148      * Requests permissions from the given fragment.
    149      * See {@link FragmentActivity#requestPermissions(String[], int)}
    150      */
    151     public void onRequestPermissionsFromFragment(@NonNull Fragment fragment,
    152             @NonNull String[] permissions, int requestCode) {
    153     }
    154 
    155     /**
    156      * Checks whether to show permission rationale UI from a fragment.
    157      * See {@link FragmentActivity#shouldShowRequestPermissionRationale(String)}
    158      */
    159     public boolean onShouldShowRequestPermissionRationale(@NonNull String permission) {
    160         return false;
    161     }
    162 
    163     /**
    164      * Return {@code true} if there are window animations.
    165      */
    166     public boolean onHasWindowAnimations() {
    167         return true;
    168     }
    169 
    170     /**
    171      * Return the window animations.
    172      */
    173     public int onGetWindowAnimations() {
    174         return mWindowAnimations;
    175     }
    176 
    177     @Nullable
    178     @Override
    179     public View onFindViewById(int id) {
    180         return null;
    181     }
    182 
    183     @Override
    184     public boolean onHasView() {
    185         return true;
    186     }
    187 
    188     @Nullable
    189     Activity getActivity() {
    190         return mActivity;
    191     }
    192 
    193     @NonNull
    194     Context getContext() {
    195         return mContext;
    196     }
    197 
    198     @NonNull
    199     Handler getHandler() {
    200         return mHandler;
    201     }
    202 
    203     FragmentManagerImpl getFragmentManagerImpl() {
    204         return mFragmentManager;
    205     }
    206 
    207     void onAttachFragment(Fragment fragment) {
    208     }
    209 }
    210