Android 片段显示为对话框片段或普通片段

2023-11-23

我想要实现的是有一个片段,在平板电脑上显示为DialogFragment,而在智能手机上它将显示为常规片段。我知道已经有一个类似的帖子,但我无法做到这一点 - 将样式应用于片段。

为了自上而下地显示内容,MainActivity.java:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_next) {
            decideToNext();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void decideToNext() {
        String device = getString(R.string.device);
        if ("normal".equalsIgnoreCase(device)) {
            Intent intent = new Intent(this, DetailedActivity.class);
            startActivity(intent);
        } else if ("large".equalsIgnoreCase(device)) {
            Log.d("SOME_TAG", "Yes, I am seeing this line on tablet only");
            DetailedFragment fragment = DetailedFragment.newInstance();
            getSupportFragmentManager().beginTransaction().add(fragment, "MAGIC_TAG").commit();
        }
    }

}

详细的活动没什么太多:

public class DetailedActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detailed_activity);
    }
}

它的布局:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_container"
    android:name="com.myapps.sampleandroid.DetailedFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

和有趣的DetailedFragment:

public class DetailedFragment extends Fragment {

    public static DetailedFragment newInstance() {
        return new DetailedFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.MyDialogTheme);
        LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
        return localInflater.inflate(R.layout.detailed_fragment, container, false);
    }
}

...及其布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Regular Text" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button Dummy" />

</LinearLayout>

In onCreateView我尝试设置自定义样式,但它似乎不适用于平板电脑。

Styling

res/values/styles.xml 包含:

<resources>

    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    </style>

    <style name="MyDialogTheme" />

</resources>

而 res/values-large/styles.xml:

<resources>
    <!-- Is there anything I should add here? -->
    <style name="MyDialogTheme" parent="@android:style/Theme.Dialog"/>
</resources>

我已经嵌套了MyDialogTheme from Theme.Dialog,但似乎没有帮助。

On smartphone when tapping on "NEXT" action bar menu item I am seeing the detailed activity (snapshot from an SG2): snapshot from an SG2

while tapping on the same "NEXT" menu item from the tablet it doesn't do anything (except viewing the message on Logcat: Yes, I am seeing this line). enter image description here

我应该在 styles.xml 或代码中添加更多内容才能看到DetailedFragment作为平板电脑的对话框?

EDIT

我已经尝试过解决方案小孩儿提议(有一个DialogFragment包含我的初始片段并显示它)。所以,我添加了一个WrapperDetailedFragment:

public class WraperDetailedFragment extends DialogFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.wrap_detailed_fragment, container, false);
    }
}

它的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_container_dialog"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <fragment
        android:id="@+id/wrapped_fragment_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.myapps.sampleandroid.DetailedFragment" />

</LinearLayout>

MainActivity 中的代码更改为:

private void decideToNext() {
    String device = getString(R.string.device);
    if ("normal".equalsIgnoreCase(device)) {
        Intent intent = new Intent(this, DetailedActivity.class);
        startActivity(intent);
    } else if ("large".equalsIgnoreCase(device)) {
        Log.d("SOME_TAG", "Yes, I am seeing this line ...");
        WraperDetailedFragment fragment = new WraperDetailedFragment();
        fragment.show(getSupportFragmentManager(), "MAGICAL_TAG");
    }
}

但是当我尝试添加此 DialogFragment 时,出现以下崩溃:

android.view.InflateException: Binary XML file line #8: Error inflating class fragment
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    at com.myapps.sampleandroid.WraperDetailedFragment.onCreateView(WraperDetailedFragment.java:12)
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:304)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    at com.myapps.sampleandroid.WraperDetailedFragment.onCreateView(WraperDetailedFragment.java:12)
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f050047, tag null, or parent id 0x0 with another fragment for com.myapps.sampleandroid.DetailedFragment
    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:290)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
    ... 28 more

这个问题可以很容易地解决,如果不是尝试做一个Fragment看起来像一个DialogFragment我会从相反的角度看:做一个DialogFragment看起来像一个Fragment- 毕竟,一个DialogFragment is a Fragment!

这个修复的关键是调用还是不调用DialogFragment.setShowsDialog();

所以改变DetailedFragment to:

public class DetailedFragment extends DialogFragment {

    private static final String ARG_SHOW_AS_DIALOG = "DetailedFragment.ARG_SHOW_AS_DIALOG";

    public static DetailedFragment newInstance(boolean showAsDialog) {
        DetailedFragment fragment = new DetailedFragment();
        Bundle args = new Bundle();
        args.putBoolean(ARG_SHOW_AS_DIALOG, showAsDialog);
        fragment.setArguments(args);
        return fragment;
    }

    public static DetailedFragment newInstance() {
        return newInstance(true);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            setShowsDialog(args.getBoolean(ARG_SHOW_AS_DIALOG, true));
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.detailed_fragment, container, false);
    }
}

它的布局保持原样,DetailedActivity更改为:

public class DetailedActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detailed_activity);
        if (savedInstanceState == null) {
            DetailedFragment fragment = DetailedFragment.newInstance(false);
            getSupportFragmentManager().beginTransaction().add(R.id.root_layout_details, fragment, "Some_tag").commit();
        }
    }
}

它的布局也是如此:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_layout_details"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

并且调用者活动仅执行以下操作:

private void decideToNext() {
    String device = getString(R.string.device);
    if ("normal".equalsIgnoreCase(device)) {
        Intent intent = new Intent(this, DetailedActivity.class);
        startActivity(intent);
    } else if ("large".equalsIgnoreCase(device)) {
        DetailedFragment fragment = DetailedFragment.newInstance();
        fragment.show(getSupportFragmentManager(), "Tablet_specific");
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 片段显示为对话框片段或普通片段 的相关文章

随机推荐

  • 为什么 '.sort()' 会导致 Python 中的列表为 'None'? [复制]

    这个问题在这里已经有答案了 我正在尝试对 Python 列表进行排序ints 然后使用 pop 函数返回最高的一个 我尝试过以不同的方式编写该方法 def LongestPath T paths Ancestors T x for x in
  • 计算出一天已过去的百分比

    有点奇怪的问题 但希望有人能帮忙 本质上 如果时间是中午 12 点 则经过百分比为 50 上午 6 点为 25 下午 16 点为 75 给定当前时间 您如何计算出已经过去了多少天 假设您可以获得一天中的当前时间 那么计算一天过去的百分比将非
  • JSpinner.DateEditor 必须包含年份,即使开始和结束是同一年

    我有一个使用 SpinnerDateModel 的 JSpinner 其开始日期为 2010 年 1 月 1 日 00 00 00 000 结束日期为 2010 年 1 月 1 日 00 12 34 217 我希望我的 JSpinner D
  • 如何设置在整个应用程序中可访问的全局变量

    我开发了一个带有全局变量的PHP页面 如下所示 global amty imgCache amty imgCache array GLOBALS amty imgCache amty imgCache 该页面具有向该数组添加 删除条目的功能
  • 使用管道符号作为分隔符拆分字符串

    为什么下面的输出是 并不是 1 String input 1 2 3 String values input split System out println values 0 Output 但是 如果我们更改分隔符 则输出为 1 Stri
  • Grub 2 未检测到内核中的多重引导标头

    我在使用 Grub 2 以及 QEMU 的 kernel 没有检测到我的内核中的 Multiboot v1 标头 我之前将标题放在单独的部分中 text linker ld SECTIONS 1M multiboot ALIGN 4K mu
  • 如何列出 git 存储库中跟踪文件的所有不同扩展名?

    我想知道所有不同的扩展名给定存储库中 git 跟踪的文件的数量 以便创建适当的 gitattributes file 预期输出示例 bat gitignore gradle html jar java js json md png prop
  • Golang 中的泛型方法参数

    我需要帮助才能使其适用于任何类型 我有一个函数 我需要接受其他类型ID财产 我尝试过使用接口 但这对我来说不起作用ID财产案 这是代码 package main import fmt strconv type Mammal struct I
  • 如何加密非阻塞 PHP 套接字流?

    我正在尝试以非阻塞 异步 方式使用 PHP 的stream socket client 函数 PHP 网站上的文档表明 STREAM CLIENT ASYNC CONNECT 选项标志应该启用此功能 然而 下面的代码 start time
  • C# .net 更改标签文本

    您好 我尝试使用此代码 但由于某种原因它不起作用 确实需要帮助 问题是当我进入网站时 标签不会从 标签 更改名称
  • 是否可以在我的网站上禁用 IE8“加速器”?

    我是一名专注于 UI 的 Web 开发人员 我的 Web 应用程序中的许多界面功能都是基于双击的 在 IE 中 这会带来新的烦人的问题 加速器 图标干扰我的用户界面 是否可以禁用我的页面上的 加速器 也许有一些新的愚蠢的特定于 IE 的me
  • 如何捕获div中的一行文本

    我浏览过与此相关的类似 SO 帖子 但没有一个完全符合我正在寻找的内容 假设我有一些文本 我将其放入 div 中 然后向该 div 添加一些任意 甚至可能是动态 宽度 有没有什么方法可以让我以编程方式捕获和操作 div 中的各个文本行 例如
  • Json.NET 按深度和属性序列化

    例如我们有两个类 class FooA SomeSpecialAttribute public int SomeValueA get set public int SomeValueB get set public int SomeValu
  • Persistence.xml放在eclipse项目的哪里

    简单的问题 我在Eclipse环境中有一些项目MainApp 企业应用项目 其中 包含 Web控制器 EJB项目 WebModel JPA 项目 WebView 动态Web项目 问题是 persistence xml 文件放在哪里 获取异常
  • Spring Boot、静态资源和mime类型配置

    我面临着无法处理的 Spring Boot 配置问题 我正在尝试使用 Spring Boot 为 HbbTV 构建一个 HelloWorld 示例 因此我需要使用 mime type application vnd hbbtv xhtml
  • 从本地服务器迁移到 Azure:TIMEZONE UTC。怎么解决?

    我设计我的应用程序时考虑到了这样一个事实 根据规范 应该在位于意大利的服务器上运行 并且客户端只能是意大利人 大约一个月前 我的老板决定将所有内容都放在 Azure 上 一切都很顺利 唯一给我带来问题的是时间服务器是 UTC 解决方案是 一
  • 标记为“内容”->“始终复制”的文件不会被复制

    我的 C VS2010 项目的文件夹中有一个文件标记为Content and Always Copy 当我更改此文件并将其保存到 VS 外部 然后运行该项目时 修改后的文件不会复制到输出中 如果我重建 那就是 我的猜测是VS不会使用文件的修
  • 在自定义 powershell 函数中模拟 -ErrorAction

    如何在自定义 powershell 函数中模拟 ErrorAction 例如考虑以下脚本 function Foo2 Write Host in Foo2 Error occurs Foo3 function Foo1 Write Host
  • 是否值得在代码中缓存 glsl 统一位置?

    我希望能够通过着色器中的实际名称设置制服 myProgram uniform3fv uniformVector 0 0f 0 1f 1 0f 我是否必须以某种形式的地图缓存位置 std map
  • Android 片段显示为对话框片段或普通片段

    我想要实现的是有一个片段 在平板电脑上显示为DialogFragment 而在智能手机上它将显示为常规片段 我知道已经有一个类似的帖子 但我无法做到这一点 将样式应用于片段 为了自上而下地显示内容 MainActivity java pub