Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 201cbefe authored by Jorge Ruesga's avatar Jorge Ruesga Committed by Gerrit Code Review
Browse files

NotificationBar: Force DateView to collapse to gain space for clear_all_button

When DateFormat.getLongDateFormat() text is too long, the notification "clear_all_button" button
is hidden because DateView width. This change redesign the notification bar layout to force
DateView to collapse. This forces you to change the position of the buttons to the right.

Alternatives:

Patch 1: Align buttons (rotation and settings) to the right

Patch 2: Align buttons (rotation and settings) to the middle

Patch 3: Compute the text width of DateView to fit the maximum allowed by the status bar.
           * Calculate dinamicaly the width of the DateView to assign the maximum width
             when it fit in the screen, and stretch when not fit
           * Redesign the DateView widget. Now is a LinearLayout with 2 TextView's. This allow
             the use of ellipsize, because it is set to single line. Otherwise when the text is set
             the DateView don't show the ellipsize, although the view fit to the width.
Patch 4: Fix bug that in some circumstances ellipsize is not displayed

Change-Id: I2486c5e6b7d83a3c483519c17cdf57e90b50c79e
parent 4bec296b
Loading
Loading
Loading
Loading
+19 −16
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/notification_header_bg"
@@ -42,6 +41,9 @@
        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
        />

    <LinearLayout android:id="@+id/buttons_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <com.android.systemui.statusbar.RotationToggle android:id="@+id/rotation_lock_button"
            android:layout_width="32dp"
            android:layout_height="32dp"
@@ -58,6 +60,7 @@
            android:src="@drawable/ic_notify_quicksettings"
            android:contentDescription="@string/accessibility_settings_button"
            />
    </LinearLayout>

    <Space
        android:layout_width="0dp"
+132 −11
Original line number Diff line number Diff line
@@ -39,7 +39,9 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -53,6 +55,9 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextUtils.TruncateAt;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
@@ -96,6 +101,7 @@ import com.android.systemui.statusbar.RotationToggle;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.DateView;
import com.android.systemui.statusbar.policy.IntruderAlertView;
import com.android.systemui.statusbar.policy.LocationController;
@@ -195,6 +201,7 @@ public class PhoneStatusBar extends BaseStatusBar {
    boolean mNotificationPanelIsFullScreenWidth;

    // top bar
    View mButtonsBar;
    View mClearButton;
    View mSettingsButton;
    RotationToggle mRotationButton;
@@ -216,7 +223,8 @@ public class PhoneStatusBar extends BaseStatusBar {
    boolean mExpanded;
    boolean mExpandedVisible;

    // the date view
    // the clock and date view
    Clock mClockView;
    DateView mDateView;

    // for immersive activities
@@ -513,12 +521,50 @@ public class PhoneStatusBar extends BaseStatusBar {
        mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
        mClearButton.setOnClickListener(mClearButtonListener);
        mClearButton.setAlpha(0f);
        mClearButton.setVisibility(View.INVISIBLE);
        mClearButton.setVisibility(View.GONE);
        mClearButton.setEnabled(false);
        mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
        mDateView.getDate().addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                computeDateViewWidth();
            }
        });
        mClockView = (Clock)mStatusBarWindow.findViewById(R.id.clock);
        mClockView.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                computeDateViewWidth();
            }
        });
        mSettingsButton = mStatusBarWindow.findViewById(R.id.settings_button);
        mSettingsButton.setOnClickListener(mSettingsButtonListener);
        mRotationButton = (RotationToggle) mStatusBarWindow.findViewById(R.id.rotation_lock_button);
        mButtonsBar = mStatusBarWindow.findViewById(R.id.buttons_bar);

        // Compute the DateView width
        mDateView.post(new Runnable() {
            @Override
            public void run() {
                computeDateViewWidth();
            }
        });

        mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
        mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
@@ -1091,7 +1137,8 @@ public class PhoneStatusBar extends BaseStatusBar {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        if (mClearButton.getAlpha() <= 0.0f) {
                            mClearButton.setVisibility(View.INVISIBLE);
                            mClearButton.setVisibility(View.GONE);
                            computeDateViewWidth();
                        }
                    }

@@ -1099,6 +1146,7 @@ public class PhoneStatusBar extends BaseStatusBar {
                    public void onAnimationStart(Animator animation) {
                        if (mClearButton.getAlpha() <= 0.0f) {
                            mClearButton.setVisibility(View.VISIBLE);
                            computeDateViewWidth();
                        }
                    }
                });
@@ -1106,7 +1154,8 @@ public class PhoneStatusBar extends BaseStatusBar {
            }
        } else {
            mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
            mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
            mClearButton.setVisibility(clearable ? View.VISIBLE : View.GONE);
            computeDateViewWidth();
        }
        mClearButton.setEnabled(clearable);

@@ -1136,11 +1185,10 @@ public class PhoneStatusBar extends BaseStatusBar {
    public void showClock(boolean show) {
        if (mStatusBarView == null) return;
        ContentResolver resolver = mContext.getContentResolver();
        View clock = mStatusBarView.findViewById(R.id.clock);
        mShowClock = (Settings.System.getInt(resolver,
                Settings.System.STATUS_BAR_CLOCK, 1) == 1);
        if (clock != null) {
            clock.setVisibility(show ? (mShowClock ? View.VISIBLE : View.GONE) : View.GONE);
        if (mClockView != null) {
            mClockView.setVisibility(show ? (mShowClock ? View.VISIBLE : View.GONE) : View.GONE);
        }
    }

@@ -1592,6 +1640,9 @@ public class PhoneStatusBar extends BaseStatusBar {

        mCloseView.setPressed(true);

        // Compute the space of the DateView
        computeDateViewWidth();

        mTracking = true;
        setPileLayers(View.LAYER_TYPE_HARDWARE);
        mVelocityTracker = VelocityTracker.obtain();
@@ -1894,7 +1945,6 @@ public class PhoneStatusBar extends BaseStatusBar {
            final View signalText = mStatusBarView.findViewById(R.id.signal_cluster_text);
            final View battery = mStatusBarView.findViewById(R.id.battery);
            final View batteryText = mStatusBarView.findViewById(R.id.battery_text);
            final View clock = mStatusBarView.findViewById(R.id.clock);

            mLightsOutAnimation = new AnimatorSet();
            mLightsOutAnimation.playTogether(
@@ -1904,7 +1954,7 @@ public class PhoneStatusBar extends BaseStatusBar {
                    ObjectAnimator.ofFloat(signalText, View.ALPHA, 0),
                    ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
                    ObjectAnimator.ofFloat(batteryText, View.ALPHA, 0),
                    ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
                    ObjectAnimator.ofFloat(mClockView, View.ALPHA, 0.5f)
                );
            mLightsOutAnimation.setDuration(750);

@@ -1916,7 +1966,7 @@ public class PhoneStatusBar extends BaseStatusBar {
                    ObjectAnimator.ofFloat(signalText, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(batteryText, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
                    ObjectAnimator.ofFloat(mClockView, View.ALPHA, 1)
                );
            mLightsOnAnimation.setDuration(250);
        }
@@ -2450,6 +2500,7 @@ public class PhoneStatusBar extends BaseStatusBar {
                updateResources();
                repositionNavigationBar();
                updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
                computeDateViewWidth();
            }
        }
    };
@@ -2663,6 +2714,76 @@ public class PhoneStatusBar extends BaseStatusBar {
        return mExpanded || NavigationBarView.getEditMode() || (mDisabled & StatusBarManager.DISABLE_HOME) != 0;
    }

    private void computeDateViewWidth() {
        // Compute the max length that the DateView & buttons could have.
        try {
            // Ensure that all components are loaded
            if (mButtonsBar == null ||
                mClearButton == null ||
                mDateView == null ||
                mDateView.getDoW() == null ||
                mDateView.getDate() == null) {

                return;
            }

            // Obtain the screen width. StatusBar width is not valid on screen rotation
            // We need the real size, and status bar has the old width
            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            int width = size.x;

            // Retrieve the date of the DateView
            CharSequence date = mDateView.getDate().getText();
            if (date == null) {
                return;
            }

            // Get the width of the elements of the status bar
            int buttonsBarWidth = 0;
            if (mButtonsBar.getVisibility() != View.GONE) {
                buttonsBarWidth = mButtonsBar.getWidth();
            }
            int clearButtonWidth = 0;
            if (mClearButton.getVisibility() != View.GONE) {
                clearButtonWidth = mClearButton.getWidth();
            }

            // Create a temporary paint object for testing
            Paint mTestPaint = new Paint();
            mTestPaint.set(mDateView.getDate().getPaint());
            float dateViewWidth = mTestPaint.measureText(date.toString().toUpperCase());

            // Calculate DateView room width
            int maxRoomWidth = width - clearButtonWidth - buttonsBarWidth - mDateView.getLeft();

            // Compute the new width (if text fits in screen show all; otherwise stretch to fit)
            int newWidth = (int)dateViewWidth;
            if (maxRoomWidth < newWidth) {
                newWidth = maxRoomWidth;
            }
            mDateView.getLayoutParams().width = newWidth;
            mDateView.getDoW().getLayoutParams().width = newWidth;
            mDateView.getDate().getLayoutParams().width = newWidth;
            mDateView.measure(newWidth, mDateView.getHeight());

            if (DEBUG) {
                System.out.println(
                        String.format(
                                "width: %s, buttonsBarWidth: %s, clearButtonWidth: %s, " +
                                "dateViewWidth: %s, maxRoomWidth: %s, newWidth: %s",
                                width, buttonsBarWidth, clearButtonWidth,
                                dateViewWidth, maxRoomWidth, newWidth));
            }

         }catch (Exception ex) {
             // Audit
             Slog.e(TAG, "Problem computing the status bar DateView width.", ex);
         }
    }

    private static class FastColorDrawable extends Drawable {
        private final int mColor;

+52 −2
Original line number Diff line number Diff line
@@ -20,19 +20,25 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.text.TextUtils.TruncateAt;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.View;
import android.view.ViewParent;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.systemui.R;

import java.util.Date;

public final class DateView extends TextView {
public final class DateView extends LinearLayout {
    private static final String TAG = "DateView";

    private TextView mDoW;
    private TextView mDate;

    private boolean mAttachedToWindow;
    private boolean mWindowVisible;
    private boolean mUpdating;
@@ -52,6 +58,41 @@ public final class DateView extends TextView {

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

        // Layout params
        setOrientation(LinearLayout.VERTICAL);

        // Create the text views
        mDoW = new TextView(context, attrs);
        mDoW.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1.0f));
        mDoW.setSingleLine();
        mDoW.setEllipsize(TruncateAt.END);
        mDoW.setTextAppearance(context, R.style.TextAppearance_StatusBar_Expanded_Date);
        mDate = new TextView(context, attrs);
        mDate.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1.0f));
        mDate.setSingleLine();
        mDate.setEllipsize(TruncateAt.END);
        mDate.setTextAppearance(context, R.style.TextAppearance_StatusBar_Expanded_Date);

        // Extract how DoW and Date are distributed in the layout
        // The format is distributed as %1$s\n%2$s or %2$s\n%1$s but always in
        // two lines. Otherwise assume DoW = Top and Date = Bottom
        int positionDoW = 0;
        int positionDate = 1;
        try {
            String format = context.getString(R.string.status_bar_date_formatter);
            String[] positions = format.split("\n");
            if (positions.length == 2) {
                positionDoW = positions[0].indexOf("1") != -1 ? 0 : 1;
                positionDate = positions[1].indexOf("2") != -1 ? 1 : 0;
            }
        } catch (Exception ex) {
            Slog.w(TAG, "Error extracting DoW and Date positions", ex);
        }

        // Add the TextViews
        addView(positionDoW == 0 ? mDoW : mDate);
        addView(positionDate != 0 ? mDate : mDoW);
    }

    @Override
@@ -92,7 +133,16 @@ public final class DateView extends TextView {
        Date now = new Date();
        CharSequence dow = DateFormat.format("EEEE", now);
        CharSequence date = DateFormat.getLongDateFormat(context).format(now);
        setText(context.getString(R.string.status_bar_date_formatter, dow, date));
        mDoW.setText(dow);
        mDate.setText(date);
    }

    public final TextView getDoW() {
        return mDoW;
    }

    public final TextView getDate() {
        return mDate;
    }

    private boolean isVisible() {