Android收藏集AndroidAndroid开发

12Material Design-卡片式布局

2018-04-07  本文已影响290人  何惧l

虽然这个时候的项目中已经使用了很多Material Design效果,但是在主页面上还是一片空白,这个时候就用一些水果图片来填充这个区域
为了让水果图片也能Material化,这次就学习如何实现卡片式布局的效果

CardView

这个就是用于实现卡片布局效果的控件,由v7库提供,实际上CardView也是一个FrameLayout,但是会额外提供圆型和阴影的效果,看上去会有立体的感觉

  1. 基本用法,
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:elevation="5dp"
    app:cardCornerRadius="4dp">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
</android.support.v7.widget.CardView>

  1. 这里要使用到RecyclerView、CardView这几个控件,因此要在app/build.gradle文件中声明这些库的依赖
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.android.support:design:26.1.0'
    compile 'de.hdodenhof:circleimageview:2.1.0'

    compile 'com.android.support:recyclerview-v7:26.1.0'
    compile 'com.android.support:cardview-v7:26.1.0'
    compile 'com.github.bumptech.glide:glide:3.7.0'
}
  1. 修改activity_main.xml中的代码
<?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"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            />
        
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

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

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/ic_done"
            android:elevation="10dp"
            />


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

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

  1. 定义一个实体类Fruit,代码:
package com.example.tool;

public class Fruit {
    private String name;
    private int imageId;

    public Fruit(String name,int imageId) {
        this.name = name;
        this.imageId = imageId;
    }


    public String getName() {
        return name;
    }
    
    public int getImageId() {
        return imageId;
    }
}

  1. 需要为RecyclerView的子项指定一个自定义的布局,在layout目录下新建fruit_item文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:elevation="5dp"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

      <ImageView
          android:id="@+id/fruit_image"
          android:layout_width="match_parent"
          android:layout_height="100dp"
          android:scaleType="centerCrop"
          />
        <TextView
            android:id="@+id/fruit_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp"
            />
    </LinearLayout>

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

  1. 接下来要给RecyclerView准备一个适配器,新建一个FruitAdapter类,让这个适配器继承子RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,
package com.example.tool;

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{


    private Context mContext;
    private List<Fruit> mFruitList;

    // 获取到自定义的子项的每个控件
    static class ViewHolder extends RecyclerView.ViewHolder{

        CardView cardView;
        ImageView imageView;
        TextView textView;
        public ViewHolder(View itemView) {
            super(itemView);
            cardView = (CardView)itemView;
            imageView = (ImageView)itemView.findViewById(R.id.fruit_image);
            textView = (TextView)itemView.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List<Fruit> fruitList){
        mFruitList = fruitList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mContext == null){
            mContext = parent.getContext();
        }
        // 自定义的每项组件
        View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // 获取到Fruit实例,用于设置文字和照片
        Fruit fruit = mFruitList.get(position);
        holder.textView.setText(fruit.getName());
        //
        Glide.with(mContext).load(fruit.getImageId()).into(holder.imageView);
    }

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

}


  1. 接下来修改MainActivity中的代码就可以了
package com.example.tool;

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;

    private Fruit[] fruits = {new Fruit("apple",R.drawable.apple),
            new Fruit("mango",R.drawable.mango),
            new Fruit("banana",R.drawable.banana),
            new Fruit("orange",R.drawable.orange),
            new Fruit("watermelon",R.drawable.watermelon),
            new Fruit("pear",R.drawable.pear),
            new Fruit("grape",R.drawable.grape),
            new Fruit("pineapple",R.drawable.pineapple),
            new Fruit("strawberry",R.drawable.strawberry)
    };

    private List<Fruit> fruitList = new ArrayList<>();

    private FruitAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        initFruits();
        RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        GridLayoutManager layoutManager = new GridLayoutManager(this,2);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);


    }

    // 添加信息
    private void initFruits(){
        fruitList.clear();
        for (int i = 0; i<50; i++){
            Random random = new Random();
            int index = random.nextInt(fruits.length);
            fruitList.add(fruits[index]);
        }
    }
}

AppBarLayout

  1. 怎么使用AppBarLayout解决覆盖的问题,其实只要两步就可以,
    • 第一要把Toolbar嵌套到AppBarLayout中,
    • 第二要给RecyclerView指定一个布局行为
    • 修改activity_main.xml中的代码
<?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"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                />
        </android.support.design.widget.AppBarLayout>


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

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

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/ic_done"
            android:elevation="10dp"
            />


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

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

  1. 上面的例子完全体现不出来AppBarLayout的强大,事实上,当RecyclerView滚动的时候已将滚动事件都通知给了AppBarLayout了,当AppBarLayout接收到滚动事件的时候,它的内部的子控件其实是可以指定如何去影响这些事件的,通过app:layout_scrollFlags属性就能实现
<?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"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                />
        </android.support.design.widget.AppBarLayout>
        ...
    </android.support.design.widget.CoordinatorLayout>

    ...
</android.support.v4.widget.DrawerLayout>
上一篇 下一篇

猜你喜欢

热点阅读