簡體   English   中英

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

[英]Layout change when orientation changes in Android Fragments

請提出解決方案。

當我旋轉我的片段時,它應該變成橫向模式並顯示另一個布局。但屏幕沒有旋轉到橫向。

我的代碼打擊:

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

當我旋轉屏幕時,此片段更改為橫向模式並設置另一個布局,而禱告時間是新布局。

   @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

如果您的片段在方向改變時沒有重新加載的問題,您可以簡單地重新加載。

layoutlayout-land文件夾中添加兩個同名的layout

這將在加載時顯示正確的定向布局,以便在設備旋轉時更改布局在片段本身的 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();
        }
    }
}

如果在旋轉屏幕時調用了onCreateView函數,則可以在其中執行以下操作:

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

晚了,但這會幫助某人

在 V4 片段中​​試試這個

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

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

你要做的事情相當復雜。 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

    }

}

希望它有幫助。

您需要做的就是在res文件夾中打開一個新的layout-land文件夾,並將與您的片段布局相同名稱的 xml 放在那里,框架將知道在方向更改時查找該.xml 詳情請看這里

默認情況下,/res/layout 中的布局同時應用於縱向和橫向。
如果你有例如

/res/layout/main.xml

您可以添加一個新文件夾 /res/layout-land,將 main.xml 復制到其中並進行所需的調整。

另請參閱http://www.androidpeople.com/android-portrait-amp-landscape-diferent-layoutshttp://www.devx.com/wireless/Article/40792/1954了解更多選項。

當您更改方向時,您的片段會被銷毀並再次重新創建( 請參閱此以獲得更好的理解)。 因此,在 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM