Android View 在旋转后宽度和高度未改变

4
我有一个活动,需要在旋转后更改其布局,其中的一部分布局是使用视图的宽度和高度绘制的图形。当代码第一次运行时,图形会被正确地绘制出来,但旋转后,容器视图的宽度和高度不正确,实际上它们似乎是未旋转的视图。
到目前为止,我所做的如下:
- 在我正在工作的活动的清单中: ``` android:configChanges="keyboardHidden|orientation|screenSize" ```
- 在我的活动中,我有以下方法: ``` onCreate ```
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Bundle extras = getIntent().getExtras();
    patient_id = extras.getInt("patient_id");
    patient_name = extras.getString("patient_name");
    historyDurationType = 12;

    constructLayout();
}

构建布局

public void constructLayout(){
    if(landScape){
        setContentView(R.layout.activity_bg_history_static_land);

        //Set buttons
        btnTwelve = (Button)findViewById(R.id.btnTwelveHoursLand);
        btnTwentyFour = (Button)findViewById(R.id.btnTwentyFourHoursLand);
        btnSeven= (Button)findViewById(R.id.btnSevenDaysLand);

        btnTwelve.setOnClickListener(this);
        btnTwentyFour.setOnClickListener(this);
        btnSeven.setOnClickListener(this);

        btnTwelve.setBackgroundColor(getResources().getColor(R.color.light_blue_regular));
        btnTwentyFour.setBackgroundResource(android.R.drawable.btn_default);
        btnSeven.setBackgroundResource(android.R.drawable.btn_default);         
    }else{
        setContentView(R.layout.activity_bg_history_static);
        //Set buttons
        btnTwelve = (Button)findViewById(R.id.btnTwelveHours);
        btnTwentyFour = (Button)findViewById(R.id.btnTwentyFourHours);
        btnSeven= (Button)findViewById(R.id.btnSevenDays);

        btnTwelve.setOnClickListener(this);
        btnTwentyFour.setOnClickListener(this);
        btnSeven.setOnClickListener(this);

        btnTwelve.setBackgroundColor(getResources().getColor(R.color.light_blue_regular));
        btnTwentyFour.setBackgroundResource(android.R.drawable.btn_default);
        btnSeven.setBackgroundResource(android.R.drawable.btn_default);

        btnComment = (Button)findViewById(R.id.btnCommentGraph);
        btnComment.setOnClickListener(this);

         populateOtherContent(officialReadings12);
         TextView tvStats = (TextView)findViewById(R.id.txtStatistics);
         Typeface chunkFiveFont = Typeface.createFromAsset(getAssets(), "fonts/chunkfivettfversion.ttf");
         tvStats.setTypeface(chunkFiveFont);

         TextView tvReading = (TextView)findViewById(R.id.txtReadingTitle);
         tvReading.setTypeface(chunkFiveFont);
         comment = null;
    }

    if(needData){
        getLatestReadings();
    }  

    populateGraph();
}

populateGraph

public void populateGraph(){
    if(landScape){
        graph_container = (LinearLayout)findViewById(R.id.graph_land_content_layout);
    }else{
        graph_container = (LinearLayout)findViewById(R.id.graph_content_layout);
    }

    //Create graphlayout        
    mainGraph_Layout = new RelativeLayout(this);

    RelativeLayout.LayoutParams glParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    mainGraph_Layout.setId(909);
    mainGraph_Layout.setLayoutParams(glParams);
    graph_container.addView(mainGraph_Layout);


    graph_container.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            if(needsGraph){
                layoutGraph();
                needsGraph = false;
            }
        }
    });

}

布局图

public void layoutGraph(){      

    viewWidth = mainGraph_Layout.getWidth();
    viewHeight = mainGraph_Layout.getHeight();

     //MORE STUFF IS HERE BUT NOT IMPORTANT

}

onConfigurationChanged

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    ActionBar actionBar = getActionBar();
    if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){
        //Config is landscape here          
        actionBar.hide();
        needData = false;
        landScape = true;
        needsGraph = true;
        constructLayout();
    }else{
        //Config is portrait here
        actionBar.show();
        needData = false;
        landScape = false;
        needsGraph = true;
        constructLayout();
    }
}

旋转后,在layoutGraph()中,我遇到了问题,在这里viewWidth和viewHeight对象。在那个时候,我假设(使用全局布局监听器)值是正确的。我的理解是,监听器只会在“graph_container”完成(横向或纵向)后触发一次,因此调用layoutGraph()时,“mainGraph_layout”的宽度和高度(一个子图形容器,宽度和高度设置为MATCH_PARENT)将已经准备就绪。看起来我所得到的宽度和高度都像手机仍处于纵向状态,需要注意的是操作栏被移除也已经考虑进去了。
抱歉问题有点长,但我认为展示所有的代码最好。如果还需要展示其他内容,请告诉我。
提前感谢, Josh
1个回答

1

有一种更好的方法来实现这个。

使用资源文件夹

将默认布局文件放在res/layout中,横屏布局文件放在res/layout-land中。换句话说,将res/layout/activity_bg_history_static_land.xml移动到res/layout-land/activity_bg_history_static.xml中。

onCreate中调用

setContentView(R.layout.activity_bg_history_static);

系统将从res/layout-land中选择文件,当您处于横向方向时,否则从res/layout中选择。
如果您有视图仅存在于一个布局而不在另一个布局中,例如评论按钮,请像这样将代码包装在空值检查中:
btnComment = (Button) findViewById(R.id.btnCommentGraph);
if (btnComment != null) {
  btnComment.setOnClickListener(this);
}

对于 populateGraph(),请确保 res/layout/activity_bg_history_static.xmlres/layout-land/activity_bg_history_static.xml 都有 android:id="@+id/R.id.graph_content。然后,您可以执行 findViewById(R.id.graph_content) 并获取所需的 LinearLayout保存旋转时的数据 在您的活动中,覆盖 onSaveInstanceState(),并将来自 getLatestReadings() 的数据保存到 bundle 中。
然后,在 onCreate 中:
if (savedInstanceState == null) {
  getLatestReadings();
} else {
  // Restore latest readings from savedInstanceState
}

有了这个,你可以让系统处理旋转,也就是从你的清单中移除这个:

 android:configChanges="keyboardHidden|orientation|screenSize" 

由于系统正在处理旋转,您不再需要拥有视图树观察器。而且您不必覆盖 onConfigurationChanged


谢谢您的建议,我已经按照它解决了我的问题,并清理了我的代码。唯一还没有做的是处理onSavedInstanceState方面,因为我需要将我的自定义对象(来自getLatestReadings())parcelabl,但这似乎是正确的方向。 - Josh Suckling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接