Replace CardView usages with MaterialCardView.

main
Alex Hart 2023-03-08 14:55:19 -04:00
rodzic f1c2ee9b32
commit 2d3e8ef31c
37 zmienionych plików z 272 dodań i 76 usunięć

Wyświetl plik

@ -440,7 +440,6 @@ dependencies {
implementation libs.androidx.recyclerview
implementation libs.material.material
implementation libs.androidx.legacy.support
implementation libs.androidx.cardview
implementation libs.androidx.preference
implementation libs.androidx.legacy.preference
implementation libs.androidx.gridlayout

Wyświetl plik

@ -6,8 +6,8 @@ import android.graphics.Path
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import androidx.cardview.widget.CardView
import androidx.core.graphics.withClip
import com.google.android.material.card.MaterialCardView
/**
* Adds manual clipping around the card. This ensures that software rendering
@ -16,7 +16,7 @@ import androidx.core.graphics.withClip
class ClippedCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : CardView(context, attrs) {
) : MaterialCardView(context, attrs) {
private val bounds = Rect()
private val boundsF = RectF()

Wyświetl plik

@ -28,7 +28,7 @@ import kotlin.jvm.functions.Function2;
* fill the bounds with a gradient.
*
* If you wish to apply clipping to this drawable, it is recommended to either use it with
* a CardView or utilize {@link org.thoughtcrime.securesms.util.CustomDrawWrapperKt#customizeOnDraw(Drawable, Function2)}
* a MaterialCardView or utilize {@link org.thoughtcrime.securesms.util.CustomDrawWrapperKt#customizeOnDraw(Drawable, Function2)}
*/
public final class RotatableGradientDrawable extends Drawable {

Wyświetl plik

@ -7,10 +7,10 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import com.google.android.flexbox.AlignItems;
import com.google.android.flexbox.FlexboxLayout;
import com.google.android.material.card.MaterialCardView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.events.CallParticipant;
@ -116,7 +116,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
private void update(int index, int count, @NonNull CallParticipant participant) {
View view = getChildAt(index);
CardView cardView = view.findViewById(R.id.group_call_participant_card_wrapper);
MaterialCardView cardView = view.findViewById(R.id.group_call_participant_card_wrapper);
CallParticipantView callParticipantView = view.findViewById(R.id.group_call_participant);
callParticipantView.setCallParticipant(participant);

Wyświetl plik

@ -29,7 +29,6 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
@ -39,6 +38,7 @@ import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.card.MaterialCardView;
import org.signal.core.util.Stopwatch;
import org.signal.core.util.logging.Log;
@ -360,9 +360,9 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
}
private void initializeViewFinderAndControlsPositioning() {
CardView cameraCard = requireView().findViewById(R.id.camera_preview_parent);
View controls = requireView().findViewById(R.id.camera_controls_container);
CameraDisplay cameraDisplay = CameraDisplay.getDisplay(requireActivity());
MaterialCardView cameraCard = requireView().findViewById(R.id.camera_preview_parent);
View controls = requireView().findViewById(R.id.camera_controls_container);
CameraDisplay cameraDisplay = CameraDisplay.getDisplay(requireActivity());
if (!cameraDisplay.getRoundViewFinderCorners()) {
cameraCard.setRadius(0f);

Wyświetl plik

@ -26,7 +26,6 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
@ -35,13 +34,13 @@ import androidx.camera.view.CameraController;
import androidx.camera.view.LifecycleCameraController;
import androidx.camera.view.PreviewView;
import androidx.camera.view.video.ExperimentalVideo;
import androidx.cardview.widget.CardView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.util.Executors;
import com.google.android.material.card.MaterialCardView;
import org.signal.core.util.Stopwatch;
import org.signal.core.util.concurrent.SimpleTask;
@ -293,9 +292,9 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
}
private void initializeViewFinderAndControlsPositioning() {
CardView cameraCard = requireView().findViewById(R.id.camerax_camera_parent);
View controls = requireView().findViewById(R.id.camerax_controls_container);
CameraDisplay cameraDisplay = CameraDisplay.getDisplay(requireActivity());
MaterialCardView cameraCard = requireView().findViewById(R.id.camerax_camera_parent);
View controls = requireView().findViewById(R.id.camerax_controls_container);
CameraDisplay cameraDisplay = CameraDisplay.getDisplay(requireActivity());
if (!cameraDisplay.getRoundViewFinderCorners()) {
cameraCard.setRadius(0f);

Wyświetl plik

@ -18,7 +18,6 @@ import android.view.View
import android.view.animation.Interpolator
import android.widget.FrameLayout
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
@ -30,6 +29,7 @@ import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
import com.google.android.material.progressindicator.CircularProgressIndicatorSpec
import com.google.android.material.progressindicator.IndeterminateDrawable
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
@ -176,7 +176,7 @@ class StoryViewerPageFragment :
val moreButton: View = view.findViewById(R.id.more)
val distributionList: TextView = view.findViewById(R.id.distribution_list)
val cardWrapper: TouchInterceptingFrameLayout = view.findViewById(R.id.story_content_card_touch_interceptor)
val card: CardView = view.findViewById(R.id.story_content_card)
val card: MaterialCardView = view.findViewById(R.id.story_content_card)
val caption: TextView = view.findViewById(R.id.story_caption)
val largeCaption: TextView = view.findViewById(R.id.story_large_caption)
val largeCaptionOverlay: View = view.findViewById(R.id.story_large_caption_overlay)
@ -610,7 +610,7 @@ class StoryViewerPageFragment :
private fun adjustConstraintsForScreenDimensions(
viewsAndReplies: View,
cardWrapper: View,
card: CardView
card: MaterialCardView
) {
val constraintSet = ConstraintSet()
constraintSet.clone(storyPageContainer)

Wyświetl plik

@ -6,11 +6,11 @@ import android.graphics.drawable.Drawable
import android.net.Uri
import android.util.AttributeSet
import android.widget.ImageView
import androidx.cardview.widget.CardView
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.google.android.material.card.MaterialCardView
import org.signal.core.util.DimensionUnit
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.animation.transitions.CrossfaderTransition
@ -24,7 +24,7 @@ import kotlin.reflect.KProperty
class StoriesSharedElementCrossFaderView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : CardView(context, attrs), CrossfaderTransition.Crossfadeable {
) : MaterialCardView(context, attrs), CrossfaderTransition.Crossfadeable {
companion object {
val CORNER_RADIUS_START = DimensionUnit.DP.toPixels(12f)

Wyświetl plik

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/camera_preview_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -19,7 +19,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<FrameLayout
android:id="@+id/camera_controls_container"

Wyświetl plik

@ -6,7 +6,7 @@
android:layout_height="match_parent"
tools:viewBindingIgnore="true">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/camerax_camera_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -20,7 +20,7 @@
android:layout_height="match_parent"
android:layout_gravity="top"
app:implementationMode="compatible" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<FrameLayout
android:id="@+id/camerax_controls_container"

Wyświetl plik

@ -117,7 +117,7 @@
app:barrierDirection="end"
app:constraint_referenced_ids="typing_avatar_1, typing_avatar_2, typing_avatar_3, typing_count" />
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/indicator_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -143,6 +143,6 @@
app:typingIndicator_tint="@color/signal_inverse_primary" />
</FrameLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</org.thoughtcrime.securesms.components.ConversationTypingView>

Wyświetl plik

@ -12,7 +12,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/preview_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -30,7 +30,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ccpv_chat_bubble_count="4" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<org.thoughtcrime.securesms.conversation.colors.ui.custom.CustomChatColorGradientToolView
android:id="@+id/gradient_tool"

Wyświetl plik

@ -17,7 +17,7 @@
android:layout_marginBottom="25dp"
android:contentDescription="@string/device_link_fragment__link_device"/>
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="25dp"
@ -87,6 +87,6 @@
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

Wyświetl plik

@ -9,7 +9,7 @@
tools:layout_height="match_parent"
tools:layout_width="match_parent">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/group_call_participant_card_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -23,6 +23,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</FrameLayout>

Wyświetl plik

@ -15,7 +15,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -59,9 +59,9 @@
tools:maxHeight="192dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
@ -116,7 +116,7 @@
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -14,7 +14,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -70,7 +70,7 @@
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/group_media_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="?android:attr/windowBackground"
app:cardCornerRadius="0dp"
app:cardElevation="0dp">
app:cardElevation="0dp"
tools:viewBindingIgnore="true">
<androidx.constraintlayout.widget.ConstraintLayout
@ -113,4 +113,4 @@
app:srcCompat="@drawable/ic_unidentified_delivery" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/group_media_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="?android:attr/windowBackground"
app:cardCornerRadius="0dp"
app:cardElevation="0dp">
app:cardElevation="0dp"
tools:viewBindingIgnore="true">
<FrameLayout
android:layout_width="match_parent"
@ -34,4 +34,4 @@
app:iconColor="@color/signal_inverse_primary" />
</FrameLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -6,7 +6,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
@ -74,6 +74,6 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</merge>

Wyświetl plik

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
@ -44,4 +44,4 @@
app:layout_constraintTop_toBottomOf="@id/processing_card_progress" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
@ -44,4 +44,4 @@
app:layout_constraintTop_toBottomOf="@id/processing_card_progress" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -21,7 +21,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bubble" />
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/bubble"
android:layout_width="0dp"
android:layout_height="0dp"

Wyświetl plik

@ -7,7 +7,7 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
tools:parentTag="androidx.cardview.widget.CardView">
tools:parentTag="com.google.android.material.card.MaterialCardView">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"

Wyświetl plik

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/story_text_post_card"
android:layout_width="0dp"
android:layout_height="0dp"
@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/background_protection"
@ -86,7 +86,7 @@
app:srcCompat="@drawable/ic_arrow_end_24"
app:tint="@color/signal_colorSecondaryContainer" />
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/send_in_progress_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -104,6 +104,6 @@
android:layout_margin="24dp"
android:indeterminate="true"
app:indicatorColor="@color/signal_colorPrimary" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -23,7 +23,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/story_content_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -71,7 +71,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<org.thoughtcrime.securesms.stories.StoryVolumeOverlayView
android:id="@+id/story_volume_overlay"

Wyświetl plik

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
@ -44,4 +44,4 @@
app:layout_constraintTop_toBottomOf="@id/processing_card_progress" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
@ -18,4 +18,4 @@
android:layout_width="72dp"
android:layout_height="72dp" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -176,7 +176,7 @@
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/call_screen_pip"
android:layout_width="@dimen/picture_in_picture_gesture_helper_pip_width"
android:layout_height="@dimen/picture_in_picture_gesture_helper_pip_height"
@ -196,7 +196,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</org.thoughtcrime.securesms.util.views.TouchInterceptingFrameLayout>
<include

Wyświetl plik

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -63,4 +63,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

Wyświetl plik

@ -9,7 +9,7 @@
android:clipToPadding="false"
android:clipChildren="false">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="5dp"
@ -47,6 +47,6 @@
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -50,7 +50,6 @@ dependencyResolutionManagement {
alias('androidx-recyclerview').to('androidx.recyclerview:recyclerview:1.2.1')
alias('androidx-legacy-support').to('androidx.legacy:legacy-support-v13:1.0.0')
alias('androidx-legacy-preference').to('androidx.legacy:legacy-preference-v14:1.0.0')
alias('androidx-cardview').to('androidx.cardview:cardview:1.0.0')
alias('androidx-preference').to('androidx.preference:preference:1.0.0')
alias('androidx-gridlayout').to('androidx.gridlayout:gridlayout:1.0.0')
alias('androidx-exifinterface').to('androidx.exifinterface:exifinterface:1.3.3')

Wyświetl plik

@ -0,0 +1,82 @@
package org.signal.lint;
import com.android.tools.lint.client.api.JavaEvaluator;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.LintFix;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UExpression;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("UnstableApiUsage")
public final class CardViewDetector extends Detector implements Detector.UastScanner {
static final Issue CARD_VIEW_USAGE = Issue.create("CardViewUsage",
"Utilizing CardView instead of MaterialCardView subclass",
"Signal utilizes MaterialCardView for more consistent and pleasant CardViews.",
Category.MESSAGES,
5,
Severity.WARNING,
new Implementation(CardViewDetector.class, Scope.JAVA_FILE_SCOPE));
@Override
public @Nullable List<String> getApplicableConstructorTypes() {
return Collections.singletonList("androidx.cardview.widget.CardView");
}
@Override
public void visitConstructor(JavaContext context, @NotNull UCallExpression call, @NotNull PsiMethod method) {
JavaEvaluator evaluator = context.getEvaluator();
if (evaluator.isMemberInClass(method, "androidx.cardview.widget.CardView")) {
LintFix fix = quickFixIssueAlertDialogBuilder(call);
context.report(CARD_VIEW_USAGE,
call,
context.getLocation(call),
"Using 'androidx.cardview.widget.CardView' instead of com.google.android.material.card.MaterialCardView",
fix);
}
}
private LintFix quickFixIssueAlertDialogBuilder(@NotNull UCallExpression alertBuilderCall) {
List<UExpression> arguments = alertBuilderCall.getValueArguments();
UExpression context = arguments.get(0);
String fixSource = "new com.google.android.material.card.MaterialCardView";
//Context context, AttributeSet attrs, int defStyleAttr
switch (arguments.size()) {
case 1:
fixSource += String.format("(%s)", context);
break;
case 2:
UExpression attrs = arguments.get(1);
fixSource += String.format("(%s, %s)", context, attrs);
break;
case 3:
UExpression attributes = arguments.get(1);
UExpression defStyleAttr = arguments.get(2);
fixSource += String.format("(%s, %s, %s)", context, attributes, defStyleAttr);
break;
default:
throw new IllegalStateException("MaterialAlertDialogBuilder overloads should have 1 or 2 arguments");
}
String builderCallSource = alertBuilderCall.asSourceString();
LintFix.GroupBuilder fixGrouper = fix().group();
fixGrouper.add(fix().replace().text(builderCallSource).shortenNames().reformat(true).with(fixSource).build());
return fixGrouper.build();
}
}

Wyświetl plik

@ -28,7 +28,8 @@ public final class Registry extends IssueRegistry {
BlockingGetDetector.UNSAFE_BLOCKING_GET,
RecipientIdDatabaseDetector.RECIPIENT_ID_DATABASE_REFERENCE_ISSUE,
ThreadIdDatabaseDetector.THREAD_ID_DATABASE_REFERENCE_ISSUE,
StartForegroundServiceDetector.START_FOREGROUND_SERVICE_ISSUE);
StartForegroundServiceDetector.START_FOREGROUND_SERVICE_ISSUE,
CardViewDetector.CARD_VIEW_USAGE);
}
@Override

Wyświetl plik

@ -0,0 +1,100 @@
package org.signal.lint;
import com.android.tools.lint.checks.infrastructure.TestFile;
import org.junit.Test;
import java.io.InputStream;
import java.util.Scanner;
import static com.android.tools.lint.checks.infrastructure.TestFiles.java;
import static com.android.tools.lint.checks.infrastructure.TestLintTask.lint;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@SuppressWarnings("UnstableApiUsage")
public final class CardViewDetectorTest {
private static final TestFile cardViewStub = java(readResourceAsString("CardViewStub.java"));
@Test
public void cardViewUsed_LogCardViewUsage_1_arg() {
lint()
.files(cardViewStub,
java("package foo;\n" +
"import androidx.cardview.widget.CardView;\n" +
"public class Example {\n" +
" public void buildDialog() {\n" +
" new CardView(context);\n" +
" }\n" +
"}")
)
.issues(AlertDialogBuilderDetector.ALERT_DIALOG_BUILDER_USAGE)
.run()
.expect("src/foo/Example.java:5: Warning: Using 'androidx.cardview.widget.CardView' instead of com.google.android.material.card.MaterialCardView [CardViewUsage]\n" +
" new CardView(context);\n" +
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
"0 errors, 1 warnings")
.expectFixDiffs("Fix for src/foo/Example.java line 5: Replace with new com.google.android.material.card.MaterialCardView(context):\n" +
"@@ -5 +5\n" +
"- new CardView(context);\n" +
"+ new com.google.android.material.card.MaterialCardView(context);");
}
@Test
public void cardViewUsed_LogCardViewUsage_2_arg() {
lint()
.files(cardViewStub,
java("package foo;\n" +
"import androidx.cardview.widget.CardView;\n" +
"public class Example {\n" +
" public void buildDialog() {\n" +
" new CardView(context, attrs);\n" +
" }\n" +
"}")
)
.issues(AlertDialogBuilderDetector.ALERT_DIALOG_BUILDER_USAGE)
.run()
.expect("src/foo/Example.java:5: Warning: Using 'androidx.cardview.widget.CardView' instead of com.google.android.material.card.MaterialCardView [CardViewUsage]\n" +
" new CardView(context, attrs);\n" +
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
"0 errors, 1 warnings")
.expectFixDiffs("Fix for src/foo/Example.java line 5: Replace with new com.google.android.material.card.MaterialCardView(context, attrs):\n" +
"@@ -5 +5\n" +
"- new CardView(context, attrs);\n" +
"+ new com.google.android.material.card.MaterialCardView(context, attrs);");
}
@Test
public void cardViewUsed_withAssignment_LogCardViewUsage_1_arg() {
lint()
.files(cardViewStub,
java("package foo;\n" +
"import androidx.cardview.widget.CardView;\n" +
"public class Example {\n" +
" public void buildDialog() {\n" +
" CardView cardView = new CardView(context)\n" +
" ;\n" +
" }\n" +
"}")
)
.issues(AlertDialogBuilderDetector.ALERT_DIALOG_BUILDER_USAGE)
.run()
.expect("src/foo/Example.java:5: Warning: Using 'androidx.cardview.widget.CardView' instead of com.google.android.material.card.MaterialCardView [CardViewUsage]\n" +
" CardView cardView = new CardView(context)\n" +
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
"0 errors, 1 warnings")
.expectFixDiffs("Fix for src/foo/Example.java line 5: Replace with new com.google.android.material.card.MaterialCardView(context):\n" +
"@@ -5 +5\n" +
"- CardView cardView = new CardView(context)\n" +
"+ CardView cardView = new com.google.android.material.card.MaterialCardView(context)");
}
private static String readResourceAsString(String resourceName) {
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(resourceName);
assertNotNull(inputStream);
Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
assertTrue(scanner.hasNext());
return scanner.next();
}
}

Wyświetl plik

@ -0,0 +1,16 @@
package androidx.appcompat.app;
public class CardView {
public CardView(Context context) {
}
public CardView(Context context, AttributeSet attrs) {
}
public CardView(Context context, AttributeSet attrs, int defStyleAttr) {
}
}

Wyświetl plik

@ -9,7 +9,7 @@
android:clipToPadding="false"
android:clipChildren="false">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="5dp"
@ -25,6 +25,6 @@
android:fontFamily="monospace"
tools:text="Spider-Man"/>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -9,7 +9,7 @@
android:clipToPadding="false"
android:clipChildren="false">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="5dp"
@ -25,6 +25,6 @@
android:fontFamily="monospace"
tools:text="Spider-Man"/>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>