【问题标题】:How to handle 2 different layouts in an activity Android如何在一个活动 Android 中处理 2 种不同的布局
【发布时间】:2014-06-10 11:41:00
【问题描述】:

[已编辑]: 我已经开发了一个在不同屏幕尺寸的手机和平板电脑上运行良好的应用程序,我按照 android 指南创建了不同的 UI 布局集以适应不同尺寸的屏幕(手机和平板电脑),并且所有布局都是纵向的模式。在那之前一切正常,但现在我有一个新要求,即平板电脑的布局将被更改,即 它将比手机布局具有一些额外的信息,并且所有新布局都将处于横向模式。 p>

现在我的疑问是:

  1. 在旧实现中,不同布局文件夹中的所有布局名称都相同,即布局、布局-小、布局-大等...因此,根据新要求,所有大和超大布局应为横向模式但是如果我保持相同的布局名称,那么我该如何处理方向?目前,每个活动的清单文件中都提到了方向属性。
  2. 如果我保留这些布局的不同名称,那么我必须在运行时处理,即在加载活动时,基于检查手机屏幕大小,然后加载相应的布局,因此相同的活动可以根据检查加载不同的布局屏幕尺寸。这将是这样做的最佳方法吗?
  3. 或者,我是否必须为所有新布局完全引入新活动来处理这种情况?

请建议我处理这种情况的最佳方法。

【问题讨论】:

  • 您已经待了这么久,知道此类问题会给您带来很多反对票,因为您自己没有尝试解决问题。我建议您在反对票开始之前改写您的问题。我不会对您的帖子投反对票,但其他人可能会。 ;)
  • 你想要意见吗?

标签: android android-layout


【解决方案1】:

官方 Android 文档(以下链接)是一个很好的起点。

  1. http://developer.android.com/guide/practices/screens_support.html
  2. http://developer.android.com/training/basics/supporting-devices/screens.html

简而言之,我可以告诉您必须创建多个布局来满足您对支持多种屏幕尺寸/分辨率的要求。在您的应用程序源目录中,您必须在不同的资源布局目录下创建不同的布局 xml(同名),如下所示:

 res/
        layout/              # default (portrait)
            main.xml
        layout-land/         # landscape
            main.xml
        layout-large/        # large screen devices (portrait)
            main.xml
        layout-large-land/   # large screen devices (landscape)
            main.xml

【讨论】:

    【解决方案2】:

    我建议您将所有相似的文件命名为相同的名称。

    充分利用 Android 提供的限定符,例如尺寸或设置宽度限定符。您可能有小屏幕手机的单窗格布局和平板电脑的多窗格布局。为横向提供多窗格布局(您可以将两个现有布局合并为一个)是一个很好的建议。

    例如:

    res/layout/onepane.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <fragment android:id="@+id/frag1"
              android:layout_height="fill_parent"
              android:name="com.example.android.dummyApp"
              android:layout_width="match_parent" 
              android:background="@drawable/bg"/>
              </LinearLayout>
    

    res/layout/twopanes.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/fragone"
              android:layout_height="fill_parent"
              android:name="com.example.android.dummyApp"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"
              android:background="@drawable/bg"/>
    <fragment android:id="@+id/fragtwo"
              android:layout_height="fill_parent"
              android:name="com.example.android.dummyApp"
              android:layout_width="fill_parent" />
             </LinearLayout>
    

    现在所有可能的布局都已定义,只需使用配置限定符将正确的布局映射到每个配置即可。您现在可以使用布局别名技术来做到这一点:

    res/values/layouts.xml:

    <resources>
    <item name="main_layout" type="layout">@layout/onepane</item>
    <bool name="has_two_panes">false</bool>
    </resources>
    

    res/values-sw600dp-land/layouts.xml:

    <resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
    </resources>
    

    注意:values 文件夹中两个 xml 文件中的布尔值。

    Smallest-width 限定符允许您定位在 dp 中具有特定最小宽度的屏幕。代替大尺寸限定符,使用 sw600dp 指示双窗格布局适用于最小宽度为 600 dp 的屏幕。

    另外,另一种解决方案:

    如果您打算为不同的屏幕尺寸制作不同的活动,您可以为同一个项目构建多个 apk。您要发布的每个 APK 都应该有一个单独的 Android 项目。

    请查看此链接以获取有关多个 APK 的更多信息。 http://developer.android.com/training/multiple-apks/screensize.html

    【讨论】:

    【解决方案3】:

    就个人而言,我会制作两个不同的 Fragment,具有两个不同的 Fragment 布局,我会根据布局文件夹标识符为正确的屏幕尺寸加载 Fragment,如下所示:http://developer.android.com/training/basics/supporting-devices/screens.html

    典型片段:

    public class MyFragment extends Fragment implements View.OnClickListener
    {
        private Button btnSave;
        private Button btnCancel;
    
        public MyFragment()
        {
            super();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View rootView = inflater.inflate(R.layout.fragment_myfragment_small, container, false);
            return rootView;
        }
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState)
        {
            super.onViewCreated(view, savedInstanceState);
            btnSave = (Button) getActivity().findViewById(R.id.myfragment_small_save);
            btnCancel = (Button) getActivity().findViewById(R.id.myfragment_small_cancel);
    
            btnSave.setOnClickListener(this);
            btnCancel.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v)
        {
            if (btnSave == v)
            {
                save();
            }
            else if (btnCancel == v)
            {
                cancel();
            }
        }
    }
    

    对较大的做同样的事情。如果您通过从 MyFragment 扩展或将它们的逻辑剥离到另一个类中来重用 save() 和 cancel() 函数,则可以加分。

    静态片段链接:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <fragment
            android:id="@+id/fragment_myfragment_small"
            android:name="com.example.stuff.longer.MyFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>
    

    以及fragment_myfragment_small.xml中片段的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    <Button android:id="@+id/myfragment_small_cancel"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="@string/cancel"
    />
    <Button android:id="@+id/myfragment_small_save"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/myfragment_small_cancel"
            android:text="@string/save"
    />
    
    </RelativeLayout>
    

    并为第二个更大的布局制作第二个。将布局放在不同的 \res\layout 文件夹中,例如 \res\layout-large。

    【讨论】:

    • 显然,这可能不是一个完美的方法。哦,好吧,我想这会很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    相关资源
    最近更新 更多