Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-26246] Android: Added Ti.UI.Window "extendSafeArea", "safeAreaPadding", and inset/notch support #10383

Merged
merged 9 commits into from
Oct 25, 2018
3 changes: 1 addition & 2 deletions android/modules/ui/res/layout/titanium_ui_drawer_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:fitsSystemWindows="true"/>
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

<org.appcelerator.titanium.view.TiCompositeLayout
android:layout_width="match_parent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,11 @@ private void fillIntent(Activity activity, Intent intent)
TiConvert.toInt(getProperty(TiC.PROPERTY_WINDOW_SOFT_INPUT_MODE), -1));
}

if (hasProperty(TiC.PROPERTY_EXTEND_SAFE_AREA)) {
boolean value = TiConvert.toBoolean(getProperty(TiC.PROPERTY_EXTEND_SAFE_AREA), false);
intent.putExtra(TiC.PROPERTY_EXTEND_SAFE_AREA, value);
}

if (hasProperty(TiC.PROPERTY_EXIT_ON_CLOSE)) {
intent.putExtra(TiC.INTENT_PROPERTY_FINISH_ROOT,
TiConvert.toBoolean(getProperty(TiC.PROPERTY_EXIT_ON_CLOSE), false));
Expand Down Expand Up @@ -604,6 +609,33 @@ protected AppCompatActivity getWindowActivity()
return (tabGroupActivity != null) ? tabGroupActivity.get() : null;
}

public void fireSafeAreaChangedEvent()
{
// First, fire the event for this TabGroup.
super.fireSafeAreaChangedEvent();

// Create a shallow copy of the tab proxy collection owned by this TabGroup.
// We need to do this since a tab's event handler can remove a tab, which would break iteration.
ArrayList<TabProxy> clonedTabs = null;
synchronized (this.tabs)
{
clonedTabs = (ArrayList<TabProxy>) this.tabs.clone();
}
if (clonedTabs == null) {
return;
}

// Fire a safe-area change event for each tab window.
for (TabProxy tab : clonedTabs) {
if (tab != null) {
TiWindowProxy window = tab.getWindow();
if (window != null) {
window.fireSafeAreaChangedEvent();
}
}
}
}

@Override
public String getApiName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ private void fillIntent(Activity activity, Intent intent)
intent.putExtra(TiC.PROPERTY_WINDOW_PIXEL_FORMAT,
TiConvert.toInt(getProperty(TiC.PROPERTY_WINDOW_PIXEL_FORMAT), PixelFormat.UNKNOWN));
}
if (hasProperty(TiC.PROPERTY_EXTEND_SAFE_AREA)) {
boolean value = TiConvert.toBoolean(getProperty(TiC.PROPERTY_EXTEND_SAFE_AREA), false);
intent.putExtra(TiC.PROPERTY_EXTEND_SAFE_AREA, value);
}

// Set the theme property
if (hasProperty(TiC.PROPERTY_THEME)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public class AndroidModule extends KrollModule
{
private static final String TAG = "UIAndroidModule";

@Kroll.constant
public static final int FLAG_TRANSLUCENT_NAVIGATION = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
@Kroll.constant
public static final int FLAG_TRANSLUCENT_STATUS = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;

@Kroll.constant
public static final int PIXEL_FORMAT_A_8 = PixelFormat.A_8;
@Kroll.constant
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ti.modules.titanium.ui.widget;

import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
Expand All @@ -18,7 +20,9 @@
import org.appcelerator.titanium.TiDimension;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiColorHelper;
import org.appcelerator.titanium.view.TiCompositeLayout;
import org.appcelerator.titanium.view.TiDrawableReference;
import org.appcelerator.titanium.view.TiToolbarStyleHandler;
import org.appcelerator.titanium.view.TiUIView;

public class TiToolbar extends TiUIView implements Handler.Callback
Expand Down Expand Up @@ -66,7 +70,53 @@ public class TiToolbar extends TiUIView implements Handler.Callback
public TiToolbar(TiViewProxy proxy)
{
super(proxy);
toolbar = new Toolbar(proxy.getActivity());
toolbar = new Toolbar(proxy.getActivity()) {
@Override
protected void onConfigurationChanged(Configuration newConfig)
{
// If auto-sized, then resize toolbar height and font size to what's defined in XML.
// Note: Typically, the default height is 56dp in portrait and 48dp in landscape.
TiCompositeLayout.LayoutParams params = TiToolbar.this.getLayoutParams();
boolean isAutoSized = (params != null) ? params.hasAutoSizedHeight() : true;
if (isAutoSized) {
TiToolbarStyleHandler styleHandler = new TiToolbarStyleHandler(this);
styleHandler.onConfigurationChanged(newConfig);
}
super.onConfigurationChanged(newConfig);
}

@Override
protected boolean fitSystemWindows(Rect insets)
{
// Do custom inset handling if "extendBackground" was applied to toolbar.
if ((insets != null) && getFitsSystemWindows()) {
// Determine if we need to pad the top or bottom based on toolbar's y-axis position.
boolean isPaddingTop = true;
TiCompositeLayout.LayoutParams params = TiToolbar.this.getLayoutParams();
if (params != null) {
if ((params.optionTop == null) && (params.optionCenterY == null)) {
if ((params.optionBottom != null) && (params.optionBottom.getAsPixels(this) <= 0)) {
// Toolbar is docked to the bottom of the view. So, pad the bottom instead.
isPaddingTop = false;
}
}
}

// Create a new insets object with either the top or bottom inset padding stripped off.
// Note: We never want the toolbar to pad both the top and bottom.
// Especially when toolbar is docked to top of view but using a translucent navigation bar.
insets = new Rect(insets);
if (isPaddingTop) {
insets.bottom = 0;
} else {
insets.top = 0;
}
}

// Apply the insets to the toolbar. (Google blindly pads view based on these insets.)
return super.fitSystemWindows(insets);
}
};
setNativeView(toolbar);
}

Expand Down Expand Up @@ -131,27 +181,15 @@ private void handleBackgroundExtended()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = TiApplication.getAppCurrentActivity().getWindow();
//Compensate for status bar's height
// Compensate for status bar's height
toolbar.setFitsSystemWindows(true);
//Set flags for the current window that allow drawing behind status bar
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.setStatusBarColor(Color.TRANSPARENT);
}
}

/**
* Calculates the Status Bar's height depending on the device
* @return The status bar's height. 0 if the API level does not have status_bar_height resource
*/
private int calculateStatusBarHeight()
{
int resourceId =
TiApplication.getAppCurrentActivity().getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return TiApplication.getAppCurrentActivity().getResources().getDimensionPixelSize(resourceId);
// Set flags for the current window that allow drawing behind status bar
int flags = window.getDecorView().getSystemUiVisibility();
flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
window.getDecorView().setSystemUiVisibility(flags);
window.setStatusBarColor(Color.TRANSPARENT);
}
return 0;
}

/**
Expand Down