设备旋转时如何使用不同的标记更改布局?

时间:2018-01-20 18:32:15

标签: java android android-layout android-studio android-fragments

描述

我在垂直orinentation 中有一个活动,带有两个标签( TabLayout )和片段,这些标签随 Viewpager 更改。

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        // Assign created adapter to viewPager
        viewPager.setAdapter(new TabsExamplePagerAdapter(getSupportFragmentManager()));

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        // This method setup all required method for TabLayout with Viewpager
        tabLayout.setupWithViewPager(viewPager);
    }

    public class TabsExamplePagerAdapter extends FragmentPagerAdapter {
        // As we are implementing two tabs
        private static final int NUM_ITEMS = 2;

        public TabsExamplePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        // For each tab different fragment is returned
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new TabOneFragment();
                case 1:
                    return new TabTwoFragment();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public CharSequence getPageTitle(int position) { 
            return "Tab " + (position + 1);
        }
    }
}  

activity_main.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:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:tabTextColor="#ffffff"
        app:tabIndicatorColor="#fbff3a"
        app:tabSelectedTextColor="#fbff3a"
        app:tabIndicatorHeight="5dp"
        android:elevation="4dp"
        app:tabGravity="fill"
        app:tabMaxWidth="0dp" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>  

在每个标签中我都有一个片段。

TabOneFragment.java (TabTwoFragment类似):

public class TabOneFragment extends Fragment {

    // Required empty public constructor
    public TabOneFragment() { }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_tab_one, container, false);
    }
}

fragment_one_tab.xml (fragment_one_tab.xml类似)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="innovatecode.com.tabexample.TabOneFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="18dp"
        android:text="@string/tab_one" />

</FrameLayout>

我只是结果:

enter image description here

我的问题

当我的设备旋转到水平位置时,我希望得到以下结果: enter image description here

我为水平标记创建了xml( land ):

active_main.xml (土地)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

     <FrameLayout 
            android:id="@+id/fragment_left"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />

      <FrameLayout
            android:id="@+id/fragment_right"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />

</LinearLayout>

但我不知道如何更改我的代码以获得此结果。我在处理碎片方面不是很强大。

1 个答案:

答案 0 :(得分:1)

首先,您可以通过将片段直接添加到布局文件(在&#34; res / layout-land&#34;下)来改善您的横向布局:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

     <fragment
            android:name="innovatecode.com.tabexample.TabOneFragment"
            android:id="@+id/fragment_left"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />

      <fragment
            android:name="innovatecode.com.tabexample.TabTwoFragment"
            android:id="@+id/fragment_right"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />

</LinearLayout>

您可以阅读有关here主题的内容。

对于代码部分,您可以利用横向和纵向布局的不同功能在代码中的相应逻辑之间切换。例如:

 public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        if (findViewById(R.id.tab_layout) != null) {
            setUpPortraitLayout();
        } else {
            setUpLandscapeLayout();
        }
    }

    private void setUpPortraitLayout() {
        ViewPager viewPager = findViewById(R.id.pager);
        // Assign created adapter to viewPager
        viewPager.setAdapter(new TabsExamplePagerAdapter(getSupportFragmentManager()));

        TabLayout tabLayout = findViewById(R.id.tab_layout);
        // This method setup all required method for TabLayout with Viewpager
        tabLayout.setupWithViewPager(viewPager);
    }

    private void setUpLandscapeLayout() {
        // Note: with the layout definition suggested above you don't
        // need any manual processing to set-up your layout for landscape
        // but you still may have some extra set-up (initial binding, etc).
        tabOneFragment = (TabOneFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_left);
        tabTwoFragment = (TabTwoFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_right);
        // ...
    }
}

您可以通过&#34; setArguments()&#34;将保存的参数传递给您的片段。方法。或者考虑使用&#34; onSaveInstanceState()&#34;片段的方法(与您现在使用的活动相对)。

替代方法:在横向和纵向情况下动态添加片段。它基于您的代码。我认为某些方面是有争议的(我可能是错的),但改变方向意味着重写整个事情。但它最终应该有效。

RES /布局脊/ active_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

     <FrameLayout 
            android:id="@+id/fragment_left"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />

      <FrameLayout
            android:id="@+id/fragment_right"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />

</LinearLayout>

MainActivity.java(基于您通过gist共享的代码)

public class MainActivity extends AppCompatActivity {
    private Fragment tabOneFragment;
    private Fragment tabTwoFragment;

    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        if (savedInstanceState != null) {
            //Restore the fragment's instance
            tabOneFragment = (TabOneFragment) getSupportFragmentManager().getFragment(
                    savedInstanceState, "tabOneFragment");
            tabTwoFragment = (TabTwoFragment) getSupportFragmentManager().getFragment(
                    savedInstanceState, "tabTwoFragment");
        } else {
            tabOneFragment = new TabOneFragment();
            tabTwoFragment = new TabTwoFragment();
        }

        if (findViewById(R.id.tab_layout) != null) {
            setUpPortraitLayout();
        } else {
            setUpLandscapeLayout();
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        getSupportFragmentManager().putFragment(outState, "tabOneFragment", tabOneFragment);
        getSupportFragmentManager().putFragment(outState, "tabTwoFragment", tabTwoFragment);
    }

    private void setUpPortraitLayout() {
        viewPager = (ViewPager) findViewById(R.id.pager);
        // Assign created adapter to viewPager
        viewPager.setAdapter(new TabsPagerAdapter(getSupportFragmentManager()));

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        // This method setup all required method for TabLayout with Viewpager
        tabLayout.setupWithViewPager(viewPager);
    }

    private void setUpLandscapeLayout() { 
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_left, tabOneFragment);
        transaction.replace(R.id.fragment_right, tabTwoFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }

    private class TabsPagerAdapter extends FragmentPagerAdapter {
        // As we are implementing two tabs
        private static final int NUM_ITEMS = 2;

        public TabsPagerAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        @Override
        // For each tab different fragment is returned
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return tabOneFragment;

                case 1:
                    return tabTwoFragment;

                default:
                    throw new IllegalStateException("Invalid tab index");
            }
        }

        @Override
        public int getCount() { return NUM_ITEMS; }

        @Override
        public CharSequence getPageTitle(int position) {  return "Tab " + (position + 1); }

        // NOTE: I think you do not really need to override "instantiateItem()", therefore I removed it.
    }
}