6

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

Zoe
  • 27,060
  • 21
  • 118
  • 148
AndroidSRS
  • 61
  • 1
  • 1
  • 3

7 Answers7

15

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.

This will show correct oriented layout when load, for change layout when device rotate add following in onConfigarationChanged method inside fragment itself.

@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();
        }
    }
}
UdayaLakmal
  • 4,035
  • 4
  • 29
  • 40
  • @tmm1 the above solution it reload current fragment again with remove current one.. and onConfigurationChanged defined on fragment it self. so I'm not clear what you men by fragment is lost. – UdayaLakmal Aug 13 '18 at 04:34
  • 1
    Thanks. I was trying to put it in my base fragment class and it wasn't working (fragment would disappear from screen). Once I moved it into the final fragment subclass it started working. – tmm1 Aug 13 '18 at 16:09
  • 1
    Thanks it is help full me its save my whole day – Mehul Tank Aug 29 '18 at 10:17
  • 1
    Worked perfectly for me! – GetSwifty Nov 14 '18 at 18:21
  • 1. What is the purpose of explicit check for orientation to be just portrait or landscape, what are other possibilities? – alizeyn Sep 01 '19 at 12:33
  • 2. It's not a good idea to catch generic exception. https://source.android.com/setup/contribute/code-style#dont-catch-generic-exception – alizeyn Sep 01 '19 at 12:34
  • @AliZeynali 1. because onConfigurationChanged call not only for orientation change ex: "keyboardHidden" therefor this action perform just for orientation change either to portrait or landscape – UdayaLakmal Sep 02 '19 at 05:13
3

If the onCreateView function is called when you rotate the screen, you can do this in it:

if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
    ......
} else if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT) {
    .........
}
jayeshsolanki93
  • 2,096
  • 1
  • 20
  • 37
sky
  • 63
  • 1
  • 7
3

Late but this will help some one

Try this in V4 Fragment

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

        if (getFragmentManager() != null) {
            getFragmentManager()
                    .beginTransaction()
                    .detach(this)
                    .attach(this)
                    .commit();
        }
    }
Tara
  • 692
  • 5
  • 23
1

What you're trying to do is rather complicated. Android Fragments are not meant to be rotated. 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). This LinearLayout will serve as the canvas for our menu:

<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.

Luís Henriques
  • 604
  • 1
  • 10
  • 30
0

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. Look here for details.

Community
  • 1
  • 1
Nir Duan
  • 6,164
  • 4
  • 24
  • 38
0

By default, the layouts in /res/layout are applied to both portrait and landscape.
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.

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.

Vinothkumar Nataraj
  • 588
  • 2
  • 7
  • 23
0

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; 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;
}
Shift Delete
  • 1,015
  • 6
  • 13