文章目錄
Android
安卓開發者指南:https://developer.android.google.cn/guide
1 ListView
ListView是android中常用的一個控件,通常是以列表的形式展示數據,並且當加載的數據過多的時候可以分頁加載,動態顯示數據,通常是橫向顯示數據。ListView適合“自底向上”的開發模式,即從每個條目的顯示組件,到對其進行控制的數據結構,最後通過Activity等進行使用。
應用場景
1.通訊錄,短信列表
2.聊天聯繫人,聊天界面,好友動態
3.設置界面,各種列表界面
4.文件夾列表,應用列表等等
5.O2O美食外賣等商家列表、評論列表
ListView實踐的三種效果
1.模擬異步請求網絡數據
2.獲取本機安裝的軟件
3.類似聊天頁面實現
學習ListView需要學會的技能:
1.添加header rooter
2.實現ListView各種效果
3.綁定視圖與數據
4.優化列表樣式,加載性能優化
1.1 ListView展示列表數據
實現步驟:
-
在Layout創建ListView:activity_app_list,< ListView>標籤
-
創建每一行的layout:item_app_list_view.xml,< ImageView>和< TextView> 標籤
-
創建每一行的數據
public class AppLIstAdapter extends BaseAdapter中重寫方法:
public int getCount():有多少條數據
public Object getItem(int position):返回當前position位置的這一條數據
public long getItemId(int position):返回當前position位置的這一條數據的ID
public View getView(int position,View convertView, ViewGroup parent):處理view–data填充數據的一個過程
-
用adapter(數據綁定至相應組件)將數據填充到每一行的視圖中
appListView.setAdapter(new AppListAdapter(appNames));
1.2 獲取系統已安裝應用列表
- 獲取應用列表
// 獲取所有的應用信息
private List<ResolveInfo> getAppInfos() {
//手機系統中的主應用Intent
Intent intent = new Intent(Intent.ACTION_MAIN, null);
//應用程序顯示在程序列表裏的應用
intent.addCategory(Intent.CATEGORY_LAUNCHER);
//獲取手機中的所有應用信息列表
return getPackageManager().queryIntentActivities(intent, 0);
}
- 綁定應用列表信息
List<ResolveInfo> mInfos;
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.item_app_list_view, null);
ImageView appIconImageView = (ImageView)convertView.findViewById(R.id.app_icon);
TextView appNameTextView = (TextView)convertView.findViewById(R.id.app_name);
//獲取應用的名稱並與佈局View綁定
appNameTextView.setText(mInfos.get(position).activityInfo.loadLabel(getPackageManager()));
//獲取應用的圖標並與行佈局View綁定
appIconImageView.setImageDrawable(mInfos.get(positin,activityInfo.loadIcon(getPackageManager()));
// 爲圖標添加點擊事件,跳轉到其他應用去。方法一
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String packageName = mInfos.get(position).activityInfo.packageName;//包名
String className = mInfos.get(position).activityInfo.name;
ComponentName componentName = new ComponentName(packageName,className);
final Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
}
});
// 方法二:在OnCreate下,appListView.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 重寫onItemClick方法 });
// 長按:appListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){ 重寫onItemLongClick方法 });
return convertView;
}
添加一個頭部視圖:
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View headerView = layoutInflater.inflate(R.layout.header_list_view,null);
appListView.addHeaderView(headerView);
優化列表,每次都要解析layout,再findViewById查找,實際上提供了緩存,進行優化。(優化列表的樣式)
1.3 網絡下載數據並顯示
- 使用異步訪問網絡
- 解析獲取json數據
創建類:LessonInfo.java:mName,mDescription;
創建類:LessonResult.java:mMessage,mStatus,List< LessonInfo> mLessonInfoList=new ArrayList< >();
mListView.setAdapter(new RequestDataAdapter(RequestDataActivity.this, lessonResult.getLessonInfoList()); - 加載數據到ListView
新建適配器RequestDataAdapter類,繼承BaseAdapter重寫其中的方法:
注意,在AndroidManifest中聲明Activity,並且加入權限。
1.4 引用不同行佈局
根據不同type下展示不同view視圖。
ChatActivity.java中添加public static class ChatMessageAdapter extends BaseAdapter,重寫四個方法,並且再實現public int getItemViewType(int position)根據不同類型返回不同視圖,實現方法public int getViewTypeCount(){ return 2; }
添加類ChatMessage.java:
public class ChatMessage{
屬性:mId,mFriendID,mName,mDate,mContent,boolean mIsComMessage;
帶參構造方法
}
設計佈局
2 CardView控件
2.1 介紹
1.Android5.0 之後新增
2.com.android.support:cardview-v7:26.1.0 獨立引入
3.繼承自FrameLayout,方便作爲其他控件容器,添加3D陰影和圓角效果。
CardView常用屬性
- cardBackgroundColor 設置背景色
- cardCornerRadius 設置圓角半徑
- contentPadding 設置內部padding
- cardElevation 設置陰影大小
- cardUseCompatPadding 默認爲false,用於5.0及以上,true則添加額外的padding繪製陰影
- cardPreventCornerOverlap 默認爲true,用於5.0以下,添加額外的padding,防止內容和圓角重疊
2.2 demo
我的版本:
implementation ‘androidx.appcompat:appcompat:1.1.0’
implementation ‘androidx.cardview:cardview:1.0.0’
<androidx.cardview.widget.CardView>
2.3 手機適配之dimen
dimen是用來定義尺寸的資源文件,默認路徑工程的 res\values\dimens.xml
可以在res下創建不同分辨率的values目錄例如values-480x320、values-800x480、values-1920x1080等,並且在上述目錄中可以分別創建尺寸文件, 這樣在不同分辨率下,該目錄下的dimens.xml會代替res/values/dimens.xml達到最佳的適配效果。
dimen定義的資源文件如何使用?
1、在工程的res\values\目錄下創建一一個dimens.xml尺寸資源文件
2、添加一個佈局文件,在此佈局文件中添加一個按鈕,使用尺寸資源文件來定義按鈕的寬和高
3、在java代碼中也可以獲取到dimens尺寸資源文件的數值
Resources res = getResources();
float btn_h = res.getDimension(R.dimen.btn.height);
float btn_w = res.getDimension(R.dimen.btn.width);
尺寸文件使用建議:
1、在values目錄下創建一個默認的 dimens文件
2、儘可能多的創建不同分辨率的dimens文件(這樣應用纔會適配的完美)
手機適配之values目錄基礎知識:
values目錄用來存放colors.xml,dimens.xml,strings.xml等數值文件,同時也可以根據屏幕分辨率、語言、API 等設置對values目錄進行分類,特定的values目錄能滿足設定的設備進行加載,但values目錄命名是有規範的。
3 屏幕適配
由於Android系統的開放性,任何用戶、開發商、OEM廠商、運營商都可以對Android進行定製,修改成他們想要的樣子,導致碎片化嚴重。
屏幕尺寸:指屏幕的對角線的長度,單位是英寸,1英寸=2.54釐米,常見尺寸: 2.4,2.8,3.5,3.7 ,4.2,5.0,5.5,6.0等
屏幕分辨率:是指在橫縱向上的像素點數,單位是px,1px= 1個像素點,一般以 縱向像素 * 橫向像素 ,如: 1960 *1080
屏幕像素密度:是指每英寸上的像素點數,單位是dpi,即"dot per inch"的縮寫。屏幕像素密度與屏幕尺寸和屏幕分辨率有關。
eg:320*240,2.5inch
在屏幕像素密度爲160dpi的情況下,1dp=1px,假如:320dpi→1dp=2px
在尺寸一定的情況下,分辨率越高,屏幕越清晰,屏幕像素密度越大。
1dp= (像素密度/160dpi)*1px
換算公式:pxValue= (像素密度/160dpi)*dpValue
density:(像素密度/160dpi)
像素單位
px:pixel的縮寫,像素,1px代表屏幕上一個物理的像素點。
dip、 dp:都是Density Independent Pixels的縮寫,即密度無關像素。
sp:scaled pixels,與dp類似,用於設置字體大小。
dp的範圍劃分
佈局適配的方法
1.禁用絕對佈局;
2.少用px
3.使用wrap_ content、match_parent、權重layout_weight
4.重建佈局文件
1.wrap_content:先按照內容的多少去設定控件大小,然後按照權重的比例來分配剩餘控件。
2.match_parent:不受內容長度改變而改變,控件大小=父容器大小+權重比例剩餘空間大小。
3.使用0dp:直接按照所設定的比例去分配空間。
圖片適配的方法
1.提供不同分辨率的備用位圖
2.使用自動拉伸圖
4 BaseAdapter抽象類
BaseAdapter簡介及使用場景:
BaseAdapter是一個抽象類,常用於和Android中的一些控件如ListView,GridView ,ExpandableListview,Spinner等控件結合來顯示數據的一種控件,在Android開發中佔有很重要的位置。
使用步驟:
定義一個類來繼承BaseAdapter抽象類;
實現裏面的方法,書寫方法體;
在相應的Activity中使用該適配器。
重寫的方法:
public int getCount():數據域大小方法
public object getItem(int arg0):返回每個Item的數據
public long getItemId(int arg0):返回每個Item的ID
View getView(int position, View convertView, ViewGroup parent)
參數介紹:position就是位置從0開始;convertView是Spinner,ListView中每一項要顯示的view;parent就是父窗體了,也就是Spinner,ListView,GridView了,通常return的view 也就是convertView。
getView()方法的優化處理
第一種優化方式:
通過緩存convertView。這種利用緩存contentView的方式可以判斷如果緩存中不存在View才創建View,如果已經存在可以利用緩存中的View,提升了性能。
第二種優化方式:
通過convertView + ViewHolder來實現,ViewHolder就是一個靜態類,使用ViewHolder 的關鍵好處是緩存了顯示數據的視圖(View),加快了UI的響應速度。
當我們判斷convertView== null的時候,如果爲空,就會根據設計好的List的Item佈局(XML),來爲convertView賦值,並生成一個viewHolder來綁定converView裏面的各個View控件( XML佈局裏面的那些控件)。再用convertView的setTag將viewHolder設置到Tag中,以便系統第二次繪製ListView 時從Tag中取出。
如果convertView不爲空的時候,就會直接用convertView的getTag(),來獲得一個ViewHolder。
最重要的是:重繪視圖,調用次數是由第一個方法確定的,最後將視圖返回。
注意:有些控件必須設置成沒有獲利焦點與點擊。
這幾個方法寫的內容基本不變, 具有參考價值。
重寫數據區域使用ArrayList實現List。先封裝一個數據類,再將這個數據類裝進list集合中,綁定數據區域與視圖區域。setlistAdapter(MyAdapter);
注:MyAdapter是自定義的Adapter。