-
Notifications
You must be signed in to change notification settings - Fork 594
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a BottomSheetFragment to bottomsheet-commons that works like a …
…DialogFragment.
- Loading branch information
Showing
10 changed files
with
375 additions
and
0 deletions.
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
bottomsheet-commons/src/main/java/android/support/v4/app/AccessFragmentInternals.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package android.support.v4.app; | ||
|
||
public class AccessFragmentInternals { | ||
private AccessFragmentInternals() { | ||
} | ||
|
||
public static int getContainerId(Fragment fragment) { | ||
return fragment.mContainerId; | ||
} | ||
} |
257 changes: 257 additions & 0 deletions
257
bottomsheet-commons/src/main/java/com/flipboard/bottomsheet/commons/BottomSheetFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,257 @@ | ||
package com.flipboard.bottomsheet.commons; | ||
|
||
import android.app.Activity; | ||
import android.content.Context; | ||
import android.os.Bundle; | ||
import android.support.annotation.CallSuper; | ||
import android.support.annotation.IdRes; | ||
import android.support.annotation.Nullable; | ||
import android.support.v4.app.AccessFragmentInternals; | ||
import android.support.v4.app.Fragment; | ||
import android.support.v4.app.FragmentManager; | ||
import android.support.v4.app.FragmentTransaction; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
|
||
import com.flipboard.bottomsheet.BottomSheetLayout; | ||
import com.flipboard.bottomsheet.OnSheetDismissedListener; | ||
import com.flipboard.bottomsheet.ViewTransformer; | ||
|
||
/** | ||
* A fragment that shows itself in a {@link BottomSheetLayout}. Like a {@link | ||
* android.support.v4.app.DialogFragment}, you can show this either in a bottom sheet by using | ||
* {@link #show(FragmentManager, int)} or attach it to a view with the normal fragment transaction | ||
* methods. | ||
*/ | ||
public class BottomSheetFragment extends Fragment implements OnSheetDismissedListener, BottomSheetLayout.OnSheetStateChangeListener { | ||
|
||
private static final String SAVED_SHOWS_BOTTOM_SHEET = "bottomsheet:savedBottomSheet"; | ||
private static final String SAVED_BACK_STACK_ID = "bottomsheet:backStackId"; | ||
private static final String SAVED_BOTTOM_SHEET_LAYOUT_ID = "bottomsheet:bottomSheetLayoutId"; | ||
|
||
@IdRes | ||
private int bottomSheetLayoutId = View.NO_ID; | ||
private BottomSheetLayout bottomSheetLayout; | ||
private boolean dismissed; | ||
private boolean shownByMe; | ||
private boolean viewDestroyed; | ||
private boolean showsBottomSheet = true; | ||
private int backStackId = -1; | ||
|
||
public BottomSheetFragment() { | ||
|
||
} | ||
|
||
/** | ||
* Display the bottom sheet, adding the fragment to the given FragmentManager. This does | ||
* <em>not</em> add the transaction to the back stack. When teh fragment is dismissed, a new | ||
* transaction will be executed to remove it from the activity. | ||
* | ||
* @param manager The FragmentManager this fragment will be added to. | ||
* @param bottomSheetLayoutId The bottom sheet layoutId in the parent view to attach the | ||
* fragment to. | ||
*/ | ||
public void show(FragmentManager manager, @IdRes int bottomSheetLayoutId) { | ||
dismissed = false; | ||
shownByMe = true; | ||
this.bottomSheetLayoutId = bottomSheetLayoutId; | ||
manager.beginTransaction() | ||
.add(this, String.valueOf(bottomSheetLayoutId)) | ||
.commit(); | ||
} | ||
|
||
/** | ||
* Display the bottom sheet, adding the fragment using an excising transaction and then | ||
* committing the transaction. | ||
* | ||
* @param transaction An existing transaction in which to add the fragment. | ||
* @param bottomSheetLayoutId The bottom sheet layoutId in the parent view to attach the | ||
* fragment to. | ||
*/ | ||
public int show(FragmentTransaction transaction, @IdRes int bottomSheetLayoutId) { | ||
dismissed = false; | ||
shownByMe = true; | ||
this.bottomSheetLayoutId = bottomSheetLayoutId; | ||
transaction.add(this, String.valueOf(bottomSheetLayoutId)); | ||
viewDestroyed = false; | ||
backStackId = transaction.commit(); | ||
return backStackId; | ||
} | ||
|
||
/** | ||
* Dismiss the fragment and it's bottom sheet. If the fragment was added to the back stack, all | ||
* back stack state up to and including this entry will be popped. Otherwise, a new transaction | ||
* will be committed to remove this fragment. | ||
*/ | ||
public void dismiss() { | ||
dismissInternal(/*allowStateLoss=*/false); | ||
} | ||
|
||
/** | ||
* Version of {@link #dismiss()} that uses {@link FragmentTransaction#commitAllowingStateLoss()}. | ||
* See linked documentation for further details. | ||
*/ | ||
public void dismissAllowingStateLoss() { | ||
dismissInternal(/*allowStateLoss=*/true); | ||
} | ||
|
||
private void dismissInternal(boolean allowStateLoss) { | ||
if (dismissed) { | ||
return; | ||
} | ||
dismissed = true; | ||
shownByMe = false; | ||
if (bottomSheetLayout != null) { | ||
bottomSheetLayout.dismissSheet(); | ||
bottomSheetLayout = null; | ||
} | ||
viewDestroyed = true; | ||
if (backStackId >= 0) { | ||
getFragmentManager().popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE); | ||
backStackId = -1; | ||
} else { | ||
FragmentTransaction ft = getFragmentManager().beginTransaction(); | ||
ft.remove(this); | ||
if (allowStateLoss) { | ||
ft.commitAllowingStateLoss(); | ||
} else { | ||
ft.commit(); | ||
} | ||
} | ||
} | ||
|
||
public BottomSheetLayout getBottomSheetLayout() { | ||
return bottomSheetLayout; | ||
} | ||
|
||
/** | ||
* Override this to proved a custom {@link ViewTransformer}. | ||
*/ | ||
public ViewTransformer getViewTransformer() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void onAttach(Context context) { | ||
super.onAttach(context); | ||
if (!shownByMe) { | ||
dismissed = false; | ||
} | ||
} | ||
|
||
@Override | ||
public void onDetach() { | ||
super.onDetach(); | ||
if (!shownByMe && !dismissed) { | ||
dismissed = true; | ||
} | ||
} | ||
|
||
@Override | ||
public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
showsBottomSheet = AccessFragmentInternals.getContainerId(this) == 0; | ||
|
||
if (savedInstanceState != null) { | ||
showsBottomSheet = savedInstanceState.getBoolean(SAVED_SHOWS_BOTTOM_SHEET, showsBottomSheet); | ||
backStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, -1); | ||
bottomSheetLayoutId = savedInstanceState.getInt(SAVED_BOTTOM_SHEET_LAYOUT_ID, View.NO_ID); | ||
} | ||
} | ||
|
||
@Override | ||
public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { | ||
if (!showsBottomSheet) { | ||
return super.getLayoutInflater(savedInstanceState); | ||
} | ||
bottomSheetLayout = (BottomSheetLayout) findBottomSheetLayout(); | ||
if (bottomSheetLayout != null) { | ||
return LayoutInflater.from(bottomSheetLayout.getContext()); | ||
} | ||
return LayoutInflater.from(getContext()); | ||
} | ||
|
||
@Nullable | ||
private View findBottomSheetLayout() { | ||
Fragment parentFragment = getParentFragment(); | ||
if (parentFragment != null) { | ||
View view = parentFragment.getView(); | ||
if (view != null) { | ||
return view.findViewById(bottomSheetLayoutId); | ||
} else { | ||
return null; | ||
} | ||
} | ||
Activity parentActivity = getActivity(); | ||
if (parentActivity != null) { | ||
return parentActivity.findViewById(bottomSheetLayoutId); | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public void onActivityCreated(@Nullable Bundle savedInstanceState) { | ||
super.onActivityCreated(savedInstanceState); | ||
|
||
if (!showsBottomSheet) { | ||
return; | ||
} | ||
|
||
View view = getView(); | ||
if (view != null) { | ||
if (view.getParent() != null) { | ||
throw new IllegalStateException("BottomSheetFragment can not be attached to a container view"); | ||
} | ||
bottomSheetLayout.setOnSheetStateChangeListener(this); | ||
} | ||
} | ||
|
||
@Override | ||
public void onStart() { | ||
super.onStart(); | ||
if (bottomSheetLayout != null) { | ||
viewDestroyed = false; | ||
bottomSheetLayout.showWithSheetView(getView(), getViewTransformer(), this); | ||
} | ||
} | ||
|
||
@Override | ||
public void onSaveInstanceState(Bundle outState) { | ||
super.onSaveInstanceState(outState); | ||
if (!showsBottomSheet) { | ||
outState.putBoolean(SAVED_SHOWS_BOTTOM_SHEET, false); | ||
} | ||
if (backStackId != -1) { | ||
outState.putInt(SAVED_BACK_STACK_ID, backStackId); | ||
} | ||
if (bottomSheetLayoutId != View.NO_ID) { | ||
outState.putInt(SAVED_BOTTOM_SHEET_LAYOUT_ID, bottomSheetLayoutId); | ||
} | ||
} | ||
|
||
/** | ||
* Remove bottom sheet. | ||
*/ | ||
@Override | ||
public void onDestroyView() { | ||
super.onDestroyView(); | ||
if (bottomSheetLayout != null) { | ||
viewDestroyed = true; | ||
bottomSheetLayout.dismissSheet(); | ||
bottomSheetLayout = null; | ||
} | ||
} | ||
|
||
@Override | ||
@CallSuper | ||
public void onDismissed(BottomSheetLayout bottomSheetLayout) { | ||
if (!viewDestroyed) { | ||
dismissInternal(true); | ||
} | ||
} | ||
|
||
@Override | ||
public void onSheetStateChanged(BottomSheetLayout.State state) { | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...et-sample/src/main/java/com/flipboard/bottomsheet/sample/BottomSheetFragmentActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.flipboard.bottomsheet.sample; | ||
|
||
import android.os.Bundle; | ||
import android.support.v7.app.AppCompatActivity; | ||
import android.view.View; | ||
|
||
import com.flipboard.bottomsheet.BottomSheetLayout; | ||
import com.flipboard.bottomsheet.R; | ||
import com.flipboard.bottomsheet.commons.ImagePickerSheetView; | ||
|
||
/** | ||
* Activity demonstrating the use of {@link ImagePickerSheetView} | ||
*/ | ||
public final class BottomSheetFragmentActivity extends AppCompatActivity { | ||
|
||
protected BottomSheetLayout bottomSheetLayout; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_bottom_sheet_fragment); | ||
bottomSheetLayout = (BottomSheetLayout) findViewById(R.id.bottomsheet); | ||
findViewById(R.id.bottomsheet_fragment_button).setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
new MyFragment().show(getSupportFragmentManager(), R.id.bottomsheet); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
bottomsheet-sample/src/main/java/com/flipboard/bottomsheet/sample/MyFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.flipboard.bottomsheet.sample; | ||
|
||
import android.os.Bundle; | ||
import android.support.annotation.Nullable; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
import com.flipboard.bottomsheet.R; | ||
import com.flipboard.bottomsheet.commons.BottomSheetFragment; | ||
|
||
public class MyFragment extends BottomSheetFragment { | ||
|
||
@Nullable | ||
@Override | ||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||
return inflater.inflate(R.layout.fragment_my, container, false); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
bottomsheet-sample/src/main/res/layout/activity_bottom_sheet_fragment.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<com.flipboard.bottomsheet.BottomSheetLayout | ||
android:id="@+id/bottomsheet" | ||
xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
> | ||
|
||
<RelativeLayout | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:padding="16dp" | ||
> | ||
|
||
<Button | ||
android:id="@+id/bottomsheet_fragment_button" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:layout_gravity="center_horizontal|top" | ||
android:layout_marginBottom="16dp" | ||
android:text="@string/show" | ||
/> | ||
</RelativeLayout> | ||
</com.flipboard.bottomsheet.BottomSheetLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:background="?android:colorBackground" | ||
android:orientation="vertical" | ||
> | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="400dp" | ||
android:padding="16dp" | ||
android:text="Hello, World!" | ||
/> | ||
</LinearLayout> |
Oops, something went wrong.