为什么我的 DialogFragment 样式在我从不同 Activity 显示时是错误的?

Why my DialogFragment style is wrong when I show it from different Activity?

我在使用带有自定义视图的 DialogFragment 时遇到了一个奇怪的行为。

当我从 activity 的另一个对话框显示对话框时,一切都很好,但是当我从另一个片段(和不同的 activity)显示它时,样式就乱七八糟了,我不能查看 SearchView、RecyclerView 项装饰器和其中的 TextView 文本。

对话框代码:

public class MyDialogFragment extends DialogFragment 
{
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.My_Dialog);

        LayoutInflater inflater = LayoutInflater.from(getContext());
        View view = inflater.inflate(R.layout.fragment_my, (ViewGroup) getActivity().findViewById(android.R.id.content), false);
        builder.setView(view);

        final SearchView searchView = (SearchView) view.findViewById(R.id.searchView);
        final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(adapter);
        HorizontalDividerDecoration.Builder dividerBuilder = new HorizontalDividerDecoration.Builder(getContext());
        recyclerView.addItemDecoration(dividerBuilder.build());

        // ...

        builder.setNegativeButton(android.R.string.cancel, null);
        final AlertDialog dialog = builder.create();

        return dialog;
    }
}

fragment_my.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </android.support.v7.widget.SearchView>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/searchView"
        android:scrollbarStyle="insideOverlay"
        app:layoutManager="LinearLayoutManager"
        tools:listitem="@layout/my_item"/>

</RelativeLayout>

使用的样式:

<style name="My.Dialog" parent="Theme.AppCompat.Light.Dialog.Alert">

</style>

my_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="android.view.View"/>

        <variable
            name="bindObject"
            type="com.spiral_root.app.pecunia.adapter.MyBind"/>
    </data>

    <RelativeLayout
        android:id="@+id/containerLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@{bindObject.selected ? @color/lightGrey : @color/transparent}"
        android:clickable="true"
        android:foreground="?android:selectableItemBackground"
        android:padding="@dimen/dimen_5dp">

        <FrameLayout
            android:id="@+id/selectedContainer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true">

            <ImageView
                android:id="@+id/selectedImageView"
                style="@style/CheckedIcon"
                android:layout_marginEnd="@dimen/dimen_5dp"
                android:tint="@color/source"
                android:visibility="@{bindObject.selected ? View.VISIBLE : View.GONE}"
                app:srcCompat="@drawable/check_circle_white_24dp"/>

        </FrameLayout>

        <ImageView
            android:id="@+id/imageView"
            style="@style/CurrencyFlag"
            android:layout_marginStart="@dimen/dimen_5dp"
            android:src="@{bindObject.flagResourceId}"
            tools:src="@drawable/flag_eur"/>

        <TextView
            android:id="@+id/nameTextView"
            style="@style/WrappedText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/dimen_5dp"
            android:layout_marginStart="@dimen/dimen_10dp"
            android:layout_toEndOf="@id/imageView"
            android:layout_toStartOf="@id/selectedContainer"
            android:text="@{bindObject.name}"
            android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
            tools:text="Name"/>

        <TextView
            android:id="@+id/symbolTextView"
            style="@style/WrappedText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignStart="@id/nameTextView"
            android:layout_below="@id/nameTextView"
            android:layout_marginTop="@dimen/dimen_7dp"
            android:layout_toEndOf="@id/imageView"
            android:text="@{bindObject.symbol}"
            android:textAppearance="@style/TextAppearance.AppCompat.Caption"
            android:textSize="14sp"
            tools:text="$"/>

        <TextView
            android:id="@+id/codeTextView"
            style="@style/WrappedText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@id/symbolTextView"
            android:layout_below="@id/nameTextView"
            android:layout_marginStart="@dimen/dimen_5dp"
            android:layout_toEndOf="@id/symbolTextView"
            android:text="@{@string/parenthesis(bindObject.code)}"
            android:textAppearance="@style/Currency.Dialog.Caption"
            android:textSize="14sp"
            tools:text="USD"/>

    </RelativeLayout>

</layout>

工作代码(来自另一个对话框):

public class ParentDialogFragment extends DialogFragment
{
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.fragment_parent, (ViewGroup) getActivity().findViewById(android.R.id.content), false);
        builder.setView(view);

        final Button button = (Button) view.findViewById(R.id.currencyButton);
        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                MyDialogFragment dialog = MyDialogFragment.newInstance(selectedCode, new MyDialogFragment.Listener()
                {
                    @Override
                    public void select(CurrencyBind item)
                    {
                        // ...
                    }
                });
                dialog.show(getFragmentManager(), "my_dialog");
            }
        });
    }
}

ParentDialogFragment 显示自 ParentListFragment

public class ParentListFragment extends Fragment
{
    // ...

    private void showSourceDialog(SourceEntity entity)
    {
        ParentDialogFragment dialog = ParentDialogFragment.newInstance(entity, new ParentDialogFragment.Callback()
        {
            // ...
        });
        dialog.show(getFragmentManager(), "parent_dialog");
    }
}

ParentListFragment 是 ParentListWizardActivity 的内容,它只是加载片段并具有以下样式:

<!-- AndroidManifest.xml -->
<activity android:name=".activity.ParentListWizardActivity"
    android:label="@string/title_activity_parent_list_wizard"
    android:theme="@style/AppTheme.NoActionBar">
</activity>


<!-- styles.xml -->
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primaryDark</item>
    <item name="colorAccent">@color/secondary</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

结果是这样的:

当它不起作用时,我遇到这种情况:

public class MyWizardFragment extends ParallaxSlideFragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_my_wizard, container, false);

        actionButton = (Button) rootView.findViewById(R.id.actionButton);
        actionButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                MyDialogFragment dialog = MyDialogFragment.newInstance(preferenceManager.getDefaultCode(), new MyDialogFragment.Listener()
                {
                    @Override
                    public void select(MyBind item)
                    {
                        // ...
                    }
                });
                dialog.show(getFragmentManager(), "my_dialog");
            }
        });

        return rootView;
    }
}

MyWizardFragment 由具有以下样式的 activity WizardActivity 注入:

<activity
    android:name=".activity.WizardActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.Intro">
</activity>

<style name="Theme.Intro" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
</style>

结果是这样的:

我不明白这是关于样式还是片段管理器或任何其他东西。

谢谢

我终于解决了我的问题。

问题不在于 AlertDialog,而是自定义视图的样式,这显然不是从对话框继承的,而是您指定的。

我替换了:

LayoutInflater inflater = LayoutInflater.from(getContext());

与:

LayoutInflater inflater = LayoutInflater.from(new ContextThemeWrapper(getContext(), R.style.My_Dialog));

赞这个回答:

现在一切都很好