use*_*886 66 android android-fragments android-support-library android-support-design
如何使用Android支持设计库(v23.2.1)将片段的状态设置为扩展BottomSheetDialogFragment为扩展BottomSheetBehavior#setState(STATE_EXPANDED)?
https://code.google.com/p/android/issues/detail?id=202396说:
底部工作表首先设置为STATE_COLLAPSED.如果要展开它,请调用BottomSheetBehavior#setState(STATE_EXPANDED).请注意,您无法在视图布局之前调用该方法.
该建议的做法需要将第一膨胀的观点,但我不知道我怎么会设置BottomSheetBehaviour到片段(BottomSheetDialogFragment).
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
Run Code Online (Sandbox Code Playgroud)
efe*_*ney 166
"请注意,您无法在视图布局之前调用该方法."
以上文字是线索.
对话框曾经是对话框被开了听众所示.如果没有布局,则无法显示该对话框.
因此,在onCreateDialog()模态底部工作表(BottomSheetFragment)中,在返回对话框之前(或者在任何地方,只要您对对话框有引用),请调用:
// This listener's onShow is fired when the dialog is shown
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
// In a previous life I used this method to get handles to the positive and negative buttons
// of a dialog in order to change their Typeface. Good ol' days.
BottomSheetDialog d = (BottomSheetDialog) dialog;
// This is gotten directly from the source of BottomSheetDialog
// in the wrapInBottomSheet() method
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
// Right here!
BottomSheetBehavior.from(bottomSheet)
.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我的习惯BottomSheet结果是:
@SuppressWarnings("ConstantConditions")
public class ShareBottomSheetFragment extends AppCompatDialogFragment {
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog dialog =
new BottomSheetDialog(getActivity(), R.style.Haute_Dialog_ShareImage);
dialog.setContentView(R.layout.dialog_share_image);
dialog.findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
SwitchCompat switchview = (SwitchCompat) dialog.findViewById(R.id.switchview);
switchview.setTypeface(FontCache.get(dialog.getContext(), lookup(muli, NORMAL)));
return dialog;
}
}
Run Code Online (Sandbox Code Playgroud)
如果这有帮助,请告诉我.
UPDATE
请注意,您还可以覆盖BottomSheetDialogFragment为:
public class SimpleInitiallyExpandedBottomSheetFragment extends BottomSheetDialogFragment {
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
// Do something with your dialog like setContentView() or whatever
return dialog;
}
}
Run Code Online (Sandbox Code Playgroud)
但我真的不明白为什么有人会这样做,因为基地BottomSheetFragment除了返回之外什么都不做BottomSheetDialog.
更新ANDROIDX
使用AndroidX时,android.support.design.R.id.design_bottom_sheet现在可以在以下位置找到以前找到的资源com.google.android.material.R.id.design_bottom_sheet.
goo*_*ode 32
efeturi的答案很棒,但是,如果你想使用onCreateView()创建BottomSheet,而不是使用onCreateDialog(),那么你需要在onCreateView()方法下添加代码:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
View bottomSheetInternal = d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
return inflater.inflate(R.layout.your_bottomsheet_content_layout, container, false);
}
Run Code Online (Sandbox Code Playgroud)
Yel*_*sov 32
一条线解决方案:
(dialog as? BottomSheetDialog)?.behavior?.state = BottomSheetBehavior.STATE_EXPANDED
Run Code Online (Sandbox Code Playgroud)
BottomSheetDialogFragment:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(dialog as? BottomSheetDialog)?.behavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
Run Code Online (Sandbox Code Playgroud)
或准备好展示时:
private fun onContentLoaded(items: List<Any>) {
adapter.submitList(items)
(dialog as? BottomSheetDialog)?.behavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
Run Code Online (Sandbox Code Playgroud)
Aja*_*rya 12
在 Kotlin 中,将以下行添加到onStart()您的BottomSheetDialogFragment
(dialog as BottomSheetDialog).behavior.state = BottomSheetBehavior.STATE_EXPANDED
Run Code Online (Sandbox Code Playgroud)
DYS*_*DYS 10
一个简单而优雅的解决方案:
BottomSheetDialogFragment 可以子类化以解决此问题:
class NonCollapsableBottomSheetDialogFragment extends BottomSheetDialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
bottomSheetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
FrameLayout bottomSheet = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setSkipCollapsed(true);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
return bottomSheetDialog;
}
Run Code Online (Sandbox Code Playgroud)
}
因此,扩展此类而不是BottomSheetDialogFragment创建自己的底页。
注意
更改com.google.android.material.R.id.design_bottom_sheet为android.support.design.R.id.design_bottom_sheet项目是否使用旧的Android支持库。
我觉得上面的比较好。可悲的是,我在解决之前没有找到这些解决方案。但是写我的解决方案。非常相似。
================================================== ================================
我面临同样的问题。这就是我解决的。Behavior 隐藏在BottomSheetDialog 中,可以通过它获取行为如果你不想把你的父布局改成CooridateLayout,你可以试试这个。
STEP 1:自定义BottomSheetDialogFragment
open class CBottomSheetDialogFragment : BottomSheetDialogFragment() {
//wanna get the bottomSheetDialog
protected lateinit var dialog : BottomSheetDialog
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
return dialog
}
//set the behavior here
fun setFullScreen(){
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
Run Code Online (Sandbox Code Playgroud)
STEP 2:让你的片段扩展这个自定义片段
class YourBottomSheetFragment : CBottomSheetDialogFragment(){
//make sure invoke this method after view is built
//such as after OnActivityCreated(savedInstanceState: Bundle?)
override fun onStart() {
super.onStart()
setFullScreen()//initiated at onActivityCreated(), onStart()
}
}
Run Code Online (Sandbox Code Playgroud)
当显示软键盘时,使用 onShow() 的所有结果都会导致随机渲染错误。请参见下面的屏幕截图 - BottomSheet 对话框不在屏幕底部,而是像显示键盘一样放置。这个问题并不总是发生,但经常发生。
更新
我的解决方案与私人成员的反映是不必要的。使用 postDelayed(大约 100 毫秒)在隐藏软键盘后创建和显示对话框是一个更好的解决方案。那么上面用onShow()的解决方案就可以了。
Utils.hideSoftKeyboard(this);
mView.postDelayed(new Runnable() {
@Override
public void run() {
MyBottomSheetDialog dialog = new MyBottomSheetDialog();
dialog.setListener(MyActivity.this);
dialog.show(getSupportFragmentManager(), TAG_BOTTOM_SHEET_DLG);
}
}, 100);
Run Code Online (Sandbox Code Playgroud)
因此,我实现了另一个解决方案,但它需要使用反射,因为 BottomSheetDialog 将所有成员设为私有。但它解决了渲染错误。BottomSheetDialogFragment 类只是带有 onCreateDialog 方法的 AppCompatDialogFragment,它创建 BottomSheetDialog。我创建了自己的 AppCompatDialogFragment 子级,它创建了我的类扩展 BottomSheetDialog 并解决了对私有行为成员的访问问题,并在 onStart 方法中将其设置为 STATE_EXPANDED 状态。
public class ExpandedBottomSheetDialog extends BottomSheetDialog {
protected BottomSheetBehavior<FrameLayout> mBehavior;
public ExpandedBottomSheetDialog(@NonNull Context context, @StyleRes int theme) {
super(context, theme);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
Field privateField = BottomSheetDialog.class.getDeclaredField("mBehavior");
privateField.setAccessible(true);
mBehavior = (BottomSheetBehavior<FrameLayout>) privateField.get(this);
} catch (NoSuchFieldException e) {
// do nothing
} catch (IllegalAccessException e) {
// do nothing
}
}
@Override
protected void onStart() {
super.onStart();
if (mBehavior != null) {
mBehavior.setSkipCollapsed(true);
mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
}
public class AddAttachmentBottomSheetDialog extends AppCompatDialogFragment {
....
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new ExpandedBottomSheetDialog(getContext(), getTheme());
}
....
}
Run Code Online (Sandbox Code Playgroud)
我的答案与上述大多数答案或多或少相同,但稍作修改。与其使用 findViewById 来首先查找底部工作表视图,我宁愿不硬编码任何框架视图资源 ID,因为它们将来可能会发生变化。
setOnShowListener(dialog -> {
BottomSheetBehavior bottomSheetBehavior = ((BottomSheetDialog)dialog).getBehavior();
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
});
Run Code Online (Sandbox Code Playgroud)
小智 5
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
setOnShowListener {
(this@TipsBottomDialogFragment.dialog as BottomSheetDialog).behavior.setState(
BottomSheetBehavior.STATE_EXPANDED
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
将其发布给未来的读者,因为我认为现在我们可以使用另一种解决方案。
我试图解决与您描述的相同的问题BottomSheetDialog。
我不喜欢使用内部 Android id,我刚刚发现里面有一个方法BottomSheetDialog getBehavior可以使用:
您可以在您的BottomSheetDialog:
behavior.state = BottomSheetBehavior.STATE_EXPANDED
使用BottomSheetDialogFragment您可以执行相同的操作,将对话框从 DialogFragment 转换为BottomSheetDialog.
小智 5
您可以执行以下操作(Kotlin 版本):
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.let {
val sheet = it as BottomSheetDialog
sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
// rest of your stuff
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这是一个非常简洁的 Kotlin 解决方案,效果很好。
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return (super.onCreateDialog(savedInstanceState) as BottomSheetDialog).apply {
setOnShowListener {
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
52846 次 |
| 最近记录: |