Leos Literak
Leos Literak

Reputation: 9474

Android - calculate dimensions from activity before measurement

My activity shall have a screen divided into two sections. The first will hold custom view that occupies as much space as possible. The second section holds matrix of buttons. I do not their number at design time, I want to create them in Activity based on screen size and other conditions (easy level will have less buttons).

enter image description here

I currently use LinearLayout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:id="@+id/puzzleScreen"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <lelisoft.com.lelimath.view.TilesView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tiles" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/choices">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="6"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="23"/>
    </LinearLayout>
</LinearLayout>

TilesView had consumed complete screen until I overriden onMeasure(). To continue I have to calculate available space, number of buttons and divide space between both sections and pass this information to TilesView and LayoutManagers. Unfortunatelly onCreate() is not correct location for this calculation as I cannot figure out dimensions of root view (getters return 0).

Where is the correct place in Activity lifecycle where to get dimensions and create all buttons dynamically? It seems to me like chicken-egg problem.

UPDATE

I tried to debug other methods: onStart() and onResume() return 0, then measurement is called and finally onCreateOptionsMenu() receives coordinates. Too late.

UPDATE 2

The question is how to find dimensions of the contentView from Activity before measurement. I can get getWindowManager().getDefaultDisplay(), but it contains action bar etc.

protected void onCreate(Bundle state) {
    super.onCreate(state);
    setContentView(R.layout.activity_puzzle);
    View puzzleView = findViewById(R.id.puzzleScreen);
    // todo get maximum width and height for R.layout.activity_puzzle

Upvotes: 1

Views: 128

Answers (2)

Tin Tran
Tin Tran

Reputation: 2285

Do you know exactly how many rows the bottom matrix has?

You could set the android:layout_weight="1" and android:layout_height="0px" to tell the ViewGroup that your customView will occupy all the remaining space excluding the Button Matrix.

Upvotes: 1

Wangze Ze
Wangze Ze

Reputation: 21

For your first question:

In onCreate() lifeCycle ,you can not get the dimensions. Because your the all view have not measured()!

I always use view.post() to get the dimension() in onCreate() method;

 view.post(new Runnable() {
        @Override
        public void run() {
            view.getMeasuredHeight();
        }
    });

For your second question:

On the bottom section,I think you should use custom view extends ViewGroup.Override constructor、onMeasure()、onLayout():

public class TextBlocksView extends ViewGroup {}

In constructor, you add LinearLayout(orientation:horizontal) as much as Line Number,and add each item(addView() method and layoutParams weight 1!!) ....

public TextBlocksView(Context context, AttributeSet attrs) {
    super(context, attrs);

    this.removeAllViews();
    .....
    this.addView(linearLayoutView);
}

In onMeasure(), you calculate your dimensions in this place.(Tips:pay attention to dipToPx method!)

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    View childAt = this.getChildAt(0);
    int measuredHeight = childAt.getMeasuredHeight();
    int measuredWidth = childAt.getMeasuredWidth();
    childAt.layout(left, top, right, bottom);
    .......
}

in onLayout(),you place your Line item(LinearLayout orientation:horizontal)!

On the top section. you can use the same way!

My mother tongue is chinese,i am not good at english. Hope some guys edit my answer correctly! Thanks a lot.

Upvotes: 1

Related Questions