简体   繁体   English

Android Fragments 中方向更改时布局更改

[英]Layout change when orientation changes in Android Fragments

please suggest a solution.请提出解决方案。

When i rotate my fragment it should change in to landscape mode and to display another layout.But screen is not rotating to landscape.当我旋转我的片段时,它应该变成横向模式并显示另一个布局。但屏幕没有旋转到横向。

My code blow:我的代码打击:

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

This is main layout called dashboard and now it is in portrait mode:这是称为仪表板的主要布局,现在处于纵向模式:

 @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;
}

when i rotate the screen this fragment changed to landscape mode and set another layout, and prayer_times is the new layout.当我旋转屏幕时,此片段更改为横向模式并设置另一个布局,而祷告时间是新布局。

   @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);

    }
}

and i create layout_land for prayer_times我为祈祷时间创建了 layout_land

If your fragment has no issue of reloading when orientation change you can simply reload.如果您的片段在方向改变时没有重新加载的问题,您可以简单地重新加载。

Add two layout with same name in layout and layout-land folders.layoutlayout-land文件夹中添加两个同名的layout

This will show correct oriented layout when load, for change layout when device rotate add following in onConfigarationChanged method inside fragment itself.这将在加载时显示正确的定向布局,以便在设备旋转时更改布局在片段本身的 onConfigarationChanged 方法中添加以下内容。

@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();
        }
    }
}

If the onCreateView function is called when you rotate the screen, you can do this in it:如果在旋转屏幕时调用了onCreateView函数,则可以在其中执行以下操作:

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

Late but this will help some one晚了,但这会帮助某人

Try this in V4 Fragment在 V4 片段中​​试试这个

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

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

What you're trying to do is rather complicated.你要做的事情相当复杂。 Android Fragments are not meant to be rotated. Android Fragments 不能旋转。 I had the same problem and found a solution, though.不过,我遇到了同样的问题并找到了解决方案。 In my case, I wanted to present a Fragment containing different menu pages that would rotate according to orientation.在我的例子中,我想展示一个包含不同菜单页面的片段,这些页面会根据方向旋转。

Just create a Fragment that serves as a base and contains a simple LinearLayout (or any other layout type you want).只需创建一个 Fragment 作为基础并包含一个简单的 LinearLayout(或您想要的任何其他布局类型)。 This LinearLayout will serve as the canvas for our menu:这个 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>

Next, we want to code the base item fragment as an abstract class, that will be implemented by all menu item fragments:接下来,我们要将基本项片段编码为一个抽象类,它将由所有菜单项片段实现:

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

    }

}

And here is an example of a menu item fragment that rotates according to the device's orientation.这是一个根据设备方向旋转的菜单项片段示例。

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

    }

}

Hope it helps.希望它有帮助。

All you need to do is open a new layout-land folder inside your res folder and put there xml with the same name of your fragment's layout, the framework will know to look for that .xml on orientation changed.您需要做的就是在res文件夹中打开一个新的layout-land文件夹,并将与您的片段布局相同名称的 xml 放在那里,框架将知道在方向更改时查找该.xml Look here for details.详情请看这里

By default, the layouts in /res/layout are applied to both portrait and landscape.默认情况下,/res/layout 中的布局同时应用于纵向和横向。
If you have for example如果你有例如

/res/layout/main.xml

you can add a new folder /res/layout-land, copy main.xml into it and make the needed adjustments.您可以添加一个新文件夹 /res/layout-land,将 main.xml 复制到其中并进行所需的调整。

See also http://www.androidpeople.com/android-portrait-amp-landscape-differeent-layouts and http://www.devx.com/wireless/Article/40792/1954 for some more options.另请参阅http://www.androidpeople.com/android-portrait-amp-landscape-diferent-layoutshttp://www.devx.com/wireless/Article/40792/1954了解更多选项。

When you change the orientation, your fragment destroyed and recreated again ( See this for better understanding ).当您更改方向时,您的片段会被销毁并再次重新创建( 请参阅此以获得更好的理解)。 So in onConfigurationChanged, you inflate your new layout but it's useless because when your fragment recreated, the onCreateView is called again;因此,在 onConfigurationChanged 中,您对新布局进行了膨胀,但它没有用,因为在重新创建片段时,将再次调用 onCreateView; in other words, your old layout is inflated again.换句话说,您的旧布局再次膨胀。 So better to do this in this way:所以最好这样做:

@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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM