【问题标题】:Layout change when orientation changes in Android FragmentsAndroid Fragments 中方向更改时的布局更改
【发布时间】:2016-07-19 05:18:01
【问题描述】:

请提出解决方案。

当我旋转我的片段时,它应该变成横向模式并显示另一个布局。但是屏幕没有旋转到横向。

我的代码崩溃了:

 <activity
        android:name=".activites.MainActivity"
        android:launchMode="singleInstance"
        android:configChanges="keyboardHidden|screenLayout|screenSize|orientation"
        />

这是称为仪表板的主要布局,现在处于纵向模式:

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     View  view=View.inflate(getContext(), R.frag_dashboard,null);
     changeview= (ShimmerTextView)view.findViewById(R.id.changeview); 
     return view;
}

当我旋转屏幕时,这个片段变成了横向模式并设置了另一种布局,prague_times 是新的布局。

   @Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(getContext(), "landscape", Toast.LENGTH_SHORT).show();
        view=View.inflate(getContext(), R.layout.prayer_times,null);

    }
}

我为祈祷时间创建 layout_land

【问题讨论】:

  • 对不起,它不适合我
  • @AndroidSRS 纵向和横向最好使用不同的文件夹,布局名称相同。
  • 我得到了答案,我使用了“getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);”现在它的工作。
  • 但是有一个问题,布局没有变化,根据方向变化

标签: android android-layout android-fragments


【解决方案1】:

如果您的片段在方向改变时没有重新加载问题,您可以简单地重新加载。

在layout 和layout-land 文件夹中添加两个同名布局。

这将在加载时显示正确的方向布局,以便在设备旋转时更改布局 在片段本身内的 onConfigurationChanged 方法中添加以下内容。

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE || newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        try {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            if (Build.VERSION.SDK_INT >= 26) {
             ft.setReorderingAllowed(false);
            }
            ft.detach(this).attach(this).commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

【讨论】:

  • @tmm1 上面的解决方案它再次重新加载当前片段并删除当前片段..并且 onConfigurationChanged 定义在片段本身上。所以我不清楚你们这些人的碎片丢失了。
  • 谢谢。我试图把它放在我的基本片段类中,但它不起作用(片段会从屏幕上消失)。一旦我将它移到最终的片段子类中,它就开始工作了。
  • 感谢它帮助我充实了我的一整天
  • 非常适合我!
  • 1.明确检查方向是否为纵向或横向的目的是什么,还有哪些其他可能性?
【解决方案2】:

如果在旋转屏幕时调用onCreateView函数,你可以在里面这样做:

if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
    ......
} else if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT) {
    .........
}

【讨论】:

  • 由此可见,protrait 模式有效,但land scape 模式无效。
【解决方案3】:

迟到了,但这会帮助一些人

在 V4 片段中​​试试这个

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        if (getFragmentManager() != null) {
            getFragmentManager()
                    .beginTransaction()
                    .detach(this)
                    .attach(this)
                    .commit();
        }
    }

【讨论】:

    【解决方案4】:

    您尝试做的事情相当复杂。 Android Fragments 并不意味着旋转。 不过,我遇到了同样的问题并找到了解决方案。在我的例子中,我想展示一个包含不同菜单页面的片段,这些页面会根据方向旋转。

    只需创建一个 Fragment 作为基础并包含一个简单的 LinearLayout(或您想要的任何其他布局类型)。这个 LinearLayout 将作为我们菜单的画布:

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

    接下来,我们要将基本项片段编码为一个抽象类,它将由所有菜单项片段实现:

    public abstract class NavMenuItem extends Fragment {
    
        static final String TAG = "yourTag"; // Debug tag
    
        LinearLayout canvas;
        View hView; // we'll keep the reference of both views
        View vView;
    
        // All we'll need to do is set these up on our fragments
        abstract int getVerticalLayoutResource();
        abstract int getHorizontalLayoutResource();
        abstract void setupUI(); // assigns all UI elements and listeners
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.menu_base, container, false); // sets up the layout for this fragment
    
            // keeping our references to both layout versions
            hView = inflater.inflate(getHorizontalLayoutResource(), container, false);
            vView = inflater.inflate(getVerticalLayoutResource(), container, false);
    
            canvas = view.findViewById(R.id.llMenuCanvas); // this is the magic part: Our reference to the menu canvas
    
            // returning our first view depending on orientation
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                canvas.addView(hView);
            }else{
                canvas.addView(vView);
            }
            return view;
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            setupUI(); // here we set up our listeners for the first time
        }
    
        // Here we update the layout when we rotate the device
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
    
            canvas.removeAllViews();
    
            // Checking screen orientation
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                canvas.addView(hView);
            }
            else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
                canvas.addView(vView);
            }
            setupUI(); // we always need to rebind our buttons
    
        }
    
    }
    

    这是一个根据设备方向旋转的菜单项片段示例。

    public class NavMenuMain extends NavMenuItem{
    
        static final String TAG = "yourTag"; // Debug tag
    
        // Your layout references, as usual
        ImageButton btnCloseMenu;
    
        // here we set up the layout resources for this fragment
        @Override
        int getVerticalLayoutResource() { // vertical layout version
            return R.layout.menu_main_port;
        }
    
        @Override
        int getHorizontalLayoutResource() { // horizontal layout version
            return R.layout.menu_main_land;
        }
    
        @Override
        void setupUI(){
    
            // Setup button listeners and layout interaction here
    
            // REMEMBER: the names of your layout elements must match, both for landscape and portrait layouts. Ex: the "close menu" button must have the same id name in both layout versions
    
        }
    
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案5】:

      您需要做的就是在您的res 文件夹中打开一个新的layout-land 文件夹,并将与您的片段布局名称相同的xml 放在那里,框架将知道在方向更改时查找.xml。 详情请看here。

      【讨论】:

      • 是的,我照你说的做了。但没有变化。
      • onConfigurationChanged 函数未调用
      • 您使用的是仿真设备还是真实设备?
      【解决方案6】:

      默认情况下,/res/layout 中的布局适用于纵向和横向。
      例如,如果您有

      /res/layout/main.xml
      

      您可以添加一个新文件夹 /res/layout-land,将 main.xml 复制到其中并进行所需的调整。

      另请参阅 http://www.androidpeople.com/android-portrait-amp-landscape-differeent-layouts 和 http://www.devx.com/wireless/Article/40792/1954 了解更多选项。

      【讨论】:

        【解决方案7】:

        当您更改方向时,您的片段会被破坏并重新创建 (See this for better understanding)。所以在 onConfigurationChanged 中,你膨胀了你的新布局,但它没有用,因为当你的片段重新创建时,onCreateView 会再次被调用;换句话说,您的旧布局再次膨胀。所以最好以这种方式做到这一点:

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View  view;
        
            if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        
                view = View.inflate(getContext(), R.frag_dashboard,null);
                changeview = (ShimmerTextView)view.findViewById(R.id.changeview);
            } else(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        
                Toast.makeText(getContext(), "landscape", Toast.LENGTH_SHORT).show();
                view = View.inflate(getContext(), R.layout.prayer_times,null);
            }
        
            return view;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多