1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.widget;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.util.AttributeSet;
22import android.util.DisplayMetrics;
23import android.widget.LinearLayout;
24
25import static android.view.View.MeasureSpec.*;
26import static com.android.internal.R.*;
27
28/**
29 * A special layout when measured in AT_MOST will take up a given percentage of
30 * the available space.
31 */
32public class WeightedLinearLayout extends LinearLayout {
33    private float mMajorWeightMin;
34    private float mMinorWeightMin;
35    private float mMajorWeightMax;
36    private float mMinorWeightMax;
37
38    public WeightedLinearLayout(Context context) {
39        super(context);
40    }
41
42    public WeightedLinearLayout(Context context, AttributeSet attrs) {
43        super(context, attrs);
44
45        TypedArray a =
46            context.obtainStyledAttributes(attrs, styleable.WeightedLinearLayout);
47
48        mMajorWeightMin = a.getFloat(styleable.WeightedLinearLayout_majorWeightMin, 0.0f);
49        mMinorWeightMin = a.getFloat(styleable.WeightedLinearLayout_minorWeightMin, 0.0f);
50        mMajorWeightMax = a.getFloat(styleable.WeightedLinearLayout_majorWeightMax, 0.0f);
51        mMinorWeightMax = a.getFloat(styleable.WeightedLinearLayout_minorWeightMax, 0.0f);
52
53        a.recycle();
54    }
55
56    @Override
57    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
58        final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
59        final int screenWidth = metrics.widthPixels;
60        final boolean isPortrait = screenWidth < metrics.heightPixels;
61
62        final int widthMode = getMode(widthMeasureSpec);
63
64        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
65
66        int width = getMeasuredWidth();
67        boolean measure = false;
68
69        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY);
70
71        final float widthWeightMin = isPortrait ? mMinorWeightMin : mMajorWeightMin;
72        final float widthWeightMax = isPortrait ? mMinorWeightMax : mMajorWeightMax;
73        if (widthMode == AT_MOST) {
74            final int weightedMin = (int) (screenWidth * widthWeightMin);
75            final int weightedMax = (int) (screenWidth * widthWeightMin);
76            if (widthWeightMin > 0.0f && width < weightedMin) {
77                widthMeasureSpec = MeasureSpec.makeMeasureSpec(weightedMin, EXACTLY);
78                measure = true;
79            } else if (widthWeightMax > 0.0f && width > weightedMax) {
80                widthMeasureSpec = MeasureSpec.makeMeasureSpec(weightedMax, EXACTLY);
81                measure = true;
82            }
83        }
84
85        // TODO: Support height?
86
87        if (measure) {
88            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
89        }
90    }
91}
92