How to mimic the Material-design raised button style, even for pre-Lollipop (minus the special effects)?

后端 未结 7 1901
别跟我提以往
别跟我提以往 2020-12-07 16:54

Google has shown some nice ways that buttons are shown on Lollipop here.

I\'m talking about both the raised and the flat buttons.

How can I mimic them on pre

相关标签:
7条回答
  • 2020-12-07 17:10

    In addition to @spierce7 answer, I improved that layout a little bit. So now it has a relative layout in it, which sets our custom TextView exactly in a center of CardView. So here is it.

    <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>
    
    0 讨论(0)
  • 2020-12-07 17:17

    Add the compat library to your app. (The most current version can be found here.) Do this by adding a dependency within your build.gradle file:

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:21.0.3'
    }
    

    Declate your apptheme in a styles.xml file located in the values directory:

    <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>
    

    Set the declared style as the one to use for your application in the manifest.xml file:

    <application
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme"/>
    

    In your layouts declare a raised button as follows

    <Button
        android:id="@+id/addButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="@string/title_add" />
    

    Declare a flat button style as follows:

    <Button
        android:id="@+id/okbutton"
        style="?android:attr/borderlessButtonStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@android:string/ok" />
    

    Result on both a 4.4 (a phone) and a 5.0 (a tablet) device:

    Tablet with 5.0

    Phone 4.4

    Details can be found in the official documentation: http://developer.android.com/training/material/theme.html

    0 讨论(0)
  • I achieve same effect using,

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

    My tested output:

    enter image description here

    0 讨论(0)
  • 2020-12-07 17:17

    I'm working on a material compatibility library. I wrote my own Button class with material-like styles, animated shadows and the touch ripple effect. Although it's not perfect yet, You can try it here.

    0 讨论(0)
  • 2020-12-07 17:23

    Updated Answer: It is recommended that you rely on Google's appcompat library to backport material design styles to your app. It seems to no longer backport the raised button (instead using flat buttons), but still adequately backports a button that matches the material design style. It is my recommendation that you go with this approach.

    If you still wish to backport the raised button effect, you will need to rely on a 3rd party material design library, or you can look at my old solution below using the CardView and implement your own.

    To setup the appcompat library with Google's official Material Design backport:

    compile "com.android.support:appcompat-v7:+"
    

    Then you need to set your application theme in your styles.xml file.

    <!-- 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>
    

    And in your AndroidManifest.xml ensure the theme above is set properly:

    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="false"
        android:theme="@style/AppTheme">
    

    After the above setup, ensure all your Activity's extend from AppCompatActivity, and from there all your Buttons will be inflated with a Material Design style.

    If you are using a custom Button implementation in your project, ensure that instead of extending Button, extend AppCompatButton. That goes for most of your custom Views: AppCompatTextView, AppCompatEditText, etc...

    How does it work? All of your Android xml layouts are inflated using something called a LayoutInflater. The LayoutInflater is provided by the Activity, and has the option of having a LayoutInflaterFactory provided to it so that you can override default implementations of standard Android widgets, like Button and TextView. When you use an AppCompatActivity, it's providing you with a non-standard LayoutInflater, which is inflating special instances of the widgets that support Material Design!

    ------------------------------------------------- Old Answer: -------------------------------------------------

    So Android has given us the CardView to replicate such behavior. It provides a View with a rounded corners, that applies a drop shadow. You will probably also want to look at the #setCardElevation() method.

    You can add the CardView Library to your Gradle Project:

    compile 'com.android.support:cardview-v7:+'
    

    The CardView will use the Lollipop implementation to do this if it's available (as Lollipops shadows are better), otherwise it will replicate it as best as it can.

    Here is a sample:

    <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>
    

    The above code running on 5.0: CardView Button on 5.0

    The above code running on 4.4.4: CardView Button on 4.4.4

    It looks like there is a discrepancy in the fonts, as in the sans-serif-medium has a different font weight or isn't supported on 4.4.4, but that can be easily fixed by including the latest version of Roboto and overriding the fonts on the TextViews.

    The material documentation you post point to an an "Elevated Button". CardView's are how we make "Elevated" anything.

    0 讨论(0)
  • 2020-12-07 17:34

    This one is hacky according to Yigit (google dev on cardview) but does a descent job.

    You can use negative numbers in order to get rid of the padding and margin inside of CardView.

    Tested on api 15 nexus one and nexus 4 emulators. This solution will work on 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>
    

    Code:

            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;
                }
            });
    
    0 讨论(0)
提交回复
热议问题