Reputation: 373
Good day. I created fully custom view for notification. But on different devices left (start) margin different.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:orientation="vertical"
android:layout_marginEnd="@dimen/notificationContentInsert"
android:layout_marginStart="@dimen/notificationContentInsert"
>
where notificationContentInsert is 16dp in values/dimens.xml
F.e.
On my OnePlus 6 (1080 x 2280) with 16dp marginStart all notifications (include system notifications and others like gmail) has same start margin and looks fine.
But on Samsung Tab A (9.7", 1024x768) 16dp looks smaller than another notifications.
Also i tried to use sdk attribute android:dimen/notification_content_margin_start but this attribute is private and i obtain compile exception AAPT: error: resource android:dimen/notification_content_margin_start is private.
Is there way to get device specified notification content padding? Thanks
Upvotes: 4
Views: 1986
Reputation: 2126
Adding static margins or paddings can bring up issues when your app is running in Android 12.
If the targetSdkVersion
is less than 31, you will still get to use the full notification area for your customizable notifications.
If you add padding in the layout file and you change the targetSdkVersion to 31, the notification will look weird in Android 12 devices. This becomes a pain if you are building an sdk that has notification capabilities in it. I had a similar situation and decided to add padding after checking the targetSdkVersion
programmatically.
ApplicationInfo info = context.getApplicationInfo();
if (info.targetSdkVersion < Build.VERSION_CODES.S) {
int dp16 = Utils.dpToPx(16, context);
remoteViews.setViewPadding(R.id.notification_container, dp16, dp16, dp16, dp16);
}
Where R.id.notification_container
is the root view of my custom notification's layout.
The value 16 looks good to me. But, please let me know if there are better ways to obtain the value from the OS without having to call Resource.getIdentifier()
method.
Upvotes: 4
Reputation: 3513
I know this is an old question, but the solution is simple. Instead of using margins, we will use padding in the parent view, and then we will get the amount and set the padding in code. We will start with a default value, in case the code fails.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/notify_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingTop="0dp"
android:paddingRight="16dp"
android:paddingBottom="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
Then in code we will use Resources.getIdentifier()
to get the value. We soround it with try/catch, so in worst case, it uses the default. Here is the code:
RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.my_notification_content_layout);
try {
// We are assuming start and end are same. If we want to be nitty, we will get them separately, and then check which to use for left and which for righht.
int identifier = context.getResources().getIdentifier("notification_content_margin_start", "dimen", "android");
if (identifier != 0) {
int padding = context.getResources().getDimensionPixelSize(identifier);
contentView.setViewPadding(R.id.notify_layout, padding, 0, padding, 0);
Log.d("setViewPadding", "Setting padding to: " + padding);
} else {
Log.d("setViewPadding", "Failed to find padding");
}
} catch (Exception e) {
Log.d("setViewPadding", "Failed to set padding");
}
This code was tested, and seems to work well. We have to use padding, as there is no setMargins function for RemoteViews.
Enjoy, Lionscribe
Upvotes: 2
Reputation: 82
No need to set any margin and padding to the layout. Apply NotificationCompat.DecoratedCustomViewStyle to your notification with setStyle method as below. This API allows you to provide a custom layout for the content area normally occupied by the title and text content, while still using system decorations for the notification icon, timestamp, sub-text, and action buttons.
android.support.v4.app.NotificationCompat.Builder nBuilder = new
android.support.v4.app.NotificationCompat.Builder(parent);
nBuilder.setContentTitle("Your title")
.setSmallIcon(R.drawable.ic_launcher)
. // add your other settings
.
.setStyle(new NotificationCompat.DecoratedCustomViewStyle()); //this makes your notification similar to other system notifications
Upvotes: 1