android Material Design UI

android Material Design UI

1.DrawerLayout的用法

引用依赖库com.github.bumptech.glide:glide是一个超级强大的图片加载库,它不仅用于本地加载,还可以用于加载网络图片、GIF图片、甚至本地视频。这里我用来加载本地图片

 implementation 'com.android.support:design:28.0.0'
 implementation 'com.android.support:recyclerview-v7:28.0.0'
 implementation 'com.android.support:cardview-v7:28.0.0'
 implementation 'com.github.bumptech.glide:glide:4.9.0'

首先DrawerLayout是个布局,在布局中允许放入两个直接控件,第一个子控件是主屏幕中显示的内容,
第二个子控件是滑动菜单中显示的内容。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

     <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                style="@style/baseToolbar"
                android:background="?attr/colorPrimary"
                android:theme="@style/toolbarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
                app:popupTheme="@style/popupTheme"
                app:title="滑动菜单"
                app:titleTextAppearance="@style/Toolbar.TitleText">
    </FrameLayout>

     <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="8dp"
        app:headerLayout="@layout/nav_layout"
        app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

别忘了给布局中添加xmlns:app="http://schemas.android.com/apk/res-auto"命名空间
关于第二个子控件我们需要注意一点layout_gravity这个属性是必须定义的,因为我们需要告诉DrawerLayout滑动菜单时在屏幕的左边还是右边,指定left表示滑动菜单在左边,指定right表示滑动菜单在右边,我这里用了start,表示会根据系统语言进行判断,如果系统语言是从做往右的,哪滑动菜单就在左边,如何系统语言是从右到左的那滑动菜单就在右边。

1.2 NavigationView

这里的第二个子控件我直接用的是NavigationView用于滑动菜单,其中app:headerLayout和app:menu属性指向了是头部布局和menu文件下的item

滑动菜单的头部nav_layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:padding="10dp"
    android:background="?attr/colorPrimary">
    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/icon_image"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@mipmap/timg"
        android:layout_centerInParent="true"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        >
        <TextView
            android:id="@+id/tv_mail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="[email protected]"

            android:textColor="#fff"
            android:textSize="14sp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tony Green"
            android:layout_below="@+id/tv_mail"
            android:textColor="#fff"
            android:textSize="14sp"
            />
    </LinearLayout>

</RelativeLayout>

menu文件下nav_menu,用户滑动菜单下的item

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_all"
        android:icon="@mipmap/call"
        android:title="Call" />
    <item
        android:id="@+id/nav_friends"
        android:icon="@mipmap/friends"
        android:title="friends" />
    <item
        android:id="@+id/nav_location"
        android:icon="@mipmap/location"
        android:title="location" />
    <item
        android:id="@+id/nav_mail"
        android:icon="@mipmap/mail"
        android:title="mail" />
    <item
        android:id="@+id/nav_task"
        android:icon="@mipmap/task"
        android:title="task" />
</group>
</menu>

下面是实现滑动菜单的代码,代码都做了注释,这样就实现了一个简单的滑动菜单

public class DrawerLayoutDemo extends AppCompatActivity {
    private DrawerLayout drawer_layout;
    private Toolbar toolbar;
    private NavigationView navigationView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drawerlayout_demo);
        initView(); //绑定控件
        setSupportActionBar(toolbar);//将toolbar实列传入setSupportActionBar方法中
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                drawer_layout.openDrawer(GravityCompat.START);//openDrawer方法中传入一个Gravity参数,为了保证这里的行为和xml的一致,我传入了GravityCompat.START
            }
        });
        navigationView.setCheckedItem(R.id.nav_all);//默认选中的item
        //对滑动菜单中的Item进行监听
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                drawer_layout.closeDrawers();//将滑动菜单关闭
                switch (item.getItemId()){
                    case R.id.nav_task:
                        Toast.makeText(DrawerLayoutDemo.this,"Data deleted",Toast.LENGTH_SHORT).show();
                        break;
                }
                return true;
            }
        });

    }
    //绑定控件
    private void initView() {
        drawer_layout=findViewById(R.id.drawer_layout);
        toolbar=findViewById(R.id.toolbar);
        navigationView=findViewById(R.id.navigation);
    }
}

滑动菜单界面

android Material Design UI_第1张图片

1.3 FloatingActionButton悬浮按钮和可交互提示

3.1FloatingActionButton

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/drawer_layout">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            style="@style/baseToolbar"
            android:background="?attr/colorPrimary"
            android:theme="@style/toolbarTheme"
            app:layout_scrollFlags="scroll|enterAlways|snap"
            app:navigationIcon="@mipmap/more_z"
            app:popupTheme="@style/popupTheme"
            app:title="滑动菜单"
            app:titleTextAppearance="@style/Toolbar.TitleText">

        </android.support.v7.widget.Toolbar>
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:layout_gravity="bottom|end"/>
    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="8dp"
        app:headerLayout="@layout/nav_layout"
        app:menu="@menu/nav_menu" />

</android.support.v4.widget.DrawerLayout>

app:elevation属性是给FloatingActionButton指定一个高度值,高度越大,投影范围也越大,但是投影效果越淡,高度值越小,投影范围越小,但投影效果越浓,推荐使用默认效果就够了
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#F0625E")))//设置颜色
FloatingActionButton点击使事件,其实FloatingActionButton的点击事件和普通的button没什么两样,都是调用setOnClickListener()方法来注册一个监听器当点击按钮时,就会执行监听器中的onClick()方法

    floating.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v,"Data deleted",Snackbar.LENGTH_SHORT)
                        .setAction("Undo", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(DrawerLayoutActivity.this,"Data deleted",Toast.LENGTH_SHORT).show();
                            }
                        }).show();
            }
        });

android Material Design UI_第2张图片

1.4 CoordinatorLayout

在上面的FloatingActionButton监听器中监听Snackbar,可以看到这里调用了Snackbar.make()方法来创建一个Snackbar对象,make()方法的第一个参数需要一个view,只要是当前布局的任意一个view都可以,Snackbar会使用这个view来自动查找最外层的布局,用于展示Snackbar。第二个参数就是Snackbar中显示的内容,第三个参数是Snackbar显示的时长,和Toast类似。
当允许是我们发现Snackbar从屏幕底部出现,但这里我们发现Snackbar竟然将FloatingActionButton的悬浮按钮遮掩注了,这里我借助于CoordinatorLayout布局就可以轻松解决,把FrameLayout换成CoordinatorLayout我们在运行就会发现FloatingActionButton跟随向上移动了

CoordinatorLayout可以说是一个FrameLayout的加强版,CoordinatorLayout可以监听其所有的子控件各种事件,然后自动做出最为合理的响应,就像刚才Snackbar提示,而如果使用CoordinatorLayout监听CoordinatorLayout的弹出事件,那么他会自动将内部的FloatingActionButton向上偏移,从而不会被Snackbar遮挡

  <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">


            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            </android.support.v7.widget.RecyclerView>
        </android.support.v4.widget.SwipeRefreshLayout>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@mipmap/floating" />
    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="8dp"
        app:headerLayout="@layout/nav_layout"
        app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

android Material Design UI_第3张图片

2.卡片式布局

这里我用往布局中添加RecyclerView,用于展示卡片式布局的效果

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                style="@style/baseToolbar"
                android:background="?attr/colorPrimary"
                android:theme="@style/toolbarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
                app:popupTheme="@style/popupTheme"
                app:title="滑动菜单"
                app:titleTextAppearance="@style/Toolbar.TitleText">

            </android.support.v7.widget.Toolbar>
            
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
            </android.support.v7.widget.RecyclerView>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@mipmap/floating" />
    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="8dp"
        app:headerLayout="@layout/nav_layout"
        app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

创建一个用于android.support.v7.widget.RecyclerView的item.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/carView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardCornerRadius="4dp"
    android:layout_margin="5dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:padding="5dp"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="100dp" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            />
    </LinearLayout>
</android.support.v7.widget.CardView>

这里的item布局我的父级控件直接就式android.support.v7.widget.CardView,用于卡片式布局,放了ImageView和TextView,之后我们来写RecyclerView的适配器

public class GardBean implements Serializable {
    private int image;//图片ID
    private String name;//图片名字

    public GardBean() {
    }

    public GardBean(int image, String name) {
        this.image = image;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.Hanlder> {
    private List<GardBean> gardBeans;
    private Context context;

    public RecyclerAdapter(List<GardBean> gardBeans, Context context) {
        this.gardBeans = gardBeans;
        this.context = context;
    }

    @NonNull
    @Override
    public Hanlder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (context==null){
            context=parent.getContext();
        }
        View view = LayoutInflater.from(context).inflate(R.layout.item_gardview, parent, false);
        final Hanlder hanlder = new Hanlder(view);
        //这里式对RecyclerView的点击事件监听,跳转到折叠式标题栏
        hanlder.gardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position=hanlder.getAdapterPosition();//获取position
                GardBean gardBean=gardBeans.get(position);
                Intent intent=new Intent(context,GardDateActivity.class);
                intent.putExtra(GardDateActivity.FRUIT_NAME,gardBean.getName());
                intent.putExtra(GardDateActivity.FRUIT_IMAGE_ID,gardBean.getImage());
                context.startActivity(intent);
            }
        });
        return hanlder;
    }

    @Override
    public void onBindViewHolder(@NonNull Hanlder holder, int position) {
        GardBean gardBean = gardBeans.get(position);
        holder.imageView.setImageResource(gardBean.getImage());
        holder.name.setText(gardBean.getName());
        Glide.with(context).load(gardBean.getImage()).into(holder.imageView);
    }

    @Override
    public int getItemCount() {
        return gardBeans.size();
    }

    public class Hanlder extends RecyclerView.ViewHolder {
        private ImageView imageView;
        private TextView name;
        private CardView gardView;
        public Hanlder(View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.image);
            name = itemView.findViewById(R.id.tv_name);
            gardView=itemView.findViewById(R.id.carView);
        }
    }
}

添加适配器

private RecyclerAdapter adapter;
private GardBean[] gardBeans={new GardBean(R.mipmap.timg,"timg"),new GardBean(R.mipmap.timg_e,"timg_e")
    ,new GardBean(R.mipmap.timg_b,"timg_b"),new GardBean(R.mipmap.timg_c,"timg_c"),
     new GardBean(R.mipmap.timg_f,"timg_f")};//以数组的形式添加实例
private List<GardBean> gardBeanList=new ArrayList<>();
private RecyclerView recycler_view;
 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
      recycler_view= findViewById(R.id.recycler_view);
      initGardBean();
      adapter=new RecyclerAdapter(gardBeanList,DrawerLayoutActivity.this);
      GridLayoutManager gridLayoutManager=new GridLayoutManager(DrawerLayoutActivity.this,2);
      recycler_view.setLayoutManager(gridLayoutManager);//添加布局形式
      recycler_view.setAdapter(adapter);//添加适配器
    }
//由于图片少不好看,这里就做了个循环50次,随机出现图片
 private void initGardBean(){
        gardBeanList.clear();//清空list
        for (int i=0;i<50;i++){
            Random random=new Random();//随机出现图片
            int index=random.nextInt(gardBeans.length);
            gardBeanList.add(gardBeans[index]);//添加到list中
        }
    }

android Material Design UI_第4张图片

这里注意一下可以看到我们的布局Toolbar被RecyclerView遮挡了,一般我们是使用偏移,即让RecyclerView向下偏移一个Toolbar的高度,从而保证不会遮挡注标题栏,不过我们使用的是CoordinatorLayout,因此有一些更加巧妙的解决方式,这里我们引用android.support.design.widget.AppBarLayout,这是Design Support库提供的另一个工具,AppBarLayout实际上是一个垂直方向的LinearLayout,内部做了很多滚动事件的封装,并应用了一些Material Design设计理念

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                style="@style/baseToolbar"
                android:background="?attr/colorPrimary"
                android:theme="@style/toolbarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
                app:popupTheme="@style/popupTheme"
                app:title="滑动菜单"
                app:titleTextAppearance="@style/Toolbar.TitleText">

            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.AppBarLayout>
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

            </android.support.v7.widget.RecyclerView>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@mipmap/floating" />
    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="8dp"
        app:headerLayout="@layout/nav_layout"
        app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

可以看到上面的xml布局中给Toolbar添加父级控件,把Toolbar嵌套在AppBarLayout中,然后在RecyclerView使用app:layout_behavior属性指定一个布局行为。app:layout_behavior="@string/appbar_scrolling_view_behavior"字符串是Design Support库提供的,之后运行就会发现RecyclerView没用遮挡标题栏了,而我们向上滚动的时候发现Toolbar消失了,而向下滚动时又出现了,这里就会在一定程度上增加用户体验感。

android Material Design UI_第5张图片

2.1 SwipeRefreshLayout谷歌自带的刷新

这是谷歌自带的下拉刷新,看下布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                style="@style/baseToolbar"
                android:background="?attr/colorPrimary"
                android:theme="@style/toolbarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
                app:popupTheme="@style/popupTheme"
                app:title="滑动菜单"
                app:titleTextAppearance="@style/Toolbar.TitleText">

            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">


            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            </android.support.v7.widget.RecyclerView>
        </android.support.v4.widget.SwipeRefreshLayout>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@mipmap/floating" />
    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="8dp"
        app:headerLayout="@layout/nav_layout"
        app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

可以看到 这里的RecyclerView外面嵌套了一层SwipeRefreshLayout,这样RecyclerView就自动拥有了下拉刷新的功能了,另注意,由于RecyclerView现在变成了SwipeRefreshLayout的子控件,因此app:layout_behavior属性的生命布局的行为也要移动到SwipeRefreshLayout中才行

//swipeRefreshLayout调用刷新的方法setOnRefreshListener()
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshGardBean();
            }
        });
        //由于是本地图片加载太快,可能看不见刷新效果,这就做了个延迟2秒的效果
 private void refreshGardBean(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        initGardBean();
                        adapter.notifyDataSetChanged();//通知适配器刷新
                        swipeRefreshLayout.setRefreshing(false);
                    }
                });
            }
        }).start();
    }

android Material Design UI_第6张图片

3 可折叠式标题栏

3.1 CollapsingToolbarLayout

CollapsingToolbarLayout是一个作用于Toolbar基础之上的布局,由Design Support库提供,CollapsingToolbarLayout可以让Toolbar的效果变得更加丰富。
CollapsingToolbarLayout是不能独立存在的,他在设计的时候就被限定只能作为AppBarLayout的直接子布局在使用,而AppBarLayout又必须是CoordinatorLayout的子布局。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true"
        android:layout_height="250dp">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:id="@+id/icon_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"/>
            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:id="@+id/toolbar"
                app:layout_collapseMode="pin">

            </android.support.v7.widget.Toolbar>


        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

CollapsingToolbarLayout布局中 android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"设置指定主题,app:layout_scrollFlags=“scroll|exitUntilCollapsed”,scroll表示CollapsingToolbarLayout会随着内容详情一起滚动,exitUntilCollapsed表示当CollapsingToolbarLayout随着滚动完成折叠之后就保持在界面上,不在移除屏幕。
CollapsingToolbarLayout中定义了一个ImageView和Toolbar,也就是标题栏将是由普通的标题栏加上图片组合而成,app:layout_collapseMode属性,指定当前控件在CollapsingToolbarLayout折叠过程中的折叠模式,Toolbar指定成pin,表示在折叠的过程中位置始终保持不变,ImageView指定成parallax,表示在折叠的过程中产生一定的错位偏移。

设置内容详情布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true"
        android:layout_height="250dp">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:id="@+id/icon_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"/>
            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:id="@+id/toolbar"
                app:layout_collapseMode="pin">

            </android.support.v7.widget.Toolbar>


        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="150dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginTop="35dp"
                app:cardCornerRadius="4dp">
                <TextView
                    android:id="@+id/content_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"/>

            </android.support.v7.widget.CardView>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

最外层布局使用NestedScrollView,注意它和AppBarLayout是平级的,app:layout_behavior属性指定布局行为,
不管ScrollView还是NestedScrollView,它的内部都只允许存在一个直接子布局,这里的子布局是LinearLayout。而在其中把TextView存放在卡片式布局中显示。

下面这里在添加一个FloatingActionButton悬浮按钮表示评论按钮,他和NestedScrollView、AppBarLayout是平级,FloatingActionButton中使用app:layout_anchor属性指定一个锚点,描点指向AppBarLayout,这样悬浮按钮就会出现在标题栏区域内,app:layout_anchorGravity属性将悬浮按钮定位在标题栏区域右下角

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true"
        android:layout_height="250dp">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:id="@+id/icon_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"/>
            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:id="@+id/toolbar"
                app:layout_collapseMode="pin">

            </android.support.v7.widget.Toolbar>


        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="150dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginTop="35dp"
                app:cardCornerRadius="4dp">
                <TextView
                    android:id="@+id/content_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"/>

            </android.support.v7.widget.CardView>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end">

    </android.support.design.widget.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>

代码块

public class GardDateActivity extends AppCompatActivity {
    public static final String FRUIT_NAME = "fruit_name";
    public static final String FRUIT_IMAGE_ID = "fruit_image_id";
    private Toolbar toolbar;
    private CollapsingToolbarLayout collapsing_toolbar;
    private ImageView icon_image;
    private TextView content_text;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gardview_layout_date);
        Intent intent = getIntent();
        String fruitName = intent.getStringExtra(FRUIT_NAME);
        int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID,0);
        toolbar = findViewById(R.id.toolbar);
        collapsing_toolbar = findViewById(R.id.collapsing_toolbar);
        icon_image = findViewById(R.id.icon_image);
        content_text = findViewById(R.id.content_text);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        collapsing_toolbar.setTitle(fruitName);
        Glide.with(this).load(fruitImageId).into(icon_image);
        String fruitContent = generateFruitContent(fruitName);
        content_text.setText(fruitContent);
    }

    private String generateFruitContent(String fruitName) {

        StringBuffer stringBuffer = new StringBuffer();
        //循环名字500次由于简介内容
        for (int i = 0; i < 500; i++) {
            stringBuffer.append(fruitName);
        }
        return stringBuffer.toString();
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home://点击事件监听返回
                finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

这里FRUIT_NAME 和 FRUIT_IMAGE_ID是用来定义为图片id和名字的,在之前的适配器中用Intent传值过来
android Material Design UI_第7张图片
android Material Design UI_第8张图片
Demo链接
https://github.com/only95/TemoDemo
注:参考书籍Android第一行代码

你可能感兴趣的:(android)