Use VectorDrawableCompat compatible ways of setting drawables programmatically

so they won't crash on API < 21
This commit is contained in:
Torsten Grote
2021-01-21 15:44:56 -03:00
parent c93e5441b0
commit 94dd75f24b
9 changed files with 36 additions and 40 deletions

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.android.conversation;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.transition.Slide; import android.transition.Slide;
@@ -105,6 +106,7 @@ import androidx.recyclerview.selection.SelectionTracker.SelectionObserver;
import androidx.recyclerview.selection.StorageStrategy; import androidx.recyclerview.selection.StorageStrategy;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import de.hdodenhof.circleimageview.CircleImageView; import de.hdodenhof.circleimageview.CircleImageView;
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt; import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
@@ -479,12 +481,10 @@ public class ConversationActivity extends BriarActivity
@UiThread @UiThread
private void displayContactOnlineStatus() { private void displayContactOnlineStatus() {
if (connectionRegistry.isConnected(contactId)) { if (connectionRegistry.isConnected(contactId)) {
toolbarStatus.setImageDrawable(ContextCompat.getDrawable( toolbarStatus.setImageResource(R.drawable.contact_online);
ConversationActivity.this, R.drawable.contact_online));
toolbarStatus.setContentDescription(getString(R.string.online)); toolbarStatus.setContentDescription(getString(R.string.online));
} else { } else {
toolbarStatus.setImageDrawable(ContextCompat.getDrawable( toolbarStatus.setImageResource(R.drawable.contact_offline);
ConversationActivity.this, R.drawable.contact_offline));
toolbarStatus.setContentDescription(getString(R.string.offline)); toolbarStatus.setContentDescription(getString(R.string.offline));
} }
} }
@@ -935,13 +935,16 @@ public class ConversationActivity extends BriarActivity
return; return;
} }
int color =
ContextCompat.getColor(this, R.color.briar_primary);
Drawable drawable = VectorDrawableCompat
.create(getResources(), R.drawable.ic_more_vert_accent, null);
new MaterialTapTargetPrompt.Builder(ConversationActivity.this, new MaterialTapTargetPrompt.Builder(ConversationActivity.this,
R.style.OnboardingDialogTheme).setTarget(target) R.style.OnboardingDialogTheme).setTarget(target)
.setPrimaryText(R.string.introduction_onboarding_title) .setPrimaryText(R.string.introduction_onboarding_title)
.setSecondaryText(R.string.introduction_onboarding_text) .setSecondaryText(R.string.introduction_onboarding_text)
.setIcon(R.drawable.ic_more_vert_accent) .setIconDrawable(drawable)
.setBackgroundColour( .setBackgroundColour(color)
ContextCompat.getColor(this, R.color.briar_primary))
.show(); .show();
} }

View File

@@ -1,17 +1,13 @@
package org.briarproject.briar.android.login; package org.briarproject.briar.android.login;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import static androidx.core.content.ContextCompat.getColor; import static org.briarproject.briar.android.util.UiUtils.getDialogIcon;
import static androidx.core.content.ContextCompat.getDrawable;
import static androidx.core.graphics.drawable.DrawableCompat.setTint;
import static java.util.Objects.requireNonNull;
@NotNullByDefault @NotNullByDefault
class LoginUtils { class LoginUtils {
@@ -19,9 +15,7 @@ class LoginUtils {
static AlertDialog createKeyStrengthenerErrorDialog(Context ctx) { static AlertDialog createKeyStrengthenerErrorDialog(Context ctx) {
AlertDialog.Builder builder = AlertDialog.Builder builder =
new AlertDialog.Builder(ctx, R.style.BriarDialogTheme); new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
Drawable icon = getDrawable(ctx, R.drawable.alerts_and_states_error); builder.setIcon(getDialogIcon(ctx, R.drawable.alerts_and_states_error));
setTint(requireNonNull(icon), getColor(ctx, R.color.color_primary));
builder.setIcon(icon);
builder.setTitle(R.string.dialog_title_cannot_check_password); builder.setTitle(R.string.dialog_title_cannot_check_password);
builder.setMessage(R.string.dialog_message_cannot_check_password); builder.setMessage(R.string.dialog_message_cannot_check_password);
builder.setPositiveButton(R.string.ok, null); builder.setPositiveButton(R.string.ok, null);

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.navdrawer;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -59,6 +60,7 @@ import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt; import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
import static android.view.View.GONE; import static android.view.View.GONE;
@@ -433,8 +435,7 @@ public class NavDrawerActivity extends BriarActivity implements
Transport t = getItem(position); Transport t = getItem(position);
ImageView icon = view.findViewById(R.id.imageView); ImageView icon = view.findViewById(R.id.imageView);
icon.setImageDrawable(ContextCompat.getDrawable( icon.setImageResource(t.iconDrawable);
NavDrawerActivity.this, t.iconDrawable));
icon.setColorFilter(ContextCompat.getColor( icon.setColorFilter(ContextCompat.getColor(
NavDrawerActivity.this, t.iconColor)); NavDrawerActivity.this, t.iconColor));
@@ -476,11 +477,13 @@ public class NavDrawerActivity extends BriarActivity implements
private void showTransportsOnboarding(boolean show, ImageView imageView) { private void showTransportsOnboarding(boolean show, ImageView imageView) {
if (show) { if (show) {
int color = resolveColorAttribute(this, R.attr.colorControlNormal); int color = resolveColorAttribute(this, R.attr.colorControlNormal);
Drawable drawable = VectorDrawableCompat
.create(getResources(), R.drawable.transport_tor, null);
new MaterialTapTargetPrompt.Builder(NavDrawerActivity.this, new MaterialTapTargetPrompt.Builder(NavDrawerActivity.this,
R.style.OnboardingDialogTheme).setTarget(imageView) R.style.OnboardingDialogTheme).setTarget(imageView)
.setPrimaryText(R.string.network_settings_title) .setPrimaryText(R.string.network_settings_title)
.setSecondaryText(R.string.transports_onboarding_text) .setSecondaryText(R.string.transports_onboarding_text)
.setIcon(R.drawable.transport_tor) .setIconDrawable(drawable)
.setIconDrawableColourFilter(color) .setIconDrawableColourFilter(color)
.setBackgroundColour( .setBackgroundColour(
ContextCompat.getColor(this, R.color.briar_primary)) ContextCompat.getColor(this, R.color.briar_primary))

View File

@@ -141,8 +141,7 @@ public class TransportsActivity extends BriarActivity {
Transport t = getItem(position); Transport t = getItem(position);
ImageView icon = view.findViewById(R.id.icon); ImageView icon = view.findViewById(R.id.icon);
icon.setImageDrawable(ContextCompat.getDrawable( icon.setImageResource(t.iconDrawable);
TransportsActivity.this, t.iconDrawable));
icon.setColorFilter(ContextCompat.getColor( icon.setColorFilter(ContextCompat.getColor(
TransportsActivity.this, t.iconColor)); TransportsActivity.this, t.iconColor));

View File

@@ -54,6 +54,7 @@ import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Context.POWER_SERVICE; import static android.content.Context.POWER_SERVICE;
@@ -88,7 +89,6 @@ import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES;
import static androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode; import static androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode;
import static androidx.core.content.ContextCompat.getColor; import static androidx.core.content.ContextCompat.getColor;
import static androidx.core.content.ContextCompat.getDrawable;
import static androidx.core.content.ContextCompat.getSystemService; import static androidx.core.content.ContextCompat.getSystemService;
import static androidx.core.graphics.drawable.DrawableCompat.setTint; import static androidx.core.graphics.drawable.DrawableCompat.setTint;
import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_RTL; import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_RTL;
@@ -436,7 +436,8 @@ public class UiUtils {
} }
public static Drawable getDialogIcon(Context ctx, @DrawableRes int resId) { public static Drawable getDialogIcon(Context ctx, @DrawableRes int resId) {
Drawable icon = getDrawable(ctx, resId); Drawable icon =
VectorDrawableCompat.create(ctx.getResources(), resId, null);
setTint(requireNonNull(icon), getColor(ctx, R.color.color_primary)); setTint(requireNonNull(icon), getColor(ctx, R.color.color_primary));
return icon; return icon;
} }

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.android.view;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.AttributeSet; import android.util.AttributeSet;
@@ -53,9 +52,8 @@ public class BriarRecyclerView extends FrameLayout {
R.styleable.BriarRecyclerView); R.styleable.BriarRecyclerView);
isScrollingToEnd = attributes isScrollingToEnd = attributes
.getBoolean(R.styleable.BriarRecyclerView_scrollToEnd, true); .getBoolean(R.styleable.BriarRecyclerView_scrollToEnd, true);
Drawable drawable = attributes int drawableRes = attributes.getResourceId(R.styleable.BriarRecyclerView_emptyImage, -1);
.getDrawable(R.styleable.BriarRecyclerView_emptyImage); if (drawableRes != -1) setEmptyImage(drawableRes);
if (drawable != null) setEmptyImage(drawable);
String emtpyText = String emtpyText =
attributes.getString(R.styleable.BriarRecyclerView_emptyText); attributes.getString(R.styleable.BriarRecyclerView_emptyText);
if (emtpyText != null) setEmptyText(emtpyText); if (emtpyText != null) setEmptyText(emtpyText);
@@ -139,11 +137,6 @@ public class BriarRecyclerView extends FrameLayout {
} }
} }
public void setEmptyImage(Drawable drawable) {
if (recyclerView == null) initViews();
emptyImage.setImageDrawable(drawable);
}
public void setEmptyImage(@DrawableRes int res) { public void setEmptyImage(@DrawableRes int res) {
if (recyclerView == null) initViews(); if (recyclerView == null) initViews();
emptyImage.setImageResource(res); emptyImage.setImageResource(res);

View File

@@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.ClipData; import android.content.ClipData;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
@@ -28,6 +29,7 @@ import androidx.customview.view.AbsSavedState;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt; import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
@@ -253,12 +255,14 @@ public class TextAttachmentController extends TextSendController
public void showImageOnboarding(Activity activity) { public void showImageOnboarding(Activity activity) {
int color = resolveColorAttribute(activity, R.attr.colorControlNormal); int color = resolveColorAttribute(activity, R.attr.colorControlNormal);
Drawable drawable = VectorDrawableCompat
.create(activity.getResources(), R.drawable.ic_image, null);
new MaterialTapTargetPrompt.Builder(activity, new MaterialTapTargetPrompt.Builder(activity,
R.style.OnboardingDialogTheme).setTarget(sendButton) R.style.OnboardingDialogTheme).setTarget(sendButton)
.setPrimaryText(R.string.dialog_title_image_support) .setPrimaryText(R.string.dialog_title_image_support)
.setSecondaryText(R.string.dialog_message_image_support) .setSecondaryText(R.string.dialog_message_image_support)
.setBackgroundColour(getColor(activity, R.color.briar_primary)) .setBackgroundColour(getColor(activity, R.color.briar_primary))
.setIcon(R.drawable.ic_image) .setIconDrawable(drawable)
.setIconDrawableColourFilter(color) .setIconDrawableColourFilter(color)
.show(); .show();
} }

View File

@@ -8,7 +8,6 @@ import org.briarproject.briar.R;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.content.ContextCompat;
@UiThread @UiThread
public class TrustIndicatorView extends AppCompatImageView { public class TrustIndicatorView extends AppCompatImageView {
@@ -44,7 +43,7 @@ public class TrustIndicatorView extends AppCompatImageView {
default: default:
res = R.drawable.trust_indicator_unknown; res = R.drawable.trust_indicator_unknown;
} }
setImageDrawable(ContextCompat.getDrawable(getContext(), res)); setImageResource(res);
setVisibility(VISIBLE); setVisibility(VISIBLE);
invalidate(); invalidate();

View File

@@ -123,11 +123,11 @@
style="@style/BriarButtonFlat.Positive.Tiny" style="@style/BriarButtonFlat.Positive.Tiny"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_content_copy"
android:drawableLeft="@drawable/ic_content_copy"
android:drawablePadding="8dp" android:drawablePadding="8dp"
android:enabled="false" android:enabled="false"
android:text="@string/copy_button" android:text="@string/copy_button"
app:drawableLeftCompat="@drawable/ic_content_copy"
app:drawableStartCompat="@drawable/ic_content_copy"
app:layout_constraintEnd_toStartOf="@id/shareButton" app:layout_constraintEnd_toStartOf="@id/shareButton"
app:layout_constraintHorizontal_bias="1.0" app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_chainStyle="packed"
@@ -139,11 +139,11 @@
style="@style/BriarButtonFlat.Positive.Tiny" style="@style/BriarButtonFlat.Positive.Tiny"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawableStart="@drawable/social_share_blue"
android:drawableLeft="@drawable/social_share_blue"
android:drawablePadding="8dp" android:drawablePadding="8dp"
android:enabled="false" android:enabled="false"
android:text="@string/share_button" android:text="@string/share_button"
app:drawableLeftCompat="@drawable/social_share_blue"
app:drawableStartCompat="@drawable/social_share_blue"
app:layout_constraintBottom_toBottomOf="@id/copyButton" app:layout_constraintBottom_toBottomOf="@id/copyButton"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0" app:layout_constraintHorizontal_bias="1.0"
@@ -202,10 +202,10 @@
style="@style/BriarButtonFlat.Positive.Tiny" style="@style/BriarButtonFlat.Positive.Tiny"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_content_paste"
android:drawableLeft="@drawable/ic_content_paste"
android:drawablePadding="8dp" android:drawablePadding="8dp"
android:text="@string/paste_button" android:text="@string/paste_button"
app:drawableLeftCompat="@drawable/ic_content_paste"
app:drawableStartCompat="@drawable/ic_content_paste"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0" app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"