CardView繼承FrameLayout
一、常用屬性
1、cardBackgroundColor
設置背景色
CardView是View的子類,View一般使用Background
設置背景色,爲什麼還要單獨提取出一個屬性讓我們來設置背景色呢?
爲了實現陰影效果,內部已經消耗掉了 Background 屬性
2、cardCornerRadius
設置圓角半徑
3、contentPadding
設置內部padding
View提供了padding
設置背景色,爲什麼還要單獨提取出一個屬性?
相同的原因,內部消耗掉了 padding 屬性
4、cardElevation
設置陰影大小
5、cardUseCompatPadding
默認爲false,用於5.0及以上,true則添加額外的 padding 繪製陰影
6、cardPreventCornerOverlap
默認爲true,用於5.0及以下,添加額外的 padding,防止內容和圓角重疊
二、屬性效果展示
三、案例展示
1、在AndroidManifest.xml添加使用cardview需要引入的依賴庫
implementation 'androidx.cardview:cardview:1.0.0'
若不記得,File --> Project Structrue --> Dependencies --> app --> + --> 1 Library Dependency --> cardview --> 點擊search --> 會顯示最新版本
具體代碼:
1、一個最簡單的示例:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><!-- 幀佈局 -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- 通過cardview添加陰影效果 -->
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
>
<TextView
android:layout_width="200dp"
android:layout_height="50dp"
android:gravity="center"
android:text="Hello World!" />
<!-- android:layout_gravity="center" 讓整個容器居中 -->
</androidx.cardview.widget.CardView>
</FrameLayout>
MainActivity
package com.example.cardviewstudy;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
效果圖:
2、複雜化
① 在cardview控件內新增:
app:cardBackgroundColor="#44ff0000" android:background="#4400ff00"
#44ff0000 粉色 , #4400ff00 綠色。因都爲半透明色,故如果同時生效的話,是能夠看出來的。
效果圖:
效果圖說明:CardView內部已經消耗掉了 Background 屬性
②在cardview控件內新增:
app:cardCornerRadius="10dp"
③在cardview控件內新增:
app:contentPadding="10dp"
效果圖:整體卡片的寬高都變大了,因爲加了一個10dp的padding
③在cardview控件內新增:
app:cardElevation="10dp"
效果圖:
四、案例
目標圖:
1、佈局搭建
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listview_MsgList"
android:divider="@null"
android:background="#ffffff"
android:paddingTop="8dp"
>
</ListView>
疑問: android:divider="@null"
答案: listview去掉分割線的三種方式
item_msg.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/imageview_Image"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:layout_margin="8dp"
tools:src="@drawable/img01" />
<!-- tools 測試屬性,只會在PreView中看到,運行時沒有這些東西 -->
<TextView
android:id="@+id/textview_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textColor="#000000"
android:textSize="16dp"
android:textStyle="bold"
tools:text="使用慕課網學習Android技術" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
tools:text="使用慕課網學習Android技術使用慕課網學習Android技術使用慕課網學習Android技術使用慕課網學習Android技術"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
疑問: android:scaleType="centerCrop"
答案: 詳解android:scaleType屬性
android:scaleType
是控制圖片如何resized/moved來匹對ImageView的size
centerCrop
按比例擴大圖片的size居中顯示,使得圖片長(寬)等於或大於View的長(寬)
2、實體類創建
Message
package com.example.cardviewstudy;
/**
* function:
* Created by TMJ on 2020-02-20.
*/
public class Message {
private int id;//在整個佈局裏算第幾個Message
private int imgResId;//Image圖片的id
private String title;//標題
private String content;//內容
//無參構造函數
public Message() {
}
//有參構造函數
public Message(int id, int imgResId, String title, String content) {
this.id = id;
this.imgResId = imgResId;
this.title = title;
this.content = content;
}
//Getter and Setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getImgResId() {
return imgResId;
}
public void setImgResId(int imgResId) {
this.imgResId = imgResId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
MessageLab
package com.example.cardviewstudy;
import java.util.ArrayList;
import java.util.List;
/**
* function: 輔助作用
* Created by TMJ on 2020-02-20.
*/
public class MessageLab {
public static List<Message> generateMockList() {
List<Message> messageList = new ArrayList<>();
Message message = new Message(1,
R.drawable.img01,
"如何才能不錯過人工智能的時代?",
"下一個時代就是機器學習的時代,慕課網發大招,與你一起預見未來!");
messageList.add(message);
message = new Message(2,
R.drawable.img02,
"關於你的面試、實習心路歷程",
"獎品豐富,更設有參與獎,隨機抽取5名幸運用戶,獲得慕課網付費面試課程中的任意一門!");
messageList.add(message);
message = new Message(3,
R.drawable.img03,
"狗糧不是你想吃,就能吃的!",
"你的朋友圈開始了嗎?一半秀恩愛,一半扮感傷!不怕,還有慕課網陪你堅強地走下去!!");
messageList.add(message);
message = new Message(4,
R.drawable.img04,
"前端跳槽面試那些事兒",
"工作有幾年了,項目偏簡單有點拿不出手怎麼辦? 目前還沒畢業,正在自學前端,請問可以找到一份前端工作嗎,我該怎麼辦?");
messageList.add(message);
message = new Message(5,
R.drawable.img05,
"圖解程序員怎麼過七夕?",
"哈哈哈哈,活該單身25年!");
messageList.add(message);
return messageList;
}
}
3、功能實現
MsgAdapter
package com.example.cardviewstudy;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/**
* 繼承BaseAdapter,實現4個方法
* Created by TMJ on 2020-02-20.
*/
public class MsgAdapter extends BaseAdapter {
private Context mContext;//上下文環境
/**
* 主要用於加載item_msg的佈局
*/
private LayoutInflater mInflater;
private List<Message> mDatas;
/**
* 構造方法
*/
public MsgAdapter(Context context, List<Message> datas) {
/**
* 賦值
*/
mContext = context;
mInflater = LayoutInflater.from(context);
mDatas = datas;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null){
convertView=mInflater.inflate(R.layout.item_msg,parent,false);
viewHolder=new ViewHolder();
/**
* 獲取子佈局中三個控件:ImageView TextView TextView
*/
viewHolder.mIvImg=convertView.findViewById(R.id.imageview_Image);
viewHolder.mTvTitle=convertView.findViewById(R.id.textview_title);
viewHolder.mTvContent=convertView.findViewById(R.id.textview_content);
convertView.setTag(viewHolder);
}
else {
viewHolder= (ViewHolder) convertView.getTag();
}
Message message=mDatas.get(position);
viewHolder.mIvImg.setImageResource(message.getImgResId());
viewHolder.mTvTitle.setText(message.getTitle());
viewHolder.mTvContent.setText(message.getContent());
return convertView;
}
/**
* 內部類:可省去findViewById的時間
*/
public static class ViewHolder {
ImageView mIvImg;
TextView mTvTitle;
TextView mTvContent;
}
}
MainActivity
package com.example.cardviewstudy;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView mLvMsgList;
private List<Message> mDatas = new ArrayList<>();
private MsgAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLvMsgList = findViewById(R.id.listview_MsgList);
/**
* 多調用兩次,數據會更多
*/
mDatas.addAll(MsgLab.generateMockList());
mDatas.addAll(MsgLab.generateMockList());
mAdapter=new MsgAdapter(this,mDatas);
mLvMsgList.setAdapter(mAdapter);
}
}
效果圖:
5.0以上 <————> 5.0以下
4、適配
通過上圖對比:
① 5.0以下卡片之間的距離變大
cardUseCompatPadding
默認爲false,用於5.0及以上,true則添加額外的 padding 繪製陰影
在CardView控件內添加:
app:cardUseCompatPadding="true"
效果圖:
5.0以上添加前 <————> 添加後 <————> 5.0以下
cardview在5.0以上的效果是比較好的,在5.0以上的佈局已經寫好的情況下,期望5.0以下與5.0以上保持一致
故cardUseCompatPadding
設置爲alse
app:cardUseCompatPadding="true"
② 將5.0以下卡片間的距離,以及左右兩側我們看起來的距離變小
使用限定符
參考資料:
手機適配之 dimen 基礎知識
手機適配之 values 目錄基礎知識
1’ 新建res --> new --> Android Resource Directory,文件夾名:values-v21
新建Values Resource File,文件名:dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 橫向的: left right -->
<dimen name="margin_item_msg_l_r">16dp</dimen>
<!-- 縱向的: top bottom -->
<dimen name="margin_item_msg_t_b">8dp</dimen>
</resources>
修改item_msg.xml
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
修改成
android:layout_marginLeft="@dimen/margin_item_msg_l_r"
android:layout_marginRight="@dimen/margin_item_msg_l_r"
android:layout_marginTop="@dimen/margin_item_msg_t_b"
android:layout_marginBottom="@dimen/margin_item_msg_t_b"
2’ 新建res --> values --> new --> Values Resource File --> 文件名: dimens_hack_msg_item_cardview.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 橫向的: left right -->
<dimen name="margin_item_msg_l_r">9dp</dimen>
<!-- 縱向的: top bottom -->
<dimen name="margin_item_msg_t_b">0dp</dimen>
</resources>
效果圖:間隔變小
5.0以下添加後
③圓角與內容重疊
cardPreventCornerOverlap
默認爲true,用於5.0及以下,添加額外的 padding,防止內容和圓角重疊
效果圖:
5.0以下添加後
④注意
android:foreground="?attr/selectableItemBackground"
如果cardview在最外層,可以爲其設置點擊效果