CardView dynamic shadow depends not only on elevation

狂风中的少年 提交于 2020-01-16 11:22:38

问题


While developing my app I'd created a RecyclerView with expandable CardViews inside and then mentioned "hey, why does the elevation is changing a bit while I'm animating only vertical size of card and opacity of extension?".

And then I've found what it's not an elevation who chages -- it's only a shadow changed.

Does anybody heard smth about it? Is it just an undescribed thing of interface drawing? I have no objections for cool feature, but it just a bit confused me (I've even spend about an hour to find out something about it on Google's guidelines)

I've shared the code that proves the idea of "height affects shadow drawing" but share some information if theres' something more behind this.


回答1:


In Material Design there are 2 light sources:

  • key light - a sharp light source ~45° above the screen (over your head)
  • ambient light - softer and weaker light source perpendicular to the screen (behind your head)

The shadow of the key light dominates.

This model is implemented in Android UI. Now, the light from the key light is hitting elements close to the top of the screen under a different angle than elements at the bottom, so the shadow is cast under a different angle accordingly, just as in reality - the intention behind Material Design.

Practically: the closer the element to the bottom, the stronger the shadow at the element's bottom edge and lighter at the top edge.

See Material Design: Environment: Light and shadows: Light

Image linked from: https://touchlab.co/2016-1-consistent-lighting-in-material-design/




回答2:


activity_main.xml

<FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent" android:layout_height="match_parent">
    <android.support.v7.widget.CardView android:id="@+id/dumb_card"
                                        android:layout_margin="16dp"
                                        tools:cardCornerRadius="4dp"
                                        android:layout_width="match_parent" android:layout_height="wrap_content">
        <LinearLayout android:orientation="vertical"
                      android:layout_width="match_parent" android:layout_height="match_parent">

            <SeekBar android:id="@+id/heighter"
                     android:layout_margin="16dp"
                     android:layout_width="match_parent" android:layout_height="wrap_content"/>

            <SeekBar android:id="@+id/elevator"
                     android:layout_margin="16dp"
                     android:layout_width="match_parent" android:layout_height="wrap_content"/>

        </LinearLayout>
    </android.support.v7.widget.CardView>
</FrameLayout>

MainActivity.java

public class MainActivity extends Activity {
    CardView card;
    SeekBar  heighter;
    SeekBar  elevator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //card
        card = (CardView) findViewById(R.id.dumb_card);

        //card height
        heighter = (SeekBar) findViewById(R.id.heighter);
        heighter.setMax(2500);
        heighter.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                ViewGroup.LayoutParams lp = card.getLayoutParams();
                lp.height = progress;
                card.setLayoutParams(lp);
            }
            public void onStartTrackingTouch(SeekBar seekBar) {}
            public void onStopTrackingTouch(SeekBar seekBar) {}
        });

        //card elevation
        elevator = (SeekBar) findViewById(R.id.elevator);
        elevator.setMax(250);
        elevator.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                card.setCardElevation(progress);
            }
            public void onStartTrackingTouch(SeekBar seekBar) {}
            public void onStopTrackingTouch(SeekBar seekBar) {}
        });
    }
}

AndroidManifest.xml

<application
    android:label="DumbCardElevation"
    android:theme="@android:style/Theme.Holo.Light" >
    <activity
        android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>



来源:https://stackoverflow.com/questions/32534578/cardview-dynamic-shadow-depends-not-only-on-elevation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!