代码之家  ›  专栏  ›  技术社区  ›  loser

如何防止仅针对布局而非整个屏幕/活动的方向更改

  •  4
  • loser  · 技术社区  · 11 年前

    我需要一个子布局(可以是任何布局,比如 FrameLayout RelativeLayout )忽略方向变化并始终保持在横向方向。但不是它的父布局或任何其他同级布局/视图,它们应该相应地更改方向。

    因此,我不能使用 setRequestedOrientation() android:screenOrientation="landscape" 。或者它将锁定整个屏幕或活动的方向。我只需要锁定这个单独的布局。

    我的布局XML:

    RelativeLayout (Parent)
      TextView
        FrameLayout/RelativeLayout <-- this need to be locked
          FrameLayout
            Button
    
    2 回复  |  直到 11 年前
        1
  •  1
  •   Neil Townsend    11 年前

    这可能取决于你所说的“不改变方向”是什么意思。然而,我认为最好的开始是为不应该改变的部分创建自己的类。因此,布局xml现在有两个文件:

    主布局.xml

    RelativeLayout (Parent)
        TextView
            MyNonChangingLayout
    

    my_non_ching_layout.xml

     RelativeLayout
         FrameLayout
             Button
    

    您创建的位置

    MyNonChangingLayout extends FrameLayout {
        MyNonchangingLayout(Context content) {
            super(context);
            myContext = context;
            makeFromXML();
        }
    
    private void makeFromXML() {
        LayoutInflater inflater = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        topView =  inflater.inflate(MyR.layout.my_non_changing_layout, this, false);
    
        // Get all the sub Views here using topView.findViewById()
    
        // Do any other initiation of the View you need here
    
        // Make sure you this otherwise it won't actually appear!
        super.addView(topView);
    }
    
    /*
     * Then, you can override quite a lot of the layout's calls and
     * enforce behaviour on the children. Two examples:
     */
    
    // To specifically catch orientation changes
    @Overridge
    onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // You could create the layout here by removing all views and rebuilding them
        // Perhaps by having a two xml layouts, one of which is "90 degrees out" ...
        // If you do make the layot here, make sure you don't clash with the constructor code!
        switch (newConfig.orientation) {
            case ORIENTATION_LANDSCAPE:
                // Make the layout for this orientation (as per above)
                break;
            case ORIENTATION_PORTRAIT:
                // Make the layout for this orientation (as per above)
                break;
            case ORIENTATION_SQUARE:
                // Make the layout for this orientation (as per above)
                break;
        }
    }
    
    //to handle size changes to enforce aspect ratios on children:
    @override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    
        int viewWidth = //something I've determine
        int viewHeight = //something I've determined
        setViewsize(viewToHaveSizedControlled, viewWidth, viewheight);
    }
    
    // The post thing means that it doesn't crash no matter which thread it is
    // executed on ...
    private void setViewsize(final View v, final int w, final int h) {
        post(new Runnable() {
            public void run() {
                ViewGroup.LayoutParams lp = v.getLayoutParams();
                lp.width = w;
                lp.height = h;
                v.setLayoutParams(lp);
        }});
    }
    

    }

    然后你可以很好地执行任何你想要的东西。如果你能更具体地说明你想在子区域实施什么行为,我可能会建议更具体的代码。

    你可能想做的一件事是

        2
  •  1
  •   Jiyong Park    11 年前

    扩展要保持纵向的布局类,并覆盖dispatchConfurationChanged(Configuration)方法,如下所示。

    public void dispatchConfigurationChanged(Configuration newConfig) {
        Configuration c = new Configuration(newConfig); // copy
        c.orientation = ORIENTATION_PORTRAIT; // lock to portrait
        super.dispatchConfigurationChanged(c);
    }
    

    请确保您的应用程序已配置为在方向更改时不重新启动。