Как имитировать стиль поднятой кнопки "Material-design", даже для pre-Lollipop (минус специальные эффекты)?
Google показал несколько хороших способов, что кнопки отображаются на Lollipop здесь.
Я говорю о поднятых и плоских кнопках.
Как я могу имитировать их в версиях до Lollipop, кроме специальных эффектов (рябь и т.д.)?
Я говорю о this и this.
Конечно, на Lollipop и выше, я хотел бы использовать специальные эффекты.
Я знаю, что уже есть несколько (и даже много) сообщений об этом, но я не вижу никаких попыток имитировать его полностью.
Ответы
Ответ 1
Обновленный ответ:
Рекомендуется, чтобы вы полагались на библиотеку Google appcompat для поддержки стилей дизайна материалов для вашего приложения. Кажется, что он больше не обращает внимание на поднятую кнопку (вместо этого использует плоские кнопки), но все же адекватно поддерживает кнопку, соответствующую стилю дизайна материала. Это моя рекомендация, что вы идете с этим подходом.
Если вы все еще хотите создать резервную копию эффекта поднятой кнопки, вам нужно будет полагаться на библиотеку материалов для сторонних разработчиков, или вы можете посмотреть мое старое решение ниже, используя CardView
и реализовать свой собственный.
Чтобы настроить библиотеку appcompat с официальным официальным обращением к материалам Google:
compile "com.android.support:appcompat-v7:+"
Затем вам нужно настроить тему приложения в файле styles.xml
.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
И в вашем AndroidManifest.xml
убедитесь, что тема выше установлена правильно:
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="false"
android:theme="@style/AppTheme">
После вышеуказанной настройки убедитесь, что все ваши Activity
простираются от AppCompatActivity
, и оттуда все ваши Button
будут завышены с помощью стиля Material Design.
Если вы используете пользовательскую реализацию Button
в своем проекте, убедитесь, что вместо расширения Button
продолжите AppCompatButton
. Это относится к большинству ваших пользовательских View
s: AppCompatTextView
, AppCompatEditText
и т.д.
Как это работает?
Все ваши xml-макеты Android раздуты, используя что-то, называемое LayoutInflater
. LayoutInflater
предоставляется Activity
и имеет возможность предоставления LayoutInflaterFactory
, предоставляемого ему, чтобы вы могли переопределять стандартные реализации стандартных виджетов Android, таких как Button
и TextView
. Когда вы используете AppCompatActivity
, он предоставляет вам нестандартный LayoutInflater
, который раздувает специальные экземпляры виджетов, которые поддерживают Material Design!
-------------------------------------------- -----
Старый ответ:
----------------------------------------------- -
Итак, Android дал нам CardView, чтобы воспроизвести такое поведение. Он обеспечивает просмотр с закругленными углами, который применяет тень. Вероятно, вы также захотите посмотреть на метод # setCardElevation().
Вы можете добавить библиотеку CardView в свой проект Gradle:
compile 'com.android.support:cardview-v7:+'
CardView будет использовать реализацию Lollipop, чтобы сделать это, если он доступен (поскольку тени Lollipops лучше), иначе он будет реплицировать его как можно лучше.
Вот пример:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="#ffd9d9d9"
card_view:cardCornerRadius="2dp"
android:layout_margin="6dp"
card_view:cardElevation="6dp">
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8.5dp"
android:paddingBottom="8.5dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:textColor="#de000000"
android:fontFamily="sans-serif-medium"
android:text="NORMAL" />
</android.support.v7.widget.CardView>
Приведенный выше код работает на 5.0: ![CardView Button on 5.0]()
Вышеприведенный код работает в 4.4.4: ![CardView Button on 4.4.4]()
Похоже, что существует расхождение в шрифтах, так как в sans-serif-media имеет другой размер шрифта или не поддерживается в 4.4.4, но его можно легко устранить, включив последнюю версию Roboto и переопределение шрифтов в TextViews.
В документации к материалу вы указываете "Повышенная кнопка". CardView - это то, как мы делаем что-то "повышенное".
Ответ 2
Добавьте в приложение совместимую библиотеку. (Самая последняя версия может быть найдена здесь.) Сделайте это, добавив зависимость в файл build.gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
Объявите свою apptheme в файле styles.xml, расположенном в каталоге значений:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/theme_primary</item>
<item name="colorAccent">@color/theme_accent_1</item>
<item name="actionMenuTextColor">@color/theme_text</item>
</style>
</resources>
Задайте объявленный стиль как тот, который будет использоваться для вашего приложения в файле manifest.xml:
<application
android:icon="@drawable/ic_launcher"
android:theme="@style/AppTheme"/>
В ваших макетах объявите поднятую кнопку следующим образом
<Button
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/title_add" />
Объявите стиль плоской кнопки следующим образом:
<Button
android:id="@+id/okbutton"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@android:string/ok" />
Результат как для телефона 4.4 (телефон), так и для планшета 5.0:
![Tablet with 5.0]()
![Phone 4.4]()
Подробности можно найти в официальной документации: http://developer.android.com/training/material/theme.html
Ответ 3
Я получаю тот же эффект, используя
android:background="@android:drawable/dialog_holo_light_frame"
Мой тестовый результат:
![enter image description here]()
Ответ 4
Этот хакерский в соответствии с Yigit (google dev on cardview), но выполняет спуск.
Вы можете использовать отрицательные числа, чтобы избавиться от отступов и полей внутри CardView.
Проверено на эмуляторах api 15 nexus one и nexus 4. Это решение будет работать на pre lollipop.
<android.support.v7.widget.CardView
android:id="@+id/elevated_button_card"
card_view:cardElevation="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardMaxElevation="8dp"
card_view:contentPadding="-2dp"
android:layout_marginBottom="-2dp"
card_view:cardCornerRadius="0dp">
<Button
android:id="@+id/elevated_button"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Add New Exercise"/
</android.support.v7.widget.CardView>
код:
final CardView cardView = (CardView) rootView.findViewById(R.id.elevated_button_card);
final Button button = (Button) rootView.findViewById(R.id.elevated_button);
button.setOnTouchListener(new View.OnTouchListener() {
ObjectAnimator o1 = ObjectAnimator.ofFloat(cardView, "cardElevation", 2, 8)
.setDuration
(80);
ObjectAnimator o2 = ObjectAnimator.ofFloat(cardView, "cardElevation", 8, 2)
.setDuration
(80);
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
o1.start();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
o2.start();
break;
}
return false;
}
});
Ответ 5
Я работаю над библиотекой совместимости материалов. Я написал свой собственный класс Button с материалоподобными стилями, анимированными тенями и эффектом касания. Хотя это еще не все, вы можете попробовать здесь.
Ответ 6
В дополнение к ответу @spierce7 я немного улучшил этот макет. Итак, теперь у него есть относительный макет, который устанавливает наш пользовательский TextView точно в центре CardView. Так вот оно.
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="@color/colorPrimary"
card_view:cardCornerRadius="1dp"
card_view:cardElevation="3dp"
android:longClickable="false"
android:id="@+id/button">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp"> //just my custom height
<com.example.admin.lanet_contactwork.MyTextView //for below 5.0
android:layout_width="wrap_content"
android:layout_height="wrap_content"
PipBoy:fontName="Roboto-Medium.ttf" //custom font
android:text="@string/enter"
android:textColor="@android:color/white"
android:textSize="14sp"
android:layout_centerInParent="true"
/>
</RelativeLayout>
</android.support.v7.widget.CardView>
Ответ 7
См. мой ответ для решения, сохраняющего границу и повышенный эффект на pre-lollipop, сохраняя эффект пульсации на леденец без недостатка здесь