Intereting Posts
Путаница: как работает SQLiteOpenHelper onUpgrade ()? И вместе с импортом старой резервной копии базы данных? Вращение ролика камеры Android * Vs ** vs *** в Proguard? Android конвертирует кодировку base64 в изображение Приложение Intraweb HTML5, git и база данных – они сочетаются? Снижение воздействия приложений на приложения, загружающие контент через смартфон Некоторые вопросы об OAuth и Android Java.lang.IllegalArgumentException: просмотр не подключен к менеджеру окон Обработка различных разрешений экрана для фоновых изображений в Android AdMob из Служб Google Play будет выполнять нежелательную автоматическую прокрутку Параметры компилятора отсутствуют в Android Studio> = 0.8.2 Android – Как определить, выбрал ли пользователь, чтобы поделиться с Facebook или Twitter с помощью намерений? Программно введите секретный код, например * # * # 4636 # * # * на Android Преобразование файла класса в файл dex ActivityLifecycleCallbacks не запускаются, когда активность убивается с помощью «Не продолжать действия»,

Как реализовать Elevation Material-Design для Pre-lollipop

Google показал несколько хороших способов, чтобы эффект возвышения был показан на Lollipop здесь .

android:elevation="2dp" 

Для кнопок,

 android:stateListAnimator="@anim/button_state_list_animator" 

Как я могу имитировать эффект возвышения на версиях до Lollipop без сторонней библиотеки?

Solutions Collecting From Web of "Как реализовать Elevation Material-Design для Pre-lollipop"

Вы можете имитировать возвышение на пред-Lollipop официальным методом.

Я достигаю такого же эффекта, используя,

  android:background="@android:drawable/dialog_holo_light_frame" 

Мой тестовый результат:

Введите описание изображения здесь

Ссылка – https://stackoverflow.com/a/25683148/3879847

Благодаря пользователю @Repo ..

Обновление: если вы хотите изменить цвет этого рисунка, попробуйте ответить @Irfan ниже ↓

https://stackoverflow.com/a/40815944/3879847

Вы не можете имитировать возвышение на пред-Lollipop официальным методом.

Вы можете использовать некоторые чертежи, чтобы сделать тень в своем компоненте. Например, Google использует этот способ в CardView.

ViewCompat.setElevation(View, int) настоящее время создает тень только для API21 +. Если вы проверите код позади, этот метод вызывает:

API 21+:

  @Override public void setElevation(View view, float elevation) { ViewCompatLollipop.setElevation(view, elevation); } 

API <21

 @Override public void setElevation(View view, float elevation) { } 

Вы можете взломать его с помощью карточного вида:

 <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/btnGetStuff" android:layout_width="wrap_content" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardBackgroundColor="@color/accent" > <!-- you could also add image view here for icon etc. --> <TextView android:id="@+id/txtGetStuff" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/textSize_small" android:textColor="@color/primary_light" android:freezesText="true" android:text="Get Stuff" android:maxWidth="120dp" android:singleLine="true" android:ellipsize="end" android:maxLines="1" /></android.support.v7.widget.CardView> 

Или посмотрите на использование этой сторонней библиотеки: https://github.com/rey5137/Material (см. Статью в вики на кнопке https://github.com/rey5137/Material/wiki/Button )

Создайте 9-патч- изображение с растяжимыми патчами, определенными на изображении с тенью вокруг него.

Введите описание изображения здесь

Добавьте это изображение с 9 патчами в качестве фона вашей кнопки с отступом, чтобы тень была видна.

Вы можете найти некоторые предварительно определенные 9-патч-изображения (.9.png) здесь или здесь, откуда вы можете выбрать, настроить и скопировать на ваш проект.

Чтобы принести динамические, анимированные тени к устройствам pre-Lollipop, вам необходимо:

  1. Нарисуйте черную форму вида на растровое изображение
  2. Размытие этой формы с использованием высоты в радиусе. Вы можете сделать это с помощью RenderScript. Это не совсем метод Lollipop, но дает хорошие результаты и легко добавляется к существующим представлениям.
  3. Нарисуйте эту размытую форму под видом. Вероятно, лучшим местом является метод drawChild . Вы также должны переопределить setElevation и setTranslationZ , переопределить чертеж детского представления в макетах, отключить клип-прописку и реализовать аниматоры состояния.

Введите описание изображения здесь

Это большая работа, но она дает лучшие, динамичные тени с анимацией ответа. Я не уверен, почему вы хотели бы достичь этого без сторонних библиотек. Если вы хотите, вы можете проанализировать источники Carbon и портировать части, которые вы хотели бы иметь в своем приложении:

Генерация тени

 private static void blurRenderScript(Bitmap bitmap, float radius) { Allocation inAllocation = Allocation.createFromBitmap(renderScript, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); Allocation outAllocation = Allocation.createTyped(renderScript, inAllocation.getType()); blurShader.setRadius(radius); blurShader.setInput(inAllocation); blurShader.forEach(outAllocation); outAllocation.copyTo(bitmap); } public static Shadow generateShadow(View view, float elevation) { if (!software && renderScript == null) { try { renderScript = RenderScript.create(view.getContext()); blurShader = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)); } catch (RSRuntimeException ignore) { software = true; } } ShadowView shadowView = (ShadowView) view; CornerView cornerView = (CornerView) view; boolean isRect = shadowView.getShadowShape() == ShadowShape.RECT || shadowView.getShadowShape() == ShadowShape.ROUND_RECT && cornerView.getCornerRadius() < view.getContext().getResources().getDimension(R.dimen.carbon_1dip) * 2.5; int e = (int) Math.ceil(elevation); Bitmap bitmap; if (isRect) { bitmap = Bitmap.createBitmap(e * 4 + 1, e * 4 + 1, Bitmap.Config.ARGB_8888); Canvas shadowCanvas = new Canvas(bitmap); paint.setStyle(Paint.Style.FILL); paint.setColor(0xff000000); shadowCanvas.drawRect(e, e, e * 3 + 1, e * 3 + 1, paint); blur(bitmap, elevation); return new NinePatchShadow(bitmap, elevation); } else { bitmap = Bitmap.createBitmap((int) (view.getWidth() / SHADOW_SCALE + e * 2), (int) (view.getHeight() / SHADOW_SCALE + e * 2), Bitmap.Config.ARGB_8888); Canvas shadowCanvas = new Canvas(bitmap); paint.setStyle(Paint.Style.FILL); paint.setColor(0xff000000); if (shadowView.getShadowShape() == ShadowShape.ROUND_RECT) { roundRect.set(e, e, (int) (view.getWidth() / SHADOW_SCALE - e), (int) (view.getHeight() / SHADOW_SCALE - e)); shadowCanvas.drawRoundRect(roundRect, e, e, paint); } else { int r = (int) (view.getWidth() / 2 / SHADOW_SCALE); shadowCanvas.drawCircle(r + e, r + e, r, paint); } blur(bitmap, elevation); return new Shadow(bitmap, elevation); } } 

Рисование представления с тенью

 @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (!child.isShown()) return super.drawChild(canvas, child, drawingTime); if (!isInEditMode() && child instanceof ShadowView && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) { ShadowView shadowView = (ShadowView) child; Shadow shadow = shadowView.getShadow(); if (shadow != null) { paint.setAlpha((int) (ShadowGenerator.ALPHA * ViewHelper.getAlpha(child))); float childElevation = shadowView.getElevation() + shadowView.getTranslationZ(); float[] childLocation = new float[]{(child.getLeft() + child.getRight()) / 2, (child.getTop() + child.getBottom()) / 2}; Matrix matrix = carbon.internal.ViewHelper.getMatrix(child); matrix.mapPoints(childLocation); int[] location = new int[2]; getLocationOnScreen(location); float x = childLocation[0] + location[0]; float y = childLocation[1] + location[1]; x -= getRootView().getWidth() / 2; y += getRootView().getHeight() / 2; // looks nice float length = (float) Math.sqrt(x * x + y * y); int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.translate( x / length * childElevation / 2, y / length * childElevation / 2); canvas.translate( child.getLeft(), child.getTop()); canvas.concat(matrix); canvas.scale(ShadowGenerator.SHADOW_SCALE, ShadowGenerator.SHADOW_SCALE); shadow.draw(canvas, child, paint); canvas.restoreToCount(saveCount); } } if (child instanceof RippleView) { RippleView rippleView = (RippleView) child; RippleDrawable rippleDrawable = rippleView.getRippleDrawable(); if (rippleDrawable != null && rippleDrawable.getStyle() == RippleDrawable.Style.Borderless) { int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.translate( child.getLeft(), child.getTop()); rippleDrawable.draw(canvas); canvas.restoreToCount(saveCount); } } return super.drawChild(canvas, child, drawingTime); } 

API высот, поддерживаемый до Lollipop

 private float elevation = 0; private float translationZ = 0; private Shadow shadow; @Override public float getElevation() { return elevation; } public synchronized void setElevation(float elevation) { if (elevation == this.elevation) return; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) super.setElevation(elevation); this.elevation = elevation; if (getParent() != null) ((View) getParent()).postInvalidate(); } @Override public float getTranslationZ() { return translationZ; } public synchronized void setTranslationZ(float translationZ) { if (translationZ == this.translationZ) return; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) super.setTranslationZ(translationZ); this.translationZ = translationZ; if (getParent() != null) ((View) getParent()).postInvalidate(); } @Override public ShadowShape getShadowShape() { if (cornerRadius == getWidth() / 2 && getWidth() == getHeight()) return ShadowShape.CIRCLE; if (cornerRadius > 0) return ShadowShape.ROUND_RECT; return ShadowShape.RECT; } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); setTranslationZ(enabled ? 0 : -elevation); } @Override public Shadow getShadow() { float elevation = getElevation() + getTranslationZ(); if (elevation >= 0.01f && getWidth() > 0 && getHeight() > 0) { if (shadow == null || shadow.elevation != elevation) shadow = ShadowGenerator.generateShadow(this, elevation); return shadow; } return null; } @Override public void invalidateShadow() { shadow = null; if (getParent() != null && getParent() instanceof View) ((View) getParent()).postInvalidate(); } 

Добавить ответ @Rajnit Kuamr

Чтобы добавить фоновый цвет к выделенному (например, цвет фона кнопки), нам необходимо получить программно.

Сначала получить доступный

 Drawable drawable = getResources().getDrawable(android.R.drawable.dialog_holo_light_frame); 

Установить цвет

 drawable.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.color_primary), PorterDuff.Mode.MULTIPLY)); 

Затем установите его в представление.

 view.setBackgroundDrawable(drawable); 

В случае, если кто-либо ищет.

U может легко имитировать его, объявив, что это можно сделать так:

shadow.xml

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient android:type="linear" android:angle="270" android:startColor="#b6b6b6" android:endColor="#ffffff"/> </shape> 

И использовать его int ur main xml like –

  android:background="@drawable/shadow"