SeniorUI29__沉浸式设计、CardView

SeniorUI_高级UI汇总目录

一 沉浸式设计

1 沉浸式状态栏

Google从Android kitkat(android 4.4)开始,给我们开发者提供了一套能透明的系统ui样式给状态栏和导航栏,可以调成跟Activity一样的的主题。用户可以沉浸到设计的App中,没有其他因素可以影响到用户,更符合整体设计风格,用户所看到的一屏 包含App内容 状态栏 内容区,导航栏,内容区为开发者所控制, 导航栏与状态栏 为本身系统拥有

2 版本兼容

5.0 以上 沉浸式 不一样
5.0以下 4.4以上 以下是另一套

// 将导航栏编程透明
true
//将状态栏设置成透明
true

fitSystemWindows属性:
Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity.
这个一个boolean值的内部属性,让view可以根据系统窗口(如status bar)来调整自己的布局,如果值为true,就会调整view的paingding属性来给system windows留出空间….

实际操作:
当status bar为透明或半透明时(4.4以上),系统会设置view的paddingTop值为一个适合的值(status bar的高度)让view的内容不被上拉到状态栏,当在不占据status bar的情况下(4.4以下)会设置paddingTop值为0(因为没有占据status bar所以不用留出空间)。

3 Demo

在这里插入图片描述
注意:并不是所有的4.4以上和5.0都支持,有些系统修改了UI

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView之前  全屏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setStatusBarColor(Color.YELLOW);
           getWindow().setNavigationBarColor(Color.YELLOW);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //4.4
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 5.0  4.4
     *
     * @param toolbar
     * @param styleColor
     */
    public void setToolBarStyle(Toolbar toolbar, View bottomView, int styleColor) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
                && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            if (toolbar != null) {
                int statusHeight = getStatusHeight();
                toolbar.setPadding(0, toolbar.getPaddingTop() + statusHeight, 0, 0);
                //下面的导航栏
                if (haveNavgtion()) {
                    ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();
                    layoutParams.height += getNavigationHeight();
                    Log.i("tuch", "getNavigationHeight  " + getNavigationHeight());
                    bottomView.setLayoutParams(layoutParams);
                    bottomView.setBackgroundColor(styleColor);

                }
            }

        }
    }

    private int getNavigationHeight() {
        int height = -1;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            String heightStr = clazz.getField("navigation_bar_height").get(object).toString();
            height = Integer.parseInt(heightStr);
            //dp--px
            height = getResources().getDimensionPixelSize(height);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }


        return height;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    private boolean haveNavgtion() {
        //屏幕的高度  真实物理的屏幕
        Display display = getWindowManager().getDefaultDisplay();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getRealMetrics(displayMetrics);
        int heightDisplay = displayMetrics.heightPixels;
        //为了防止横屏
        int widthDisplay = displayMetrics.widthPixels;
        DisplayMetrics contentDisplaymetrics = new DisplayMetrics();
        display.getMetrics(contentDisplaymetrics);
        int contentDisplay = contentDisplaymetrics.heightPixels;
        int contentDisplayWidth = contentDisplaymetrics.widthPixels;
        //屏幕内容高度  显示内容的屏幕
        int w = widthDisplay - contentDisplayWidth;
        //哪一方大于0   就有导航栏
        int h = heightDisplay - contentDisplay;
        return w > 0 || h > 0;
    }

    private int getStatusHeight() {
        int height = -1;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            String heightStr = clazz.getField("status_bar_height").get(object).toString();
            height = Integer.parseInt(heightStr);
            //dp--px
            height = getResources().getDimensionPixelSize(height);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }


        return height;
    }
}

Demo:StatusBarActivity

二 CardView

1 简介

  • CardView继承自FrameLayout类。
  • CardView是一种卡片视图,主要是以卡片形式显示内容。
    CardView功能
  • CardView实现在一个卡片布局中显示相同的内容,卡片布局可以设置圆角和阴影,还可以布局其他的View。
  • CardView即可作为一般的布局使用,也可以作为ListView和RecyclerView的Item使用。

2 CardView何时使用

  • 需要显示层次性的内容,可以考虑使用。
  • 需要显示列表或网格时,可以考虑使用。
    CardView位置
    • 包名:android.support.v7.widget.CardView
    • 文件地址有两个
      ○ android-sdk/extras/android/m2repository/com/android/support/cardview-v7
      ○ android-sdk/extras/android/support/v7/cardView
      ○ CardView引用

3 兼容

对低版本SDK的兼容(低于Android L版本)

  • 针对Android L以下的版本,对CardView添加了一个Elevation的元素,即XML中的app:cardElevation和代码中的setCardElevation。
  • 对于在低版本中,设置了CardElevation后,CardView会自动留出空间供阴影显示,但对于Android L版本,就需要手动设置Margin边距来预留空间,这样的结果就是在Android 5.0以上的手机上可以正常显示,但对于Android 4.4.x的手机上就发现边距很大,导致浪费了屏幕空间。
  • 解决上面问题,需要我们做适配。可以在/res/value和/res/value-v21分别创建dimens.xml文件,在dimens.xml里,随意命名,对于Android 5.0以上的设置数值0dp,对于Android 5.0以下的设置数值(根据实际需求)。这样就解决低版本中边距过大或者视觉效果不好的问题了。

对低版本SDK的兼容(低于Android L版本)setElevation的问题:
由于缺少一些系统API(如 RenderThread),CardView中的Elevation兼容实现并不完美,和真正的实现方法还是有较大的差距(不是指效果),所以调用 setCardElevation也不能随心所欲地传入一个Float型,在低版本系统使用时应当处理一下传入的数值或加上try-catch(不推荐)。

4 API

  • android:cardCornerRadius
    在xml文件中设置card圆角的大小
  • CardView.setRadius
    在代码中设置card圆角的大小
  • android:cardBackgroundColor
    在xml文件中设置card背景颜色
  • android:elevation
    在xml文件中设置阴影的大小
  • card_view:cardElevation
    在xml文件中设置阴影的大小
  • card_view:cardMaxElevation
    在xml文件中设置阴影最大高度
  • card_view:cardCornerRadius
    在xml文件中设置卡片的圆角大小
  • card_view:contentPadding
    在xml文件中设置卡片内容于边距的间隔
  • card_view:contentPaddingBottom
    在xml文件中设置卡片内容于下边距的间隔
  • card_view:contentPaddingTop
    在xml文件中设置卡片内容于上边距的间隔
  • card_view:contentPaddingLeft
    在xml文件中设置卡片内容于左边距的间隔
  • card_view:contentPaddingRight
    在xml文件中设置卡片内容于右边距的间隔
  • card_view:contentPaddingStart
    在xml文件中设置卡片内容于边距的间隔起始
  • card_view:contentPaddingEnd
    在xml文件中设置卡片内容于边距的间隔终止
  • card_view:cardUseCompatPadding
    在xml文件中设置内边距,V21+的版本和之前的版本仍旧具有一样的计算方式
  • card_view:cardPreventConrerOverlap
    在xml文件中设置内边距,在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠
    波纹点击效果

5 注意

  • 默认情况,CardView是不可点击的,并且没有任何的触摸反馈效果。
  • 触摸反馈动画在用户点击CardView时可以给用户以视觉上的反馈。
  • 实现这种行为,你必须提供一下属性:android:clickable和android:foreground。
    使用
<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:clickable="true"
  android:foreground="?android:attr/selectableItemBackground">
发布了211 篇原创文章 · 获赞 63 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/baopengjian/article/details/103619766