Android進階:網路與資料儲存—步驟1:Android網路與通訊(第6小節:GridView)
阿新 • • 發佈:2018-12-13
內容概要:
- GirdView(網格檢視)顯示本地資料
- GirdView屬性簡介
- 案例一:用GirdView展示文字
- 案例二:用GridView顯示已安裝應用
- GridView顯示網路
- 用GridView載入網路圖片(上)
- 用GridView載入網路圖片(下)
一、GirdView(網格檢視)顯示本地資料
1.GirdView屬性簡介
在 Android 程式設計中 GridView 跟 ListView 都是比較常用的多控制元件佈局,而 GridView 更是實現九宮圖的首選!
GridView 的用法很多,主要凸顯的是那種網格式布 局,既有橫向也有縱向的資料顯示。
2. GridView 的使用場景
GridView 是 android 開發中常用的一個控制元件,它通常和以下幾塊內容結合使用
-
GridView 的九宮格效果
-
GridView 的獲取系統應用
-
GridView 動態載入資料
-
擴充套件:GridView 的上拉載入下拉重新整理
3. GridView 中常用的一些屬性 相關屬性解析:
- android:numColumns=”auto_fit” //GridView 的列數設定為自動
- android:columnWidth=”90dp " //每列的寬度,也就是 Item 的寬度
- android:stretchMode=”columnWidth"//縮放與列寬大小同步(每列單元格的寬度自適應,邊距固定)
- android:stretchMode=”SpacingWidth"//(每列單元格的寬度固定,邊距自適應)
- android:verticalSpacing=”10dp” //兩行之間的邊距
- android:horizontalSpacing=”10dp” //兩列之間的邊距
- android:cacheColorHint="#00000000" //去除拖動時預設的黑色背景
- android:listSelector="#00000000" //去除選中時的黃色底色
- android:scrollbars="none" //隱藏 GridView 的滾動條
- android:fadeScrollbars="true" //設定為 true 就可以實現滾動條的自動隱藏和顯示
- android:fastScrollEnabled="true" //GridView 出現快速滾動的按鈕(至少滾動4 頁才會顯示)
- android:fadingEdge="none" //GridView 衰落(褪去)邊緣顏色為空,預設值是vertical。(可以理解為上下邊緣的提示色)
- android:fadingEdgeLength="10dip" //定義的衰落(褪去)邊緣的長度
- android:stackFromBottom="true" //設定為 true 時,你做好的列表就會顯示你列表的最下面
- android:transcriptMode="alwaysScroll" //當你動態新增資料時,列表將自動 往下滾動最新的條目可以自動滾動到可視範圍內
- android:drawSelectorOnTop="false"//點選某條記錄不放,顏色會在記錄的後 面成為背景色,內容的文字可見(預設為 false)
4.GridView 實現資料載入的步驟:
GridView 適合“網格式佈局”的開發模式,即從每個條目的顯示元件,到對其進行控 制的資料結構,最後通過 Activity 等進行使用。
- 1) 首先是 item 元件,即用於每項佈局輸出的 xml 檔案。
- 2) 在 Activity 的佈局中載入《GridView》控制元件,並設定一系列屬性
- 3) 定義資料結構(容器),即用於持有單個 Item 的資料,可以是簡單的 String,也可
- 以通過抽象 Items 所需欄位組成一個類,抽象的原則是與 Item 中的元件對應。本
- 文中上圖涉及多個欄位,因此通過抽象元件形成 BBSTopicItem 類。
- 4) 列表介面卡。決定每行 Item 中具體顯示什麼內容,以怎樣的樣式顯示等,通常通過繼承 ArrayAdapter、SimpleAdapter 等實現。本文定義 BaseAdapter
- 5) 定義資料來源,並對資料來源進行初始化
- 6) 將介面卡設定給 GridView
二、案例
1.案例一:用GirdView展示文字
佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/girdview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:gravity="center"
>
</GridView>
</LinearLayout>
每一個格子item佈局
<?xml version="1.0" encoding="utf-8"?>
<!--必須以TextView開頭-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:id="@+id/textView"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="#000000"
android:textSize="40sp"
android:text="text"
android:background="#ed2f52"
>
</TextView>
和ListView使用一樣,只是樣式不同
public class GridView_Text extends AppCompatActivity {
GridView girdView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.girdview_text);
girdView=findViewById(R.id.girdview);
//設定固定資料
List<String> datalist=new ArrayList<>();
for (int i = 0; i <9 ; i++) {
datalist.add("單元格"+(i+1));
}
//設定簡單的陣列介面卡
ArrayAdapter<String> arrayAdapter=new ArrayAdapter<>(this,R.layout.item_view,datalist);
girdView.setAdapter(arrayAdapter);
}
}
2.案例二:用GridView顯示已安裝應用
獲取系統已經安裝的應用的方法:getAppInfo()
在方法里加上下面這句可以過濾掉系統自帶應用
//過濾掉系統應用
if((packageInfo.applicationInfo.flags& ApplicationInfo.FLAG_SYSTEM)==0)
主介面GridView_app.java
public class GridView_app extends AppCompatActivity {
private GridView gridView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_app);
gridView = findViewById(R.id.girdview);
gridView.setAdapter(new GridAdapter_app(this, getAppInfo()));
}
//獲取系統應用app資訊
public List<AppInfo> getAppInfo() {
List<AppInfo> AppInfolist = new ArrayList<>();
//使用包管理器
PackageManager packageManager = getPackageManager();
//返回一個包的資訊PackageInfo
List<PackageInfo> installedPackages = packageManager.getInstalledPackages(0);
for (int i = 0; i < installedPackages.size(); i++) {
//拿到包裡面的資訊
PackageInfo packageInfo = installedPackages.get(i);
AppInfo appInfo = new AppInfo();
//獲取包裡面應用名給appInfo裡的應用名稱賦值
appInfo.setAppName(packageInfo.applicationInfo.loadLabel(packageManager).toString());
appInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(packageManager));
appInfo.setVersionCode(packageInfo.versionCode);
appInfo.setVersionName(packageInfo.versionName);
appInfo.setPackageName(packageInfo.packageName);
AppInfolist.add(appInfo);
//過濾掉系統應用
// if((packageInfo.applicationInfo.flags& ApplicationInfo.FLAG_SYSTEM)==0)
AppInfolist.add(appInfo);
}
return AppInfolist;
}
}
封裝應用資訊的實體類 AppInfo
/***
* 建一個實體類封裝應用資訊
*/
public class AppInfo {
//應用名稱
private String appName;
//應用包名
private String packageName;
//版本名稱
private String versionName;
//版本號
private int versionCode;
//應用圖示
private Drawable appIcon;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public Drawable getAppIcon() {
return appIcon;
}
public void setAppIcon(Drawable appIcon) {
this.appIcon = appIcon;
}
}
設定資料介面卡
public class GridAdapter_app extends BaseAdapter {
private Context context;
private List<AppInfo> appInfoList;
private ViewHolder viewHolder;
//建構函式 將資料傳進來
public GridAdapter_app(Context context, List<AppInfo> appInfoList) {
this.context = context;
this.appInfoList = appInfoList;
}
@Override
public int getCount() {
return appInfoList.size();
}
@Override
public Object getItem(int position) {
return appInfoList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//優化GridView
if (convertView == null) {
viewHolder = new ViewHolder();
//convertView=View.inflate(context,R.layout.gridview_app,null);
//繫結item佈局.上下兩種方法都可以
convertView = LayoutInflater.from(context).inflate(R.layout.item_app_view, null);
viewHolder.iv_aapIcon = convertView.findViewById(R.id.app_icon);
viewHolder.tv_appName = convertView.findViewById(R.id.app_name);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//設定資料
AppInfo appInfo = appInfoList.get(position);
viewHolder.tv_appName.setText(appInfo.getAppName() + " " + appInfo.getVersionName());
viewHolder.iv_aapIcon.setImageDrawable(appInfo.getAppIcon());
return convertView;
}
public class ViewHolder {
TextView tv_appName;
ImageView iv_aapIcon;
}
}
在初始化時新增介面卡
//傳參設定介面卡
gridView.setAdapter(new GridAdapter_app(this, getAppInfo()));
3.案例三:用GridView載入網路圖片(上)
1.設定佈局
2.設定介面卡
3.獲取資料,從網路上下載圖片
- 網路連線下載(記得新增網路許可權在AndroidMainfest.xml中)
- 放到非同步任務AsyncyTask中執行下載操作
- 下載完成提示更新UI
介面卡設定
public class GridAdapter_internet extends BaseAdapter {
private List<ImageInfo> imageInfoList;
private Context context;
private ViewHolder viewHolder;
public GridAdapter_internet(Context context, List<ImageInfo> imageInfos) {
this.context = context;
this.imageInfoList = imageInfos;
}
@Override
public int getCount() {
return imageInfoList.size();
}
@Override
public Object getItem(int position) {
return imageInfoList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//優化效能
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = View.inflate(context, R.layout.item_internet_view, null);
viewHolder.text = convertView.findViewById(R.id.app_name);
viewHolder.imageView = convertView.findViewById(R.id.app_icon);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
ImageInfo imageInfo = imageInfoList.get(position);
viewHolder.text.setText(imageInfo.getText());
if (imageInfo.getBitmap() == null)//如果圖片還沒載入來
{//就預設給它載入一張本地圖
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
} else
viewHolder.imageView.setImageBitmap(imageInfo.getBitmap());
return convertView;
}
public class ViewHolder {
public TextView text;
public ImageView imageView;
}
}
圖片資訊:
public class ImageInfo {
private String imagePath;
private Bitmap bitmap;
private String text;
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
主Activity
public class GridView_internet extends AppCompatActivity {
private List<String> imgList;
private List<ImageInfo> imageInfoList;
private GridAdapter_internet gridAdapter_internet;
private GridView gridView;
private ImageLoadTask imageLoadTask;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_internet);
gridView = findViewById(R.id.girdview);
initData();
}
private void initData() {
imgList = new ArrayList<>();
imgList.add("http://img5.duitang.com/uploads/item/201406/26/20140626164837_dzKds.jpeg");
imgList.add("http://img2.imgtn.bdimg.com/it/u=3980629563,3881837630&fm=21&gp=0.jpg");
imgList.add("http://img5q.duitang.com/uploads/item/201505/08/20150508155052_XJaNW.jpeg");
imgList.add("http://img4.duitang.com/uploads/item/201407/02/20140702105736_FdN5P.jpeg");
imgList.add("http://img2.imgtn.bdimg.com/it/u=2866652161,3841912673&fm=21&gp=0.jpg");
imgList.add("http://img4.imgtn.bdimg.com/it/u=883757693,2063816225&fm=21&gp=0.jpg");
imgList.add("http://cdn.duitang.com/uploads/item/201309/26/20130926110955_QtUdX.jpeg");
imgList.add("http://zjimg.5054399.com/allimg/160815/14_160815161625_9.jpg");
imgList.add("http://i-7.vcimg.com/trim/09ce7067d2467c54cf05bbd271ee3ec8430415/trim.jpg");
imageInfoList = new ArrayList<ImageInfo>();
for (int i = 0; i < imgList.size(); i++) {
ImageInfo imageInfo = new ImageInfo();
imageInfo.setImagePath(imgList.get(i));
imageInfo.setText("圖片" + (i + 1));
imageInfoList.add(imageInfo);
}
//設定介面卡
gridAdapter_internet = new GridAdapter_internet(this, imageInfoList);
gridView.setAdapter(gridAdapter_internet);
//非同步下載
imageLoadTask = new ImageLoadTask(this, gridAdapter_internet);
imageLoadTask.execute();
}
//在網路上下載圖片返回Bitmap
public Bitmap getImagefornet(String path) {
try {
URL url = new URL(path);
//發起連結
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(10000);//超時時間
httpURLConnection.connect();
//拿到的輸入流讀取
InputStream inputStream = httpURLConnection.getInputStream();
//轉換成Bitmap
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//非同步任務下載操作
public class ImageLoadTask extends AsyncTask<String, Void, Void> {
Context context;
GridAdapter_internet gridAdapter_internet;
private ImageLoadTask(Context context, GridAdapter_internet gridAdapter_internet) {
this.gridAdapter_internet = gridAdapter_internet;
}
@Override
protected Void doInBackground(String... strings) {
for (int i = 0; i < gridAdapter_internet.getCount(); i++) {
//拿到圖片物件
ImageInfo imageInfo = (ImageInfo) gridAdapter_internet.getItem(i);
Bitmap bitmap = getImagefornet(imageInfo.getImagePath());//呼叫下載圖片的方法
imageInfo.setBitmap(bitmap);//將下載的圖片放到控制元件上
publishProgress();//通知重新整理UI
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
gridAdapter_internet.notifyDataSetChanged();
}
}
}
效果:
使用Google的的網路庫Glide去載入圖片
在build.gradle中dependencies
新增依賴包
implementation 'com.github.bumptech.glide:glide:3.7.0'
在Adapter中getView中新增,直接下載好圖片
//with第一個引數上下文
// load第二個圖片地址、
//placeholder第三個佔位符(預設圖片)
// centerCrop居中裁切顯示
// 預設緩衝
//into到你要顯示的元件上
Glide.with(context).load(imageInfo.getImagePath()).
placeholder(R.mipmap.ic_launcher).centerCrop().
into(viewHolder.imageView);
// if (imageInfo.getBitmap() == null)//如果圖片還沒載入來
// {//就預設給它載入一張本地圖
// viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
// } else
// viewHolder.imageView.setImageBitmap(imageInfo.getBitmap());
然後主Activity中的AsyncTask都可以省略了(取代了AsyncTask的下載操作)
//設定介面卡
gridAdapter_internet = new GridAdapter_internet(this, imageInfoList);
gridView.setAdapter(gridAdapter_internet);
速度更快,不用每次都重新下載,會自動快取下來,所以下次開啟就很快就有圖片了