CardView是实现卡片式布局的重要控件(appcompat-v7),它是FrameLayout的加强版,只是额外增加了圆角和投影的效果,立体感。
CardView 的基本用法
-
定义CardView布局,通过app:cardCornerRadius属性指定卡片圆角的弧度;
-
app:elevation属性指定卡片的高度。与FloatingActionButton一致。
-
将TextView放置在CardView中,这样TextView就会显示在卡片中了。
<android.support.v7.widget.CardView
android:layout_width="match_parent"
app:cardCornerRadius="4dp"
android:elevation="5dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
前几篇文章,已经实现了很多Material Design效果,但是屏幕上的主要的区域还处于空白状态,这里,我们使用RecycleView来填充这个项目的主界面部分。
使用卡片布局
添加依赖
compile 'com.android.support:cardview-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
compile 'com.github.bumptech.glide:glide:4.0.0-RC0'
(Glide库是一个超级强大的图片加载库,不仅可以加载本地图片,也可以加载网络图片,GIF图片,甚至是本地视频。 )
修改antivity_main.xml(添加RecycleView)
<?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/recycle_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<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"
app:elevation="8dp" />
</android.support.design.widget.CoordinatorLayout>
...
</android.support.v4.widget.DrawerLayout>
新建实体类Fruit
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;
}
}
定义RecycleView的子项布局fruit_item.xml文件
- 使用CardView作为子项的最外层布局(这样RecycleeView每个元素都是卡片当中的)
- Image中使用了scaleType属性,指定图片的缩放式。centerCrop(原有图片充满ImageView)。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<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>
为RecycleView准备FruitAdapter适配器
Glide的用法:首先调用Glide的with()方法并传入一个Context,Activity或Fragment参数,然后调用load()方法,传入图片的URL地址,也可以是本地路径,或者是id,接着调用info()方法设置到具体的哪个ImageView
(因为图片像素很高,如果不进行压缩就展示的话很容易引起内存溢出,使用Glide就不用更担心了,因为Glide内部做了很多复杂的逻辑,包括了图片压缩,我们只需要按照Glide的标准去加载图片就好了)
public class FruitAdapter extends RecyclerView.Adapter <FruitAdapter.ViewHolder>{
private Context mContext;
public FruitAdapter(List<Fruit> mFruitList) {
this.mFruitList = mFruitList;
}
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view) {
super(view);
cardView = (CardView) itemView;
fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
fruitName = (TextView) view.findViewById(R.id.fruit_name);
}
}
@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 = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
准备图片
这里使用郭神提供的精美的水果图片【图片地址:点我】
修改MainActivity
- 定义fruitList数组,存放多个Fruit实例
- initFruits方法,首先清空数组fruitList中的束缚,然后使用随机函数随机生成水果添加到fruitList中。
- 使用GridLayoutManager,第一个参数是Context,第二个参数是列数,这里我们设置为两列。
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private List<Fruit> fruitList = new ArrayList<>();
private FruitAdapter adapter;
private Fruit[] fruits = {new Fruit("Apple", R.drawable.apple), 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),
new Fruit("Cherry", R.drawable.cherry), new Fruit("Mango", R.drawable.mango)};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycle_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 < 25; i++) {
Random random = new Random();
int index = random.nextInt(fruits.length);
fruitList.add(fruits[index]);
}
}
运行,结果如图